Skip to content

Running validations imperatively #731

@castri1

Description

@castri1

I followed the example below to create a validation middleware using a validation chain:

example:

// can be reused by many routes
const validate = async validations => {
  return (req, res, next) => {
    await Promise.all(validations.map(validation => validation.run(req)));

    const errors = validationResult(req);
    if (errors.isEmpty()) {
      return next();
    }

    res.status(422).json({ errors: errors.array() });
  };
};

app.post('/api/create-user', validate([
  body('email').isEmail(),
  body('password').isLength({ min: 6 })
]), async (req, res, next) => {
  // request is guaranteed to not have any validation errors.
  const user = await User.create({ ... });
});

my code (using typescript):
/models/order.ts

// order validation chain
import { checkSchema, ValidationChain } from 'express-validator';

export const schema: ValidationChain[] = checkSchema({
 orderNumber: {
    isString: true,
    errorMessage: 'Order number is required'
  }
});
import { ValidationChain, validationResult } from 'express-validator';
import { Router, Request, Response, NextFunction } from 'express';

import * as orderModel from '../models/order';

const router = Router();

type RouteHandler = (
  req: Request,
  res: Response,
  next: NextFunction
) => Promise<void>;

// validation middleware
const validate = (validations: ValidationChain[]): RouteHandler => {
  return async (
    request: Request,
    response: Response,
    next: NextFunction
  ): Promise<void> => {
    await Promise.all(
      validations.map(
        (val: ValidationChain): Promise<Context> => val.run(request)
      )
    );

    const result = validationResult(request);

   // result.isEmpty() is always true
    if (!result.isEmpty()) {
      response.status(422).json();
      return;
    }
    next();
  };
};

// route handler using the validation middleware
router.post('/', validate(orderModel.schema), ordersController.createOrder);

The issue is that when awaiting for all the validations in:

await Promise.all(
      validations.map(
        (val: ValidationChain): Promise<Context> => val.run(request)
      )
    );

The request object is not being affected and then when using const result = validationResult(request); No errors are attached to the object. In other words, result.isEmpty() is always true.

I modified the code a little bit just to see what all the promises resolved:

const data = await Promise.all(
      validations.map(
        (val: ValidationChain): Promise<Context> => val.run(request)
      )
    );

And all the errors are inside the data variable. To be specific data is an array of Context objects, and those objects are holding the errors. The issue is that when running validations imperatively the request object is not being affected.

Im using express-validator version 6.0.1

Thanks for your help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions