问题
I am using express.js , node.js to connect mongoDB.
My aim
I have a quiz-collection. I have an **answers-collection****. When I am showing the user the quiz list, I want to show the user if he/she has already participated in any of the quizzes.
My way
- I added a Boolean field to each document in quiz collection as "user_participated" : false .
- When my route calls "/all-quizzes", it calls a function from controller, which first sets all the document "user_participated" false in side a forEach, then as per current "user_id" and "quiz_id" finds one data from "answers" collection inside the same forEach, and if it exists then it set the quiz document's "user_participated" to true. then it returns the whole data.
My problem
in controller function soon it finds all quiz documents, it does not wait till the 'forEach' gets executed and returns that data then it executes the 'forEach'. so when I refresh the page again I can see the manipulations that I made.
HERE IS MY CODE
exports.getAllQuiz = async function(req, res){
var newQuiz = new Quiz; // declaring that newQuiz is an instance of quiz helper
try{
var finalQuizs = await newQuiz.findAll();
var authToken = req.cookies.auth; // getting the logged in user token
var autherised_user = '';
if(authToken != undefined && authToken != null && authToken.trim().length > 0){
jwt.verify(authToken, config.secret, function(err, decoded) {
if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' });
else {
autherised_user = decoded.id;
finalQuizs.forEach(async function(item){
// first I am setting all the document's user_participated value to false
await quizModel.findOneAndUpdate({_id : ObjectId(item._id)}, {user_participated : false});
// now I am setting selected documents user_participated to true as per current user
// for that I am checking in answer collection if a data is present with
// current user id and this quiz id
await AnswerModel.findOne({quiz_id : item._id, participated_user_id : autherised_user}, async function(err, result){
if(result != null){
await quizModel.findOneAndUpdate({_id : ObjectId(item._id)}, {user_participated : true});
}
});
});
}
});
}
return finalQuizs;
}catch(e){
}
};
回答1:
I think your return value finalQuizs
is filled before the forEach
statement. So the update queries does not change it as you expect. This is the reason of getting updated data after the page refresh.
If you expect to have user_participated: true
in the returned value, you should get it after findOneAndUpdate
line.
You should do something like this at the end of try
block:
return await newQuiz.findAll();
来源:https://stackoverflow.com/questions/54059355/express-node-js-controller-not-waiting-for-data-manipulation-and-returning-old-d