eknoor4197
eknoor4197

Reputation: 199

Multiple callbacks in express

I have 2 schemas : Blogdemo and Review. Both in the same file : landing.ejs I want both the content of both the schemas to appear on the landing page.

Code :

   app.get('/', function (req, res,next) {
      Blogdemo.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allBlogs) { //finds the latest blog posts (upto 3)
        if(err) {
            console.log(err);
        } else {
            res.render("landing", {blog : allBlogs , moment : now});
        }
    })
     next();
    }, function (req, res) {
      Review.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allReviews) { //finds the latest reviews (upto 3)
                if(err) {
                    console.log(err);
                } else {
                    res.render("landing", {review : allReviews, moment : now});
                }   
    })
})

I get the error : "review is not defined". If I change the order of the callbacks, I get the error : "blog is not defined". I understand that something is wrong with the callbacks.

I browsed through the express docs and used this :

app.get('/', function (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}, function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

This works perfectly.But I'm following the exact pattern and it's not working. What am I doing wrong?

Upvotes: 0

Views: 1307

Answers (2)

Ravi Shankar Bharti
Ravi Shankar Bharti

Reputation: 9268

I think, what you are doing wrong is rendering same page 2 times with res.render and passing one of the two variables each time, that's why the other one is coming as undefined.

You should render the landing page in the last callback, and just pass variables from first callback to second.

To pass variables from one callback to another, you can use res.locals.

Also, you should put next() inside the callback of find. so that it passes the variable to next callback correctly.

Try this:

app.get('/', function (req, res,next) {
      Blogdemo.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allBlogs) { //finds the latest blog posts (upto 3)
        if(err) {
            console.log(err);
            next();
        } else {
            //set variable in `res.locals` and pass to next callback
            res.locals.blog = allBlogs;
            next();
        }
    })
}, function (req, res) {
      Review.find({}).sort([['_id', -1]]).limit(3).exec(function(err,allReviews) { //finds the latest reviews (upto 3)
                if(err) {
                    console.log(err);
                } else {
                    allBlogs = res.locals.blog;
                    res.render("landing", {blog : allBlogs ,review : allReviews, moment : now});
                }   
    })
})

For more information on res.locals read Express res.locals documentation.

Hope this helps you!

Upvotes: 1

Mukesh Soni
Mukesh Soni

Reputation: 1139

From what I can see you are doing one thing wrong: placing next() outside the async scope.

Try this:

    app.get('/', function(req, res, next) {
        Blogdemo.find({}).sort([
            ['_id', -1]
        ]).limit(3).exec(function(err, allBlogs) { //finds the latest blog posts (upto 3)
            if (err) next(err);
            res.locals.blog = allBlogs;
            res.locals.moment = now;
            next();
        })
    }, function(req, res) {
        Review.find({}).sort([
            ['_id', -1]
        ]).limit(3).exec(function(err, allReviews) { //finds the latest reviews (upto 3)
            if (err) return next(err);
            res.locals.review = allReviews;
            res.render("landing", res.locals); // 2nd argument is optional.
        })
    })

Upvotes: 1

Related Questions