Why is my $ q not getting resolved and working as I think?
I always have problems with $ q
Here is an example when .then
started immediately
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;
}
In the other place:
$scope.service.doit().then(
$scope.variable = 5
);
http://jsfiddle.net/IngoVals/stqwanhm/
I got this on Fiddle while trying to simulate another similar setup where it didn't work at all. What's going on here?
source to share
You are passing the value 5
in then
here:
$scope.service.doit().then(
$scope.variable = 5
);
This code works like this:
-
$scope.variable
assigned a value5
-
The result of the assignment expression (which is the assigned value
5
) is passed tothen
Both of these things happen right away when you call then
. They don't wait for the promise to be resolved.
Instead, you would like to pass a function in then
and set the function to a variable:
$scope.service.doit().then(function() {
$scope.variable = 5
});
Now you are passing the function. The code in the function does not run until it is called, which will be later when the promise is resolved.
The good news and the bad news is that this will be much more concise with ES6, because ES6 introduces bold arrow features:
$scope.service.doit().then(() => $scope.variable = 5);
This also creates a function and passes it to then
(on an ES6-enabled engine).
I say that this is both good news and bad news because it is beautiful and concise (good!) And also very easy to miss when you read (bad!). :-)
source to share
It doesn't fire right away, you just update the scope property outside of the callback. This code:
$scope.service.doit().then(
$scope.variable = 5
);
wrong, it must be
$scope.service.doit().then(function() {
$scope.variable = 5
});
The anothe problem is called the 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');
});
}
source to share