How to export and use a Local Middleware with Express Route?

Asked

Viewed 383 times

0

I’m having two difficulties which are:

  • 1) I’m trying to export and use mine middleware to be used locally.
  • 2) I would also like to know if it is possible to use a middleware for a specific request type using the Express Route.

What is occurring in the first difficulty?

I’m only getting to use the middleware exported if it is global, as local on the routes it seems that it is not called.

What is occurring in the second difficulty?

Any kind of requisition that’s nested that route will call that middleware, but if I want to put the middleware for a specific route which is the case of checkProjectPost, how it should be done using the express router?

Index.js

const express = require('express');
const cors = require('cors');
const bodyParser = require ('body-parser');
const routes = require('./routes');
const middleware = require('./middlewares');


const server = express();
server.use(cors());
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: false }));
// server.use(middleware.checkId);
server.use(routes);
server.listen(3000, 'localhost', () => console.log('SERVER [ONLINE]'));

module.exports = server;

Routes.js

const express = require('express')
const router = express.Router();
const middleware = require('./middlewares');

router.route('/projects', middleware.checkProjectPost)
  .get((req, res) => {
    console.log("GET")
    return res.status(200).send();
  })
  .post((req, res) => {
    req.body.tasks = [];

    return res.status(200).send({ msg: 'Success, project created!' });
  });

router.route('/projects/:id', middleware.checkId)
  .put((req, res) => {})
  .delete((req, res) => {});

router.route('/projects/:id/tasks', middleware.checkId)
  .post((req, res) => {});

module.exports = router;

Middlewares.js

module.exports = {
  checkId: (req, res, next) => {
    const { id } = req.params;

    return (!id && typeof id !== 'string') 
      ? res.status(400).send({ errorMsg: 'The id property is empty or the type is different from string' })
      : next();
  },
  checkProjectPost: (req, res, next) => {
    console.log()
    const { id, title } = req.body;
    console.log (req)

    if (!id && typeof id !== 'string' || !title && typeof title !== 'string') {
      return res.status(400).send({ errorMsg: 'The id or title property is empty or the type is different from string' })
    } else {
      req.body.tasks = [];
      return next();
    }
  },
  showQuantityRequisition: (req, res, next) => {

  }
}

2 answers

1

Hello tdb friend? So from what I understand you’re just having trouble implementing a middleware within a correct route? If this is the case you can use your middleware in the following way by following this example:

post("/registro", (req, res) => {
    var erros = []

    if(!req.body.nome || typeof req.body.nome == undefined || req.body.nome == null){
        erros.push({texto: "Nome inválido!"})
    }

    if(!req.body.email || typeof req.body.email == undefined || req.body.email == null){
        erros.push({texto: "Email inválido!"})
    }

    if(!req.body.senha || typeof req.body.senha == undefined || req.body.senha == null){
        erros.push({texto: "Senha inválida!"})
    }

    if(req.body.senha.length < 4){
        erros.push({texto: "Senha muito curta"})
    }   

    if(req.body.senha != req.body.senha2){
        erros.push({texto: "As senhas são diferêntes, tente novamente!"})
    }

    if (erros.length > 0) {

        res.render("usuarios/registro", {erros: erros})

    } else {
        Usuario.findOne({email: req.body.email}).then((usuario) =>{
            if (usuario) {
                req.flash("error_msg", "Email já cadastrado!")
                res.redirect("/usuarios/registro")
            } else {

                const novoUsuario = new Usuario({
                    nome: req.body.nome,
                    email: req.body.email,
                    senha: req.body.senha
                })

                bcrypt.genSalt(10, (erro, salt) => {
                    bcrypt.hash(novoUsuario.senha, salt, (erro, hash) => {
                        if (erro) {
                            req.flash("error_msg", "Não foi possível salvar novo usuário")
                            res.redirect("/")
                        }

                        novoUsuario.senha = hash

                        novoUsuario.save().then(() => {
                            req.flash("success_msg", "Usuário criado com sucesso!")
                            res.redirect("/")
                        }).catch((err) => {
                            req.flash("error_msg", "Houve um erro ao criar novo usuário")
                            res.redirect("/usuarios/registro")
                        })

                    })
                })

            }
        }).catch((err) => {
            req.flash("error_msg", "Houve um erro interno")
            res.redirect("/")
        })
    }
})

In this example I created an error handling array before passing the specific post function which was to register new user you can pass the error data directly on the answers as I did Another way is to create in a separate folder as you did and pass before req and res for example:

const express = require('express')
const router = express.Router()
const eAdmin = require('../Path_do_middleware')

//Exemplo de rota X
router.get('/', eAdmin, (req, res) funcionou() {
  res.render('index')//a função vai sempre depois da rota
})
  • Hello friend, thank you for the patience and willingness to answer, but your answer does not match what I expected, the user @user140828 answered the same perfectly. I would like to leave here also some code standardization tips for you, for example: You did req.body.password == null and also req.body.password == Undefined, for you to check if this property exists do not need to compare this way, just enter "req.body.password" will be checked if this property exists. And the second tip is about your code, separate your project by good practice.

  • thank you very much Thiago I will refactor my codes this way from now on, thanks for the tip

0


You are passing the wrong parameters to the methods.

The method route() of router takes only one parameter: the string with its path. Passing the middleware as the second parameter will have no effect, if you want this middleware to run before the other handlers, you can pass it to the method all(), that is always fired, no matter if the request is of the type GET, POST, PUT, DELETE.

Example:

router.route('/projects')
  .all(middleware.checkProjectPost)
  .get((req, res) => {
    console.log("GET")
    return res.status(200).send();
  })
  .post((req, res) => {
    req.body.tasks = [];
    return res.status(200).send({ msg: 'Success, project created!' });
  });

Now if you want the middleware running only on a route request type, as for example on POST, no mystery, just pass it as a parameter for the post(), because this method accepts any number of parameter, and will continue running these middlewares sequentially until the function next() is no longer invoked:

router.route('/projects')
  .get((req, res) => {
    console.log("GET")
    return res.status(200).send();
  })
  .post(middleware.checkProjectPost, (req, res) => {
    req.body.tasks = [];
    return res.status(200).send({ msg: 'Success, project created!' });
  });
  • That’s what I needed. Before I was doing without the route of the express, so I put on the right the middlewares, but with the express route he did not accept there did not understand anything.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.