Reputation: 4898
I'm always having problems with $q
Here is an example where the .then
is fired right away
function doit() {
var deferred = $q.defer();
var modalInstance = $modal.open({
template: '<p>this is modal</p><a ng-click="ok()">ok</a>',
controller: function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
}
});
modalInstance.result.then(function () {
console.log('ok');
deferred.resolve();
}, function () {
console.log('Modal dismissed');
});
return deferred.promise;
}
Elsewhere:
$scope.service.doit().then(
$scope.variable = 5
);
http://jsfiddle.net/IngoVals/stqwanhm/
I got this in Fiddle when trying to model another similar setup where .then didn't fire at all. What is going on here?
Upvotes: 3
Views: 157
Reputation: 1074385
You're passing the value 5
into then
here:
$scope.service.doit().then(
$scope.variable = 5
);
That code runs like this:
$scope.variable
is assigned the value 5
The result of the assignment expression (which is the assigned value, 5
) is passed into then
Both of those things happen right away, when you call then
. They don't wait for the promise to be resolved.
You wanted to pass a function into then
instead, and have the function set the variable:
$scope.service.doit().then(function() {
$scope.variable = 5
});
Now you're passing in a function. The code in the function isn't run until it's called, which it will be later when the promise is resolved.
The good news and bad news is that this is going to get a lot more concise as of ES6, because ES6 introduces "fat arrow" functions:
$scope.service.doit().then(() => $scope.variable = 5);
That also creates a function and passes it into then
(on an ES6-enabled engine).
I say this is both good news and bad news because it's nice and concise (good!), and also very easy to miss when you're reading (bad!). :-)
Upvotes: 1
Reputation: 193261
It doesn't fire right away, it's just you update scope property outside of then callback. This code:
$scope.service.doit().then(
$scope.variable = 5
);
is incorrect, it should be
$scope.service.doit().then(function() {
$scope.variable = 5
});
Anothe problem is so called deferred anti-pattern. Avoid creating redundant deferred object:
function doit() {
return $modal.open({
template: '<p>this is modal</p><a ng-click="ok()">ok</a>',
controller: function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
}
}).result.then(function () {
console.log('ok');
}, function () {
console.log('Modal dismissed');
});
}
Demo: http://jsfiddle.net/stqwanhm/2/
Upvotes: 2