Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign value from successful promise resolve to external variable

I have a pretty silly problem. Consider the following:

vm.feed = getFeed().then(function(data) {return data;}); 

getFeed() returns a $q deferred promise (I am on angular) that resolves successfully.

My goal is to set vm.feed equal to the data value returned by the successful callback. As it is right now, the code simply assigns vm.feed equal to the $promise object returned by getFeed().

I know I could simply do: vm.feed = data inside the resolved function but I want to understand why this code does not work as it is.

PD: the promise resolves correctly and even after it has been resolved vm.feed keeps being equal to the Promise, and not data. I copy the console.log of vm.feed after +10 seconds have elapsed:

Promise {$$state: Object} $$state: Objectstatus:1 value: Object 

That value property inside the Promise object contains the actual solution of the promise that I want to assign to vm.feed (e.i. data).

thank you!

like image 735
Gerard Clos Avatar asked Jul 07 '15 09:07

Gerard Clos


People also ask

How do I return a value from promise resolve?

The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.

How do you get variables from promises?

Define an async function. Use the await operator to await the promise. Assign the result of using the await operator to a variable.

How can I access a variable outside a promise then method?

You need to return the promise from the Spotify. getCurrentUser() , and then when you return names within that it is returned by the outer function.

Can I return value from promise?

Promise resolve() method:If the value is a promise then promise is returned. If the value has a “then” attached to the promise, then the returned promise will follow that “then” to till the final state. The promise fulfilled with its value will be returned.


2 Answers

You are going to get whatever then() returns. But since you are reading this, the following may help you:

Your statement does nothing more than ask the interpreter to assign the value returned from then() to the vm.feed variable. then() returns you a Promise (as you can see here: https://github.com/angular/angular.js/blob/ce77c25b067b7b74d90de23bfb4aac6a27abb9d1/src/ng/q.js#L288). You could picture this by seeing that the Promise (a simple object) is being pulled out of the function and getting assigned to vm.feed. This happens as soon as the interpreter executes that line.

Since your successful callback does not run when you call then() but only when your promise gets resolved (at a later time, asynchronously) it would be impossible for then() to return its value for the caller. This is the default way Javascript works. This was the exact reason Promises were introduced, so you could ask the interpreter to push the value to you, in the form of a callback.

Though on a future version that is being worked on for JavaScript (ES2016) a couple keywords will be introduced to work pretty much as you are expecting right now. The good news is you can start writing code like this today through transpilation from ES2016 to the current widely supported version (ES5).

A nice introduction to the topic is available at: https://www.youtube.com/watch?v=lil4YCCXRYc

To use it right now you can transpile your code through Babel: https://babeljs.io/docs/usage/experimental/ (by running with --stage 1).

You can also see some examples here: https://github.com/lukehoban/ecmascript-asyncawait.

like image 73
Nathan Avatar answered Sep 29 '22 10:09

Nathan


This could be updated to ES6 with arrow functions and look like:

getFeed().then(data => (vm.feed = data)); 

If you wish to use the async function, you could also do like that:

async function myFunction(){     vm.feed = await getFeed();     // do whatever you need with vm.feed below  } 

Edit: added parenthesis to be eslint correct (as commented by Max Waterman)

like image 43
Soldeplata Saketos Avatar answered Sep 29 '22 09:09

Soldeplata Saketos