Reputation: 121
I am integrating a website with firebase. I am trying to get user IDs from my users collection in the database and then pass each of the user IDs to another function that gets the experience data from another collection. I order the users by name because i want the users sorted alphabetically on my page. The code works as I have it except that the promises do not resolve in the correct order and thus are not output alphabetically. Please see details below:
Why are the IDs not resolving in the order that they were passed?
function getUserProfiles(){
//get users, usernames and render profiles
db.getUsers().then(users => {
console.log('first index:', users[0].id);
console.log('second index:', users[1].id);
console.log('third index:', users[2].id);
users.forEach(user => {
db.getLatestExperience(user.id).then(()=>{
})
})
}
Class {
getLatestExperience(id, callback) {
console.log('getLatestExperience before database request:', id);
return this.experience.where('userID', '==', id).orderBy('start','desc').get().then(snapshot => {
console.log('getLatestExperience promise resolved', id);
})
}
getUsers(callback) {
return this.users.orderBy('name').get().then(snapshot => {
return snapshot.docs;
})
}
}
first index: ZKnqtLVzUqNqdzX9f8ap76LThh32
second index: 482uR9t2QEdCUi0Z4nq14VRVhEx1
third index: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
getLatestExperience before database request: ZKnqtLVzUqNqdzX9f8ap76LThh32
getLatestExperience before database request: 482uR9t2QEdCUi0Z4nq14VRVhEx1
getLatestExperience before database request: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
getLatestExperience promise resolved: 482uR9t2QEdCUi0Z4nq14VRVhEx1
getLatestExperience promise resolved: ZKnqtLVzUqNqdzX9f8ap76LThh32
getLatestExperience promise resolved: 7bJBqk2gQBeTIZOY5h3FikO0Yqm2
Upvotes: 0
Views: 53
Reputation: 7012
You can use Promise.all
in order to resolve when all users return. Promise.all
have it built in to order the result array the same as the given promises
function getUserProfiles() {
//get users, usernames and render profiles
return db.getUsers()
.then(users => {
console.log('first index:', users[0].id);
console.log('second index:', users[1].id);
console.log('third index:', users[2].id);
const latestExperiencePerUserPromises = users
.map((user) => db.getLatestExperience(user.id));
return Promise.all(latestExperiencePerUserPromises);
});
}
Upvotes: 0
Reputation: 2180
You can put the promises in an array and reduce
them so they execute sequential:
const promiseArray = [promise2, promise3...]
promiseArray.reduce(
(prev, next) => prev.then(prevResult => next(prevResult)), promise1())
.then(finalResult => {...})
promiseArray
is an array of functions that returns a promise. You leave out the first one, as you need a starting one later.
Array.reduce
will execute one after another.
prev
is your previous promise you are resolving and if needed, for the next one, you can resolve it with a result and pass it over to next.
Finally at the end you can resolve the whole reduce with one single result from the last promise.
Upvotes: 0