utility.fetchInfo() returns a Promise object. I need to be able to get the value of this Promise object and assign the value of it to a variable that I can then use later on in my code.
At the moment, I can happily print the value of result to the console, but I need to be able to assign this value to myVal. So far, I've tried a lot of things and nothing has worked.
var myVal = utility.fetchInfo().then(result => console.log(result));
Thanks
What #dhilt said but do your stuff inside the promise callback function:
utility.fetchInfo().then(result => {
doSomethingWith(result);
});
Or use async/await if you are using a recent version of Node or Babel:
async function myFunction () {
var myVal = await utility.fetchInfo();
}
Just do an assignment within the callback's body
utility.fetchInfo().then(result => { myVal = result; });
Depends on the situation, for example, if there's a big piece of async logic, it may be better to extract it in a separate function:
let myVal; // undefined until myAsyncFunc is called
const myAsyncFunc = (result) => {
console.log(result);
myVal = result;
// ...
};
utility.fetchInfo().then(myAsyncFunc); // async call of myAsyncFunc
When you return the value to another file/function and you are getting undefined because another function where you are using that value is not waiting for the value to be assigned to the variable. For example there are two function
function1(){
var x=desired_value
}
function2(){
var y = x
}
now function1 might take some time to assign desire value to var x and java script ll not wait for this, it ll start running function2 and when you read the value of y you will get undefined.
To solve this problem we can use java script promise/await/async, return value from async function as resolve. refer below example
async function1(){ //function1 should be async here for this to work
return new Promise(function(resolve,reject){
resolve(desired_value)
});
}
or above function can be writtern as
async function1(){ //function1 should be async here for this to work
return Promise.resolve(desired_value)
}
Now we can use this value in another function by calling the function1 and use await keyword
function2(){
var y = await function1();
}
now it ll wait for function1 to complete before assigning its value to y.
I think what you are looking for is some fancy ES7 syntax:
var myVal = (async () => {
var data = await utility.fetchInfo();
return data;
})();
(async () => {
console.log(await myVal);
})();
Keep in mind console.log(myVal) will end up with Promise { <pending> }, So instead you would use
(async () => {
console.log(await myVal);
})();
which would return your desired output.
Related
I am making a function in nodejs to read a value from the database in Firebase and return it. I read in the that way and get the right value by the console.log(), but when i made the return of the value doesn´t work properly when i call that function
function test() {
database.ref(sessionId + '/name/').once("value").then((snapshot) => {
var name = snapshot.child("respuesta").val()
console.log(name);
return name;
});
}
If someone could help me. Thanks
You're not returning anything from test, so undefined is being implicitly returned. You can return the promise like this:
function test() {
return database.ref(// everything else is identical
}
Note that this will be returning a promise that resolves to the name, not the name itself. It's impossible to return the name, because that doesn't exist yet. To interact with the eventual value of the promise, you can call .then on the promise:
test().then(name => {
// Put your code that uses the name here
})
Or you can put your code in an async function and await the promise:
async function someFunction() {
const name = await test();
// Put your code that uses the name here
}
How do you get the information for the Chrome extension by using async and await?
[chrome.instanceID.getID]
[chrome.storage.sync.get]
We tried this code:
async function test()
{
let _r = await chrome.instanceID.getID();
return _r;
}
let _pc_id = test();
but _pc_id returns a promise. We find no way to get the value in it. How should we do this?
You can get the instanceID like this, but can't store it in a variable to use it out of scope of the promise, AFAIK. You may want to read this: saving data from promise in a variable
If you want to use the returned value of Promise you need to do it in the promise or in .then()s after the promise, at least that is how I do it.
chrome.instanceID.getID example:
chrome.instanceID.getID((instance_id) => {
console.log(instance_id);
// Execute your other related code here
});
or
var promise = chrome.instanceID.getID();
promise.then((instance_id) => {
console.log(instance_id);
// Execute your other related code here
});
or
chrome.instanceID.getID()
.then((instance_id) => {
console.log(instance_id);
// Execute your other related code here
});
chrome.storage.sync.get example:
chrome.storage.sync.get('myKey', function(items) {
var key = items.myKey;
// Below code is an example, change it to your needs
if (key) {
console.log(key)
} else {
key = createKey(); // a custom function that generates keys
chrome.storage.sync.set({myKey: key}, function () {
console.log(key);
});
}
};
I'm accessing google API for converting coordinates into detailed objects using node-geocoder library from npmjs. Everything went well and I'm getting the expected object from geocoder API. The problem started the moment when I thought of using the data outside the promise function. I want to use the values outside the promise/async-await function.
Below is the code I've tried, Pls take a look and help me. TIA...
function goecoderPromiseFunction() {
return new Promise(function (resolve, reject) {
geocoder.reverse({ lat: 45.767, lon: 4.833 })
.then(data => {
cityName = data[0].city;
resolve(cityName);
})
.catch(err => {
console.log(err);
});
});
}
async function app() {
var a = await goecoderPromiseFunction();
return a;
}
var a = app();
console.log("a->", a);
I expect the variable "a" should print the city name "Lyon", but it prints
a-> Promise { < pending > }
The promise returned by the app function is never consumed, that is why it remains in a pending state.
Call then on the app function to get the result :
app().then(a => console.log("a->", a));
You can also use async/await :
(async function() {
var a = await app();
console.log("a->", a);
})();
An asynchronous function actually returns a promise that 'resolves' to the function's return value. You are therefore assigning a promise to the value of a. If you are in the global scope, you obviously cannot use async/await so you need to use either a self-executing async function or you need to run
a.then(data => console.log('a->', data));
to get what you are looking for.
Find out more about async functions here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
It prints because console.log("a->", a); runs while promise haven't returned answer for a variable "a"
Note: you haven't used reject function, if there is an error you wont notice and may be that error was the required answer to be carried by variable "a" that's why it still pending i.e still waiting.
For more idea try to use reject function inside the catch block example reject(err)
instead of console it out as you've done
I would like to write a block of code using await syntax, immediately execute it, and create a promise that waits for execution to finish. I've come up with the following way to do this.
let makePromise = async () => {
return foo && await bar();
}
let promise = makePromise();
However, I find this hard to read and understand. Creating a function and then calling it right away seems counter-intuitive and goes against good practice in other programming languages. Is there a more idiomatic way to write this piece of code?
Particularly, this code is used in the following context.
let promises = items.map((item) => {
let makePromise = async () => {
return foo(item) && await bar(item);
}
return makePromise();
});
Why not using an async function directly? The following code behaves exactly the same as your example, but keep in mind, this results in an array of promises and awaits none of them.
function foo(x) { return "foo " + x; }
async function bar(x) { return "bar " + x; }
const items = [1];
let promises = items.map(
async item => foo(item) && await bar(item)
);
Promise.all(promises).then(x => console.log(x));
Async functions actually return a Promise. This is valid:
const x = async () => {
console.log(123)
}
x().then(() => {
console.log(456)
})
So in your case:
let promise = bar()
I have a function,
asdf() {
var a = fooController.getOrCreateFooByBar(param);
console.log("tryna do thing");
console.log(a); //undefined
if (!a.property) {
//blah
}
that dies. getOrCreateFooByBar does a
Model.find({phoneNumber : number}).exec()
.then(function(users) {})
and finds or creates the model, returning it at the end:
.then(function(foo) { return foo}
How can I use the result of this in asdf()? I feel like this is a fairly easy question but I am getting stuck. If I try to do a.exec() or a.then() I get 'a cannot read property of undefined' error.
The main idea about Promises (as opposed to passed callbacks) is that they are actual objects you can pass around and return.
fooController.getOrCreateFooByBar would need to return the Promise it gets from Model.find() (after all of the processing done on it). Then, you'll be able to access it in a in your asdf function.
In turn, asdf() should also return a Promise, which would make asdf() thenable as well. As long as you keep returning Promises from asynchronous functions, you can keep chaining them.
// mock, you should use the real one
const Model = { find() { return Promise.resolve('foo'); } };
function badExample() {
Model.find().then(value => doStuff(value));
}
function goodExample() {
return Model.find().then(value => doStuff(value));
}
function asdf() {
var a = badExample();
var b = goodExample();
// a.then(whatever); // error, a is undefined because badExample doesn't return anything
return b.then(whatever); // works, and asdf can be chained because it returns a promise!
}
asdf().then(valueAfterWhatever => doStuff(valueAfterWhatever));