Express node.js controller not waiting for data manipulation and returning old data

末鹿安然 提交于 2020-01-15 05:13:08

问题


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

  1. I added a Boolean field to each document in quiz collection as "user_participated" : false .
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!