Reputation: 4840
I have a promise that I am binding to in my UI. When the promise resolves and the UI element renders I can then click on that UI element. In my controller code where I handle the click I would like to act on the value of the promise. At this point in my angular code I already know that the promise is resolved.. but when I want to get the value its still a promise.
Whats the best way to get the value of the promise... given that I know it must have resolved?
Upvotes: 16
Views: 35046
Reputation: 2263
What's tricky to understand is that you might think that if the Promise is not yet full-filled then maybe if I wait a bit I can test again to see if by now it has a value. But that is not possible because as explained on MDN:
"Callbacks will never be called before the completion of the current run of the JavaScript event loop."
So as long as your currently started function is running, the Promise can not be full-filled. It has no "value" during the current run of the event loop. "Promise" means "I promise to maybe give it to you during the NEXT event-loop run".
You could save that promise to a global variable and then when a user clicks on a button in the browser a new event-loop starts by running your event-handler which can put another "when()" onto the promise such that if the promise is resolved by that time the new when-function takes the value it gets as argument and saves it into a variable from which you can read it. No need to write it to console, to see that it is there.
That for me was the tricky part, I thought yes sure I can make the Promise write to the console, but I can't read from console, so how can I get that value into the rest of my program? Answer: Wait till the current event-loop is over, then you can.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
Upvotes: 0
Reputation: 120513
Promises are always promises - and that's how they should be. While it is possible to bind a promise directly to the view, I generally discourage this practice because it lacks transparency and can lead to view flickering. A better solution is to assign a scope value in a then
call:
myService.then(function( val ) {
$scope.val = val;
});
When $scope.val
is ready, it can always be treated directly as a value - because it is.
That said, if you want to do the promise assignment directly, you just have to treat it like a promise; that is, you need to call promise.then(function () { ... });
. This seems like an inconvenience, but it's actually a testament to just how powerful promises are.
If you want some more info on promises, I pontificated on them (and provided code examples) for a recent Google+ Hangout, where I covered the advantages, common uses, and best practices of promises in AngularJS: AngularJS Hangout -- Promises, Promises Promises, Promises. The idea of never-ending promise chains was specifically addressed, though I don't have a timecode off the top of my head.
Hope this helps!
Upvotes: 22