I have following issue: I trying to "merge" data from two collections from MongoDB. Everything looks OK until I try to show some data from second query that came exactly after first one:
$scope.getData = function() {
var pipeline, fromDateRangeStatement, toDateRangeStatement, service, joblist;
service = ($scope.service && $scope.service.value) ? $scope.service.value : {
$exists: true
};
pipeline = $scope.utils.getSessionUsersPipeline($scope.fromDate, $scope.toDate,
$scope.checkedResults, $scope.checkedStatuses, service, $stateParams, $scope.usersLimit);
toApi.post("/users/aggregate", {
pipeline: pipeline
}).success(function(data) {
$scope.users = data.data.result;
for (var i = 0; i < $scope.users.length; i++) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
var user = $scope.users[i]
toApi.get(path).success(function(data) {
user.error = data.data.records[0].exception // this is not shows up in HTML!
console.log(data.data.records[0].exception); // but it can be logged!
})
}
})
};
So, problem is: $scope.users
are rendered at my page, while their attribute error
is not. Looks like data became rendered before I change attributes for every user in for loop.
How this can be handled?
Thanks
Below are two different solutions
Each of your GET requests is async, so you need to wait for all of them to resolve. You could wrap each request in its own Promise and collect all Promises like so
var promises = [];
for (var i = 0; i < $scope.users.length; i++) {
promises[i] = new Promise(function (resolve, reject) {
var path = "/jobs/" + scope.users[i].id + "/sessions";
var user = $scope.users[i]
toApi.get(path).success(function(data){
user.error = data.data.records[0].exception;
console.log(data.data.records[0].exception);
resolve(user);
})
}
Then use Promise.all() to group all promises together as one Promise and wait for it to resolve.
Promise.all(promises).then(function(users) {
$scope.users = users;
});
Quick example: http://codepen.io/C14L/pen/QNmQoN
Though, a simpler and better solution would be to display the users one after one, as their API calls return
for (var i = 0; i < $scope.users.length; i++) {
var path = "/jobs/" + $scope.users[i].id + "/sessions";
toApi.get(path).success(function (data) {
$scope.users[i].error = data.data.records[0].exception;
$scope.users[i].done = true;
console.log(data.data.records[0].exception);
});
}
Simply add into your template a check for $scope.users[i].done = true
and ony show that dataset with ng-show="user.done"
.