Why $scope.apply matters for angular's $q? Why $scope.apply matters for angular's $q? angularjs angularjs

Why $scope.apply matters for angular's $q?


This documentation sucks.

So the thing with $q is that when your promise is resolved (and also presumably on reject or notify), it invokes your handlers within $rootScope.evalAsync which ensures that after invocation, it'll trigger a digest and thus the rest of your application can have a chance to update or otherwise respond to the changes, just the way we like it.

As you found out, it works just fine without the explicit $apply in an example app. However, the reason why they are doing explicit $apply is because that automagic with $evalAsync doesn't get a chance to work when running synchronously in a test, not because it's required for your application to Just Work ™.

With a few other notable services that are augmented for testing in angular-mock.js, like $http and $timeout, we can explicitly flush when we want to simulate an async http request/response or a timeout (for example). The equivalent to stuff waiting to be evaled is to trigger a digest, which will get your promise handler invoked in the proper context. This is done with $apply or $digest, and hence why you're seeing it in their examples... because their examples are written as synchronous tests.

The docs should explain the difference between what you need to do to get your tests working and what your application itself should focus on to get the job done. The docs have a bad habit of making test facts their examples, and it just confuses people.

Hope that helps.