0

I'm using Node and express and ejs for a simple apple to test with. I have the following piece of code which is triggered by a route call to my results page. What I want is to redirect to the results page after fetching all the results from my mongodb collection. Everything works fine and in my console.log in the GetResults function in my db file the results are being retrieved and returned by the function. I think I'm dealing with the async nature of my call to DBHandler, but how can I accomplish this?

router.get("/results",isLoggedIn, function(req,res){
     var results = DBhandler.GetResults(req,res);

     console.log("value of results right before it is passed to results.ejs:  ", results)

     ////COME BACK AND MAKE THIS A PROMISE TO RUN AFTER THE RESULTS IS FETCHED
     res.render("results.ejs", {results:results});
 });

My DB function

exports.GetResults = function (req, res) {

    console.log(req.body);

    //get all the results
    ResultModel.find({},function(err, result){
        if(err){
            console.log("SOMETHING WENT WRONG GETTING RESULTS: ", err)
        }else{
            console.log("this is the value of result from the getresults call: ", result);
            return result;
        }
    });
}
mo_maat
  • 2,110
  • 12
  • 44
  • 72
  • Show us the code for `DBhandler.GetResults()`. We need to know what it actually returns and how it works. It's likely NOT synchronous so it probably doesn't actually return the results directly like you show. – jfriend00 Dec 31 '17 at 23:25
  • Edit made to add the code for GetResults()... – mo_maat Dec 31 '17 at 23:53
  • As I suspected, the problem is that you aren't returning the value for `GetResults()`. You `return result` just goes back into the `.find()` callback - it does not return from your function. Read the answer to the question yours has been marked a duplicate of for lots of details on why you aren't getting the return value and what your options are for doing it correctly (either pass in a callback or return a promise). – jfriend00 Jan 01 '18 at 00:04
  • I see it's been marked duplicate and I've read through the other post which helps a lot, but it does not get me an answer for my case. I feel like I understand conceptually, but I can't seem to get the implementation right. Not sure if protocol is to figure out it out or if more precise pointers can be given. – mo_maat Jan 01 '18 at 00:33
  • Here are the two lines I've changed on my DBHandler to: `exports.GetResults = function (req, res, callback) {` and `return callback(result);` – mo_maat Jan 01 '18 at 00:34
  • My route call has been modfied to use SunriseM's suggestion below for the callback option, but still no luck as I'm getting undefined for the value being passed to my view page. I just want as plain vanilla javascript a solution as possible without any of the newer solutions. – mo_maat Jan 01 '18 at 00:36
  • The general protocol here would be to incorporate the teachings from the duplicate and if you feel you have studied that and implemented it, but it is still not working, then you file a new attempt that shows your current code and incorporates what you learned from the duplicate and where you got stuck. We mark things duplicates in order to avoid repeating the same answers over and over again here so that people can better be referred to one or two very good answers on the topic rather than lots of scattered dups and so that the remaining answers on the topic are generally of higher quality. – jfriend00 Jan 01 '18 at 01:35

1 Answers1

1

if DBHandler returns a promise you can use

router.get("/results",isLoggedIn, async function(req,res){
 var results = await DBhandler.GetResults(req,res);

 console.log("this is the value of results right before it is passed to results.ejs:  ", results)

 ////COME BACK AND MAKE THIS A PROMISE TO RUN AFTER THE RESULTS IS FETCHED
 res.render("results.ejs", {results:results});
});

if it returns a callback

router.get("/results",isLoggedIn, function(req,res){
   DBhandler.GetResults(req,res, function(err, results){
        console.log("this is the value of results right before it is passed to results.ejs:  ", results)

        res.render("results.ejs", {results:results}); 
   })
 });
SunriseM
  • 985
  • 9
  • 15
  • The actual problem was inside of `DBhandler.GetResults()`. – jfriend00 Jan 01 '18 at 00:04
  • Got it to work. I simply had to remove the err parameter that I was passing in with my callback so that I am only passing in the one parameter. Thanks for the pointers. It all makes sense now. – mo_maat Jan 01 '18 at 01:12
  • @mo_maat - Now you have no way of communicating back an error from the `.find()` operation. That's bad. – jfriend00 Jan 01 '18 at 01:32
  • yeah you should callback the error if it exists, and when using the function check if there's any error in the callback. – SunriseM Jan 01 '18 at 01:34
  • I see will keep playing with it. – mo_maat Jan 01 '18 at 01:37