My listSvc is also using Q rather than $q if that matters.
Yes, yes it does. This is your problem.
Q is a much more complete promise implementation than $q
, it has a lot more features. However $q
integrates into the AngularJS digest cycle.
- Informally - it notifies the presentation that something has changed and it needs to refresh.
- Formally - Q resolves promises using the asap.js module for fast queuing (recently), and $q resolves promises on the evalAsync queue. The informal part is more important here though.
My suggestion would be instead of using tricks like a scope apply in a .finally
uniformally - use $q.when(prom)
which is a utility method that takes a thenable (generic promise) and turns it into a trusted $q
promise. If you don't have anything that runs in $q, you'll still need to call $rootScope.$apply()
at the end of your promise chain.
If that doesn't work, you can simply add
.finally(function(){ $scope.apply(); })
To the end of your promise chains.
Most good promise libraries implement the A+ specification that allows clean and simply assimilation of one kind of promise into another. Since both Q and $q are Promises/A+ complaint - this means you can interop between Q and $q very easily (since they have similar .then semantics):
when(value) - Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.
In your case - something like:
var items = $q.when(listSvc.getItems()); // don't forget to inject $q
Or wrap it in a when
at any other point in the chain.