I have a few async methods that I need to wait for completion before I return from the request. I\'m using Promises, but I keep getting the error:
Each then(
Just avoid the Promise constructor antipattern! If you don't call resolve
but return a value, you will have something to return
. The then
method should be used for chaining, not just subscribing:
outer.get('/account', function(req, res) {
var id = req.user.uid
var userRef = firebase.db.collection('users').doc(id)
var profilePromise = userRef.get().then(doc => {
if (doc.exists) {
var profile = doc.data()
profile.id = doc.id
return profile // I assume you don't want to return undefined
// ^^^^^^
} else {
throw new Error("Profile doesn't exist")
// ^^^^^
}
})
// More promises further on, which I wait for:
// profilePromise.then(myProfile => { … });
})
If you can't fix this issue but still want to run your code...
open : eslintrc.json file (search from project root directory)
search : 'promise/always-return'
change : Case 1: if (existing value is 2) => change to 1
Case 2: else if(existing value is "error" => change to "warn")
It will make this error into warning, but be careful with it... Also use eslint plungin in your editor to remind of good practice. Otherwise you won't get any promise/always-return related warnings.
Also make sure you find the right eslintrc.json if more than 1 appears on your search
Add at the end of the then()
return null
That's it.
Each then() should return a value or throw Firebase cloud functions
In your case firebase.db.collection('users').doc(id)
returning promise
itself, please check firebase snippet to here for node-js.
If you have multiple promises and you need to call them one by one then use Promises chaining.
Please check this article this will help you.
Use following code in your case,
router.get('/account', function(req, res) {
var id = req.user.uid;
var myProfile = {};
var userRef = firebase.db.collection('users').doc(id)
userRef.get()
.then(doc => {
if (!doc || !doc.exists) {
throw new Error("Profile doesn't exist")
}
var profile = doc.data();
profile.id = doc.id;
myProfile = profile;
return myProfile;
})
.catch(error => {
console.log('error', error);
})
})
And use Promise.all if you have multiple promises and you want's to execute them in once.
The Promise.all(iterable)
method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.
For example:
var promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo1');
});
var promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo2');
});
var promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo3');
});
Promise.all([promise1, promise2, promise3])
.then(result => console.log(result))
//result [foo1, foo2, foo3]
Hopes this will help you !!