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
Calculate Total Sum of Dynamically Added Items to a Table
Regular Expression Which Allow Only Characters or Space
How to Make an Area Unclickable With CSS
Uncheck a Checkbox and Another Checkbox Will Untick
Write a Auto-Fill and Submit Web Form Program
How to Prevent Invalid Characters from Being Typed into Input Fields
Have a Div Move on Scroll Up and Down
Nodejs MySQL Get Correct Timestamp Format
Convert Date String from Yyyymmdd to Dd Mon Yyyy
Displaying Navbar on Multiple HTML Pages Using Bootstrap
Sort Json Data Based on Date and Time
Preventing Page from Scrolling on Focus Switching
Javascript Regex: Replace Hyphen Between Characters Only (Not Spaces)
How to Format Numbers in Vuejs
How to Add Button on Each Row in Datatable
Angular 8 Loose Data After Refresh Page