I'm new to AngularJS and am struggling with how to process the data fetched asynchronously from the server before displaying it on the page.
The data I'm fetching is like this:
"all_colors":[
{"color":"red","quantity":1},
{"color":"green","quantity":11},
{"color":"yellow","quantity":5}
]
When the page loads initially I fetch the above data from the server like this:
angular.module('angularDjangoRegistrationAuthApp')
.controller('DashbordCtrl', function ($scope, djangoAuth, Validate, $location) {
djangoAuth.fetch_from_server().then(function(data){
$scope.model = data;
});
I would like to show two things on the page:
Available Colors: 3
Total Color Quantity: 17
I can show the available colors like this:
Available Colors: {{model.all_colors.length}}
Question
But how can I loop the all_colors and count the quantity for each so that I can show Total Color Quantity ?
I can't seem to do this in my JS file after fetching the data because it is fetched asynchronously. I can't figure out the way to do this.
Regardless of how you obtain the data, just think about what data you need to display - your ViewModel - and assign values to them, if and when you obtain the data.
In this case, create a scope-exposed property $scope.totalColorQty, and assign its value when you receive the data:
djangoAuth.fetch_from_server().then(function(data){
$scope.model = data;
$scope.totalColorQty = computeColorQuantity(data.all_colors);
});
function computeColorQuantity(colorsArray){
// do whatever you need to calculate the quantity
}
Then, simply display it in the UI:
<div>Total Color Quantity:
<span ng-show="totalColorQty === undefined">Loading...</span>
<span ng-hide="totalColorQty === undefined">{{totalColorQty}}</span>
</div>
Few additional notes:
1) You could expose computeColorQuantity on the scope and bind to that. But, I strongly recommend against that - since this operation is "heavy" and will be performed on every digest cycle, making your entire app slower.
DON'T DO THIS:
<div> Total Color Quantity: {{computeColorQuantity(model.all_colors)}}</div>
2) If you don't need to recalculate this value, then you could bind-once to reduce the number of $watchers:
<span ng-show="totalColorQty">{{::totalColorQty}}</span>
3) If you do intend to allow users to update the data, then I suggest to recalculate it on every user-initiated changed, for example, via ng-change, instead of via deep $watch
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With