0

I am very new to mongoose and javascript promise. I am going to write update query in global promise way and my code is in the following-

metadataAPI.route('/:surveyID')
    .put(function(req, res) {
        Surveys.findOne({_id : req.params.surveyID}, {"metadata" : 1})
            .then(function(survey) {
                return survey.metadata;
            })
            .catch(function(err) {
                res.json({ Message : "Incorrect surveyID!"});
            })
            .then(function(metadata) {
                Surveys.findOneAndUpdate(
                        {_id : req.params.surveyID},
                        {
                            $set : {
                                "metadata.language" : req.body.language || metadata.language,
                                "metadata.createdBy" : req.body.createdBy || metadata.createdBy,
                                "metadata.qCount" : req.body.qCount || metadata.qCount,
                                "metadata.category" : req.body.category || metadata.category,
                                "metadata.suggestionEnable" : req.body.suggestionEnable || metadata.suggestionEnable,
                                "metadata.publish" : req.body.publish || metadata.publish,
                                "metadata.pageArray" : req.body.pageArray || metadata.pageArray
                            }
                        }
                    )
                    .then(function() {
                        Surveys.findOne({_id : req.params.surveyID}, {"metadata" : 1})
                            .then(function(survey) {
                                res.json(survey);
                            })
                            .catch(function(err) {
                                res.send(err);
                            });         
                    })
                    .catch(function(err) {
                        res.send(err);
                    }); 
            })
            .catch(function(err) {
                res.send(err);
            });
    });

My problem is that although I have the catch() handler after each of then() function. I still get the UnhandledPromiseRejectionWarning from node. How can I solve it. Thank you!

Randal
  • 13
  • 5
  • Your main problems are that you are not chaining properly (`return` from your `then` callbacks, put one `catch` in the end) and that you still call `Surveys.findOneAndUpdate` when you have an incorrect id, as you've *handled* that already in the `catch`. – Bergi Jan 13 '17 at 02:50
  • What's the stack trace? What's the error message? – Bergi Jan 13 '17 at 02:50
  • Btw, this might be a duplicate of [Node.js UnhandledPromiseRejectionWarning even after catching it](http://stackoverflow.com/q/41247012/1048572) - see [mongoose bug #4824](https://github.com/Automattic/mongoose/issues/4824). Apart from fixing the code as suggested in @danh's answer, try updating your library. – Bergi Jan 13 '17 at 03:05
  • Thanks! I have read the read the articles. and will try their solution. : ) – Randal Jan 13 '17 at 03:20

1 Answers1

0

One of the benefits of promises is that you can flatten out a sequence of async operations. Without evaluating anything about your logic, I've flattened the operations, adding a catch at the end for any error that happens along the chain..

Surveys.findOne({_id : req.params.surveyID}, {"metadata" : 1}).then(function(survey) {
    var metadata = survey.metadata;
    return Surveys.findOneAndUpdate({_id : req.params.surveyID},
        {
            $set : {
                "metadata.language" : req.body.language || metadata.language,
                "metadata.createdBy" : req.body.createdBy || metadata.createdBy,
                "metadata.qCount" : req.body.qCount || metadata.qCount,
                "metadata.category" : req.body.category || metadata.category,
                "metadata.suggestionEnable" : req.body.suggestionEnable || metadata.suggestionEnable,
                "metadata.publish" : req.body.publish || metadata.publish,
                "metadata.pageArray" : req.body.pageArray || metadata.pageArray
            }
        }
    )
}).then(function() {
    return Surveys.findOne({_id : req.params.surveyID}, {"metadata" : 1});
}).then(function(survey) {
    res.json(survey);
}).catch(function(err) {
    res.send(err);
});

Quick note on content, I can't remember if mongoose requires that you chain .exec() to the query operations to get promises back.

danh
  • 62,181
  • 10
  • 95
  • 136
  • Regarding `.exec()` - it [did](http://stackoverflow.com/q/41247012/1048572) require it if you wanted to avoid unhandled rejections :-) – Bergi Jan 13 '17 at 03:06
  • Show me how to flatten the code do very help!!! That what I am trying to do but cannot do it properly. – Randal Jan 13 '17 at 03:11