Access a Variable Outside of .Then Function

Access a variable outside of .then function

.then is the mechanism that promises use to let you know when the value is available. The "when" part is important: only the promise object knows what time your code should run at. So even if you try to write some extra code to store values in variables, the question of when it's safe to try to get those variables can only be answered by the promise's .then method.

So yes, any code that needs the values to be available needs to be put in the .then of the promise. Maybe you have some separate part of the codebase that needs to interact with the result, and so it feels clumsy to try to have to copy that code over to here. Well you don't need to: you just need to pass that other code the promise, and then that other code can call .then on the promise itself. For example:

const tokenPromise = returnRequest()
.then(result => result.response.token);

// Anywhere else that tokenPromise in scope can write whatever code it needs to:
tokenPromise.then(token => {
// Do anything with the token
});

// And a completely different piece of code can write its own stuff with the token
tokenPromise.then(token => {
// Do other stuff with the token
});

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

getUser() is not returning anything. 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.

function getUser() {

if ( $localStorage.token == undefined) {
throw alert("Not logged in");
}
else {
return Spotify.getCurrentUser().then(function(data) {
var names = JSON.stringify(data.data.display_name);
console.log(names)
return names;
})
}
}

The above answered why you were getting undefined when calling getUser(), but if you want to work with the end result you also want to change how you're using the value you get from getUser - it returns a promise object, not the end result you're after, so your code wants to call the promise's then method when the promise gets resolved:

getUser()                        // this returns a promise...
.then(function(names) { // `names` is the value resolved by the promise...
$scope.names = names; // and you can now add it to your $scope
});

Accessing outside variables inside the 'then' function

The best way to do this is to package the data you need from one part of the promise chain into the resolved value that is sent onto the next part of the chain. In your case with Promise.map(), you're sending an array of data onto the .then() handler so the cleanest way to pass each path down to the next stage is to make it part of each array entry that Promise.map() is resolving. It appears you can just add it to the bucketStat data structure with an extra .then() as show below. When you get the data that corresponds to a path, you then add the path into that data structure so later on when you're walking through all the results, you have the .path property for each object.

You don't show any actual result here so I don't know what you're ultimately trying to end up with, but hopefully you can get the general idea from this.

Also, I switched to Promise.mapSeries() since that's a shortcut when you want concurrency set to 1.

Promise.mapSeries(bucket_paths, function(path) {
return getJson.getStoreJson(things,path.path).then(bucketStat => {
// add the path into this item's data so we can get to it later
bucketStat.path = path;
return bucketStat;
});
}).then(function(bucketStats){
return bucketStats.map(function(bucketStat) {
var bucket_stats_json = {};
bucket_stats_json.timestamp = new Date();
bucket_stats_json.name = bucketStat.path.name;
return bucket_status_json;
});
});

Not able to access the variable outside of a request

The problem here is that when you do return currPrice you are returning from the callback in the quote function, thus not getting the value in the scope of the getPrice function. Because this is a callback, once it is executed the getPrice function already left the event stack with undefined as the return value. Check this video to learn about the event loop.

A way you could fix this would be to do something like:

const getPrice = async () => {
//Get the curent market price
const marketSymobl = checkOrders[i].symbol.split(" - ")[0].toUpperCase()

// We are wrapping this function in a promise so that we can await it
const quotePromise = new Promise((resolve, reject) => finnhubClient.quote(marketSymobl, (error, data, response) => {
if (error) {
// Rejecting with error so you have the freedom to handle it however you want
reject(error)
} else {
resolve(data.c)
}
});

const currPrice = await quotePromise();

return currPrice
}

This way you are returning from the getPrice function.

Note: I changed your var variables to let. Have a look at this post for an explanation why

Edit 1: I changed your marketSymobl variable to be const, since you don't mutate it afterwards

Edit 2: Wrapped the quote function in a promise so it can be awaited

Edit 3: Edited initial statement and added reference to event loop video.



Related Topics



Leave a reply



Submit