When working with asynchronous tasks, the order of resolution may not always be guaranteed. To ensure consistency, consider using index i
instead of push
.
$scope.$watch ('timeRange', function (newValue, oldValue, scope){
$scope.chartdata = []
//If a filter has changed, redraw all charts
if (newValue !== oldValue)
{
for(var i = 0; i< $scope.charts.length; i++){
$scope.draw($scope.charts[i]).then(function(i) { // create scope to capture i
return function(value) { $scope.chartdata[i] = value; };
}(i));
}
}
}, true);
UPD Added an example to demonstrate how scopes work.
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
setTimeout(function(i) {
return function() {
console.log(`Let's teach @georgeawg scopes ${i}`)
}
}(i), i * 1000)
}
You can also use forEach
as shown below:
$scope.$watch ('timeRange', function (newValue, oldValue, scope){
$scope.chartdata = []
//If a filter has changed, redraw all charts
if (newValue !== oldValue)
{
$scope.charts.forEach(function(chart, i) {
$scope.draw(chart).then(function(value) {
$scope.chartdata[i] = value;
})
})
}
}, true);
Alternatively, you can add all at once using Promise.all
or its AngularJS equivalent $q.all
.
$scope.$watch ('timeRange', function (newValue, oldValue, scope){
$scope.chartdata = []
//If a filter has changed, redraw all charts
if (newValue !== oldValue)
{
$q.all($scope.charts.map(function(chart) {
return $scope.draw(chart)
}).then(function(chartdata) {
$scope.chartdata = chartdata;
})
}
}, true);