I'm trying to write a small service in my angular app which will enable me to pick config parameters specified in global Javascript objects. I don't want to attempt accessing the global config object unless the document is ready (because I cannot guarantee the order in which script elements will be inserted in the HTML).
However, I can't understand why I need the call to $apply
for the resolution to actually propagate to the then
callback.
myModule.service('GlobalConfigService', ['$q', '$rootScope', function($q, $rootScope) { var def = $q.defer(); $(document).ready(function() { def.resolve(MyConfig.val); $rootScope.$apply(); }); def.promise.then(function () { console.log('I am called only when $apply() is called. Why?'); }); return def.promise; }]);
In AngularJS, $apply() function is used to evaluate expressions outside of the AngularJS context (browser DOM Events, XHR). Moreover, $apply has $digest under its hood, which is ultimately called whenever $apply() is called to update the data bindings.
The relationship between the defer object and its promiseto return a value on successful receipt of asynchronous information, you'd call defer. resolve() , which, in turn, will call its promise's then() function. if you call defer. reject() , the promise's catch() function will be called. call defer.
A resolve is a property you can attach to a route in both ngRoute and the more robust UI router. A resolve contains one or more promises that must resolve successfully before the route will change.
Promises in AngularJS are provided by the built-in $q service. They provide a way to execute asynchronous functions in series by registering them with a promise object. {info} Promises have made their way into native JavaScript as part of the ES6 specification.
In AngularJS the results of resolve() are propagated asynchronously, inside a $digest cycle, not immediately. This means that callbacks registered with then() will only be called (later) when a digest cycle occurs.
In your code, nothing is causing Angular to enter a digest cycle, so the then() callback is never called. Calling $apply() is one way to cause a digest cycle to run. Another way: add a button with ng-click that does nothing, then click that, it will cause a digest cycle and you should see the results:
<button ng-click="">Force digest by clicking me</button>
See also https://stackoverflow.com/a/14657974/215945
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With