Quesofat
Quesofat

Reputation: 1531

Making a function an express middleware in a route

So I have a route and I have some ugly code in the route that I'd like to make a middleware. The only problem is that Express's documentation isn't clear and my code just 404s.

How can I accomplish this?

Route:

router.get('/product/:slug', function(req, res) {
//route params
  var slug = req.params.slug;
  var productResp; //scope up api response to pass to render()
  console.log(slug);
//api call
  Prismic.api("https://prismic.io/api").then(function(api) {
    return api.getByUID('product' , slug);
  }).then(function(response) {

   app.use(markedHtml)
  })
  .catch(function(error) {
    res.render('404');
  })
});

Function:

  var markedHtml = function(req, res, next) {
      var md_col_1 = response.data["product.markdown-col-one"].value[0].text;
      var md_col_1_1 = response.data["product.markdown-col-one"].value[1].text;
      var md_col_2 = response.data["product.markdown-col-two"].value[0].text;
      var md_col_2_1 = response.data["product.markdown-col-two"].value[1].text;
      var md_col_3 = response.data["product.markdown-col-three"].value[0].text;
      var md_col_3_1 = response.data["product.markdown-col-three"].value[1].text;


      var html_col_1 = marked(md_col_1);
      var html_col_1_1 = marked(md_col_1_1);
      var html_col_2 = marked(md_col_2);
      var html_col_2_1 = marked(md_col_2_1);
      var html_col_3 = marked(md_col_3);
      var html_col_3_1 = marked(md_col_3_1);



    res.render('product-template', {
      product: response,
      md_one: html_col_1,
      md_one_1: html_col_1_1,
      md_two: html_col_2,
      md_two_1: html_col_2_1,
      md_three: html_col_3,
      md_three_1: html_col_3_1,
    })

      next();
    }

Upvotes: 0

Views: 1868

Answers (1)

Ezra Chang
Ezra Chang

Reputation: 1298

In your root app.js, you should see all of the middleware your app is using. These middleware are matched sequentially. If they do not include the route argument, they will naturally be applied to all requests. Your routes are among them, and they look something like this: app.use('/', routes);.

Underneath your routes in app.js, declare a new one:

const markedHtml = require('./middleware/markedHtml');
app.use('/product/:slug', markedHtml);

In ./middleware/marketHtml.js, your method will appear like so, without the next call:

const markedHtml = function(req, res, next) {
  // Do stuff with req.apiResponse here.
  ...

  res.render('product-template', {
    ...
  });
}

module.exports = markedHtml;

Your original route will look like this:

router.get('/product/:slug', function(req, res, next) {
  //route params
  var slug = req.params.slug;
  var productResp; //scope up api response to pass to render()
  console.log(slug);

  //api call
  Prismic.api("https://prismic.io/api").then(function(api) {
    return api.getByUID('product' , slug);
  }).then(function(response) {
    req.apiResponse = response;
    next();
  })
  .catch(function(error) {
    res.render('404');
  });
});

Essentially, your original route will receive the client request, do the API calls etc, then (pun!) run into the next(); invocation. That cues express to execute the next applicable middleware, which happens to be markedHtml, from where the view render method will be invoked.

Let me know if anything was unclear or requires additional explanation.

Additional documentation can be found here: http://expressjs.com/en/4x/api.html#app.use

Upvotes: 1

Related Questions