How to pass Variables to the next Middleware in Express.js

avatar
Borislav Hadzhiev

Last updated: Apr 5, 2024
5 min

banner

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

Note: the second subheading shows how to pass custom parameters to middleware functions in Express.

# How to pass Variables to the next Middleware in Express.js

You can set a property on the res.locals object to pass variables to the next middleware in Express.js.

The properties that are set on res.locals are available within a single request-response cycle.

index.js
import express from 'express'; // ๐Ÿ‘‡๏ธ if you use CommonJS require() // const express = require('express') const app = express(); function middleware1(req, res, next) { const site = 'bobbyhadz.com'; // ๐Ÿ‘‡๏ธ 1) set property on res.locals res.locals.site = site; next(); } function middleware2(req, res, next) { // ๐Ÿ‘‡๏ธ 2) access property from previous middleware console.log(res.locals.site); next(); } app.get('/', middleware1, middleware2, function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ 3) access property from first middleware site: res.locals.site, hello: 'world', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The code for this article is available on GitHub

If I run the npx nodemon index.js command and visit http://localhost:5000/, I can see that the request succeeds.

shell
npx nodemon index.js

http request succeeds

The value of the res.locals.site property is also logged to the terminal.

property logged to terminal

We have 2 middleware functions - middleware1 and middleware2.

The first middleware function sets a site property on the res.locals object.

index.js
function middleware1(req, res, next) { const site = 'bobbyhadz.com'; // ๐Ÿ‘‡๏ธ 1) set property on res.locals res.locals.site = site; next(); }

Properties that are set on the res.locals object are available within a single request-response cycle and are not shared between requests.

Once you set a property on the res.locals object, you can access it in the next middleware.

index.js
function middleware2(req, res, next) { // ๐Ÿ‘‡๏ธ 2) access property from previous middleware console.log(res.locals.site); next(); }
The code for this article is available on GitHub

You can also access the res.locals.site property in your last route handler.

index.js
app.get('/', middleware1, middleware2, function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ access property from first middleware site: res.locals.site, hello: 'world', }); });

The res.locals object should be your preferred approach rather than setting properties on the request (req) object.

Here is an example from the Express.js docs on how res.locals is used.

index.js
app.use(function (req, res, next) { // Make `user` and `authenticated` available in next middlewares res.locals.user = req.user res.locals.authenticated = !req.user.anonymous next() })

Setting properties on the res.locals object is useful for exposing request-level information.

Setting properties on the request (req) object is not recommended because you might override properties that were already set on the object.

However, if you decide to set properties on the req object, use the following approach.

index.js
import express from 'express'; // ๐Ÿ‘‡๏ธ if you use CommonJS require() // const express = require('express') const app = express(); function middleware1(req, res, next) { const site = 'bobbyhadz.com'; // ๐Ÿ‘‡๏ธ 1) set property on req req.site = site; next(); } function middleware2(req, res, next) { // ๐Ÿ‘‡๏ธ 2) access property from previous middleware console.log(req.site); next(); } app.get('/', middleware1, middleware2, function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ 3) access property from first middleware site: req.site, hello: 'world', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The code for this article is available on GitHub

The code sample sets the site property on the request (req) object which makes the property available in the next middlewares.

However, as previously noted, it's better to set properties on the res.locals object because you don't risk overriding existing properties.

# Passing custom parameters to middleware functions in Express.js

If you need to pass custom parameters to middleware functions in Express:

  1. Wrap your middleware function in another function.
  2. The outer function should take the custom parameters and should return the true middleware function.
  3. The returned middleware function should take the req, res and next parameters.
index.js
import express from 'express'; // ๐Ÿ‘‡๏ธ if you use CommonJS require() // const express = require('express') const app = express(); // ๐Ÿ‘‡๏ธ takes `site` parameter function middleware1(site) { // ๐Ÿ‘‡๏ธ returns true middleware function return (req, res, next) => { console.log(site); res.locals.site = site; next(); }; } app.get('/', middleware1('bobbyhadz.com'), function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ access property from first middleware site: res.locals.site, hello: 'world', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The code for this article is available on GitHub

If I run the npx nodemon index.js command and visit http://localhost:5000/, I can see that the request succeeds.

shell
npx nodemon index.js

http request succeeds

The value of the site variable is also logged to the terminal.

property logged to terminal

The middleware1 function takes a site variable and returns another function.

index.js
function middleware1(site) { // ๐Ÿ‘‡๏ธ returns true middleware function return (req, res, next) => { console.log(site); res.locals.site = site; next(); }; }

The inner function is the true middleware function that takes the req, res and next parameters.

This way, we can invoke the middleware1() function with a value for the site parameter.

When the middleware1() function is invoked, it returns the inner function but with access to the site parameter.

index.js
app.get('/', middleware1('bobbyhadz.com'), function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ access property from first middleware site: res.locals.site, hello: 'world', }); });

We set the site property on the res.locals object, however, you can also set the property on the req object.

index.js
import express from 'express'; // ๐Ÿ‘‡๏ธ if you use CommonJS require() // const express = require('express') const app = express(); function middleware1(site) { return (req, res, next) => { console.log(site); req.site = site; next(); }; } app.get('/', middleware1('bobbyhadz.com'), function (req, res) { res.json({ // ๐Ÿ‘‡๏ธ access property from first middleware site: req.site, hello: 'world', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The code for this article is available on GitHub

I prefer setting properties on res.locals to avoid overriding properties on the request (req) object by mistake.

The key moment of passing custom parameters to a middleware function is that:

  1. You need to wrap the true middleware function with another function that takes the custom parameters.
  2. The outer function should return the true middleware function (the one that takes req, res and next).
  3. The inner function will have access to the custom parameters.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev