This question already has answers here:
How to block for a javascript promise and return the resolved result? [duplicate]
(2 answers)
Closed 5 years ago.
I have to use a method that returns a promise and that is inside a function. I want to return a value for the parent function in the .then() of the promise.
returnSomething():boolean{
theFunctionThatReturnsAPromise()
.then(
//return true for the returnSomething function here
).catch(
//return false for the returnSomething function here
);
}
How can I do this with typescript/Javascript?
You can use async/await for this.
async function foo() {
try {
var val = await theFunctionThatReturnsAPromise();
console.log(val);
}
catch(err) {
console.log('Error: ', err.message);
}
}
But the return value is still going to be a Promise, since it is asynchronous.
For a better understanding you might want to read this tutorial.
You can't return something directly because the thing you want to return isn't immediately available. That's the whole reason we use asynchronous things like promises. It's hard to know exactly what you are doing from a couple lines of code, but in general you just want to return the promise and allow the caller of the function to deal with it.
For example:
returnSomething():Promise<boolean>{
return theFunctionThatReturnsAPromise()
}
Then the caller can deal with the value like:
returnSomething()
.then(result => {
if (result) { //etc.}
}
.catch( err => { console.log("an error happened", err)}
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I cannot get this to work, and starting to think I've misunderstood something fundamental. I've been through many examples, and I cannot see what I'm doing wrong.
Here is my promise:
myPromise = new Promise ( resolve => {
if (matchNew(id)) resolve();
})
myPromise.then( () => {
console.log('resolved');
})
matchNew() is a function that simply returns 'true' after completion of save to database. My console confirms this 'true' return happens, but code is not waiting for it, and the promise above never resolves.
Update
This is what I meant regarding the purpose of MatchNew(): It waits for confirmation from MongoDB that the write is successful, then then returns true.
function matchNew(id) {
/* do some stuff */
// update database
MongoPath.Match
.replaceOne( {'_id': m._id}, thisMatch, {writeConcern: { j: true}})
.then( (msg) => {
console.log(msg);
return true;
});
}
I want to ensure my main code is waiting until I get a return values from matchNew before continuing...
matchNew() is a function that simply returns 'true' after completion of save to database.
Thats impossible. It either returns true immeadiately, or it returns a Promise, that resolves to true on completion. Therefore:
if (matchNew(id))
is th same as:
if (new Promise())
and that will enter the branch directly as objects are truthy in javascript. Instead you just want to chain promises:
matchNew(id).then(matches => {
if(matches) {
/*...*/
} else {
/*...*/
}
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am using this native script firebase plugin, which makes me use this function:
getValue() {
var value;
firebase.getValue('/companies')
.then(result => {
console.log(JSON.stringify(result));
value = result;
return result;
})
.catch(error => {
console.log("Error: " + error);
return error;
});
return value;
}
If I import it in another file and use it like this:
var myValue = this.myFirebaseService.getValue();
If I run it the first time it returns undefined but the second time it returns the value.
My question is how do I make the firebase function return a promise so I can make my second statement wait for it.
The firebase function you're referring to is returning a promise. That's why you can use .then and .catch after calling the getValue function.
If you return the firebase promise from getValue(), like this:
getValue(){
return firebase.getValue('/companies');
}
You'll be able to call getValue() whenever you like, but you'll have to execute the code after getValue() (which is a promise) is resolved. Like so:
getValue().then(function(value) {
console.log(value);
});
I would read up on promises if you don't understand this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
You can initialize myValue after the result has been received from the then block.
Something like this:
var myValue;
function getValue() {
return firebase.getValue('/companies');
}
myValue = getValue().then(result => {
const value = JSON.stringify(result);
console.log(value);
return value;
})
.catch(error => {
console.log("Error: " + error);
});
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I got this code using the async/await :
function _getSSID(){
return new Promise((resolve, reject)=>{
NetworkInfo.getSSID(ssid => resolve(ssid))
})
}
async function getSSID(){
let mySSID = await _getSSID()
if (mySSID == "error") {
return 'The value I want to return'
}
}
And getSSID() is equal to this :
Looks like the getSSID() function will always return a promise. How can I get "The value I want to return" in plain text ?
Any help is greatly appreciated.
Declaring a function async means that it will return the Promise. To turn the Promise into a value, you have two options.
The "normal" option is to use then() on it:
getSSID().then(value => console.log(value));
You can also use await on the function:
const value = await getSSID();
The catch with using await is it too must be inside of an async function.
At some point, you'll have something at the top level, which can either use the first option, or can be a self-calling function like this:
((async () => {
const value = await getSSID();
console.log(value);
})()).catch(console.error):
If you go with that, be sure to have a catch() on that function to catch any otherwise uncaught exceptions.
You can't use await at the top-level.
This question already has answers here:
How to create a AngularJS promise from a callback-based API
(2 answers)
Closed 4 years ago.
To handle promises I return and chain them with .then(). I must however use a third party library that expects a callback and that does not return a promise.
For clarity, a fake example:
person.sayHello()
.then( response => introduceMyself() )
.then( name => externalLibrary.storeAndGetInfo(name) )
.then( info => saySomeInfo(info) )
.catch( err => console.log(err) );
introduceMyself(){
return asyncFunctionToGetAndSayMyName();
}
sayDomeInfo(info){
console.log(info);
}
My problem is that externalLibrary.storeAndGetInfo expects these params:
storeAndGetInfo(string, callback(valueThatINeedForMyNextChainedFunction));
I have the feeling that I could wrap the external library function in a chainable function (one that returns a promise), and then use the library q to defer and resolve the callback function, but then I'm stuck as I don't know to actually implement it. Or is there another way?
PS in case it makes a difference, this is in a angularjs app
You should wrap your external library's call with a function that returns a a deferred promise:
function promisedStore (name) {
var deferred = Q.defer(); //initialize deferred
externalLibrary.storeAndGetInfo(name, function(error, result) {
if (error) {
deferred.reject(new Error(error)); //reject promise if error in cb
} else {
deferred.resolve(result); //resolve promise if no error in cb
}
});
return deferred.promise;
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I know you can access a Promise’s value inside the .then method like the following code:
const Promise = require("bluebird");
const fs = Promise.promisifyAll(require('fs'));
const mergeValues = require('./helper').mergeValues;
fs.readFileAsync('./index.html', {encoding: "utf8"})
.then((data) => {
return mergeValues(values, data); //async function that returns a promise
})
.then((data) => {
console.log(data);
});
In the above example, I’m reading from a file, merging the data with some values, and then logging the data to the console.
But how about returning the value from a function, as you normally would in a synchronous function? If I follow this comment on synchronous inspection, I think the code should look like this:
function getView(template, values) {
let file = fs.readFileAsync('./' + template, {encoding: "utf8"});
let modifiedFile = file.then((data) => {
return mergeValues(values, data);
});
return modifiedFile.then((data) => {
return modifiedFile.value();
});
}
console.log(getView('index.html', null));
But for some reason, it’s not working. All I’m getting in the console is the Promise object itself, not the value. And when I add the .isFulfilled method on modifiedFile, it outputs to true. So I’m not sure what I’m doing incorrectly.
Promises don't work that way. They are asynchronous by nature, so you can't interact with them in the same way you do with synchronous code.
That means you have to use the then method to get at the value:
function getView(template, values) {
let file = fs.readFileAsync('./' + template, {encoding: "utf8"});
let modifiedFile = file.then((data) => {
return mergeValues(values, data);
});
return modifiedFile.then((data) => {
return modifiedFile.value();
});
}
// This won't work
// console.log(getView('index.html', null));
// instead:
getView('index.html', null).then(function (view) {
console.log(view);
});
So I’m not sure what I’m doing incorrectly.
You're not doing anything incorrectly, actually. You just can't use promises like a normal return value from a function. Period.