Reputation: 1662
I have this function in javascript node
exports.getUserEmailByAccess = async (moduleType) => {
let emailList = []
const foundUsers = await Access.find({moduleType:moduleType})
console.log(foundUsers);
await foundUsers.forEach(access => {
User.findById(access.userId)
.then(foundUser => {
console.log(foundUser.workerEmail);
emailList.push(foundUser.workerEmail)
})
});
console.log(emailList);
return emailList
}
What I want is to push into emailList array by looping object array, the above approach results in an empty array,so I tried a different following way
exports.getUserEmailByAccess = async (moduleType) => {
let emailList = []
const foundUsers = await Access.find({moduleType:moduleType})
console.log(foundUsers);
await foundUsers.forEach(access => {
const foundUser = User.findById(access.userId)
console.log(foundUser.workerEmail);
emailList.push(foundUser.workerEmail)
});
console.log(emailList);
return emailList
}
By doing this , the array list is getting filled but with an [undefined]strong text value, I come from a humble python control structure background, Please can I know why I am not able to push data into array even after using async/await
Upvotes: 1
Views: 78
Reputation: 50830
If the User.findById()
returns a promise, I'd recommend using Promise.all()
instead of individually running all promises using forEach
to fetch documents of all foundUsers
:
exports.getUserEmailByAccess = async (moduleType) => {
const foundUsers = await Access.find({ moduleType: moduleType });
console.log(foundUsers);
const userDocs = await Promise.all(
foundUsers.map((user) => User.findById(user.userId))
);
const emailList = userDocs.map((user) => user.workerEmail);
// or alternatively
// const emailList = userDocs.map(({workerEmail}) => workerEmail);
console.log(emailList);
return emailList;
};
Upvotes: 2
Reputation: 87
How are your Models related? I think you might do a populate here if the Access Model has the ObjectId of the User Model. Something like this:
const foundUsers = await Access.find({ moduleType: moduleType }).populate({
path: 'users', // the name of the field which contains the userId
select: '-__v' // fields to bring from database. Can add a (-) to NOT bring that field
})
The idea is that you specify all the fields that you need. Then when you receive the data, you can do something like:
foundUsers.users.email
Upvotes: 1
Reputation: 1258
you can give try this
exports.getUserEmailByAccess = async (moduleType) => {
let emailList = []
const foundUsers = await Access.find({ moduleType: moduleType })
console.log(foundUsers);
await foundUsers.map(async access => {
let result = await User.findById(access.userId);
if (result) {
emailList.push(foundUser.workerEmail)
}
});
console.log(emailList);
return emailList
}
UPDATED
await Promise.all(
foundUsers.map(async access => {
let result = await User.findById(access.userId);
if (result) {
emailList.push(foundUser.workerEmail)
}
})
])
console.log(emailList);
return emailList
Upvotes: 1