ppalone
ppalone

Reputation: 1

How to pass data from express-validation middleware to next function?

I have an express app that looks like this.

const app = require('express')();

// Task model
const Task = require('./models/Task');
const { param, validationResult } = require('express-validator');

const getTaskValidations = [
  param('id')
    .custom(async (id, { req }) => {
      try {
        const task = await Task.findOne({ _id: id, user: req.user.id });
        if (!task) Promise.reject('Task not found');
      } catch (err) {
        // Handle error
      }
    })
]

const validate = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(401).json({ message: errors.array()[0].msg });
  }
  next();
}

// Get Task by id
app.get('/tasks/:id', getTaskValidations, validate, async (req, res) => {
  try {
    const task = await Task.findById(req.params.id);
    res.json(task)
  } catch (err) {
    // Handle err
  }
})

I want to get the task by id. In GET tasks/:id the req.params.id will contain the id of the task.
The Task Model looks like this

{
  id: 
  task: 
  user:
}

By looking at the endpoint it is clear that I'm passing two middlewares. The first middleware getTaskValidations will check if the task will given id and req.user exists. The second middleware validate will check for errors. And then again will query database for task and send data to the client causing 2 database queries. How can I reuse the same task obtained in the getTaskValidations middleware.

Upvotes: 0

Views: 2231

Answers (2)

Mohammad Yaser Ahmadi
Mohammad Yaser Ahmadi

Reputation: 5051

you can add result of query add to the req.body.task like this

const getTaskValidations = [
  param('id')
    .custom(async (id, { req }) => {
      try {
        const task = await Task.findOne({ _id: id, user: req.user.id });
        req.body.task = task
        if (!task) Promise.reject('Task not found');
      } catch (err) {
        // Handle error
      }
    })
]

in controller

app.get('/tasks/:id', getTaskValidations, validate, async (req, res) => {
  try {
    let {task} = req.body
    res.json(task)
  } catch (err) {
    // Handle err
  }
})

Upvotes: 1

Roshan Raj
Roshan Raj

Reputation: 198

You can store the response you get from the query in the request(req).

const task = await Task.findOne({ _id: id, user: req.user.id });
if (task) 
     req.task = task;
else 
     Promise.reject('Task not found');

Later on, in the API endpoint, you can simply use

app.get('/tasks/:id', getTaskValidations, validate, async (req, res) => {
  try {
    const task = req.task;
    res.json(task)
  } catch (err) {
    // Handle err
  }
});

to get the task obtained in the getTaskValidations middleware.

Upvotes: 0

Related Questions