Skip to content Skip to sidebar Skip to footer

How Do I Pass Data Returned From A Controller To Express' Router?

I'm trying to make a catch-all of sorts to return data to my Author endpoint. If the url that is passed to the endpoint contains no query parameters, I want the router to return th

Solution 1:

You get cannot set headers after they are sent when you have two res.[whatever]s in your route. So you have res.send(functionCallThatAlsoDoesRes.Send). That's what's causing the error.

If you want a route to take multiple actions between the request and the response, you can write those as separate middlewares. Middlewares always take the arguments req, res, and next (a function that says to go to the next middleware in the list).

So, you might write:

authorController.findAuthorsByFirstAndLastName = function(req, res, next) {
  if (!(req.query.firstName || req.query.lastName)) {
    res.locals.getFullAuthorList = true
    return next()
  } else {
    const query = /* whatever */
    Author.find(query, (err, authors) => {
      if (err) return next(err)
      res.locals.authors = authors
      next()
    })
  }
}

authorController.author_list = function(req, res, next) {
  if (!res.locals.getFullAuthorList) return next() // if we already have authors we don't need to do anything
  Author.find({}, (err, authors) => {
    if (err) return next(err)
    res.locals.authors = authors
    next()
  })
}

Then in your route, you'd say:

router.get('/', authorController.findAuthorsByFirstAndLastName, authorController.author_list, (req, res) => {
    res.json({ authors: res.locals.authors })
})

If you haven't seen res.locals before, it's just a property on the response object that is available for you to attach things to. It persists throughout the request/response cycle and is cleared for each new request.


Post a Comment for "How Do I Pass Data Returned From A Controller To Express' Router?"