'Passing variables to the next middleware using next() in Express.js

I want to pass some variable from the first middleware to another middleware, and I tried doing this, but there was "req.somevariable is a given as 'undefined'".


//app.js
..
app.get('/someurl/', middleware1, middleware2)
...

////middleware1
...
some conditions
...
res.somevariable = variable1;
next();
...

////middleware2
...
some conditions
...
variable = req.somevariable;
...


Solution 1:[1]

Attach your variable to the req object, not res.

Instead of

res.somevariable = variable1;

Have:

req.somevariable = variable1;

As others have pointed out, res.locals is the recommended way of passing data through middleware.

Solution 2:[2]

This is what the res.locals object is for. Setting variables directly on the request object is not supported or documented. res.locals is guaranteed to hold state over the life of a request.

res.locals (Note: the documentation quoted here is now outdated, check the link for the most recent version.)

An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.

This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.

app.use(function(req, res, next) {
    res.locals.user = req.user;  
    res.locals.authenticated = !req.user.anonymous;
    next();
});

To retrieve the variable in the next middleware:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});

Solution 3:[3]

I don't think that best practice will be passing a variable like req.YOUR_VAR. You might want to consider req.YOUR_APP_NAME.YOUR_VAR or req.mw_params.YOUR_VAR.

It will help you avoid overwriting other attributes.

Solution 4:[4]

The most common pattern for passing variables on to other middleware and endpoint functions is attaching values to the request object req.

In your case, that would mean having middlewares such as these:

app.use(function (req, res, next) {
  req.someVariable = 123;
  next();
});

app.use(function (req, res, next) {
  console.log("The variable is", req.someVariable);
  next();
});

There are many common use cases of this pattern, and it is the standard way of doing it in the express community. See, for example:


It is worth noting that the currently most highly voted answer incorrectly recommends using res.locals for this purpose---which seems to stem from a misreading of the documentation. For that reason, I'll elaborate on why this is not the usual approach to the problem (although it isn't particularly harmful either).

The documentation

As supporting evidence for the res.locals approach being the appropriate one for the case, the now outdated documentation is cited:

An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.

This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.

Note the framing here: res.locals is for variables only available "to the view(s) rendered during that request" (emphasis added).

That is what res.locals relates to. res.render renders some template file with some given data as well as access to the locals. This was actually more clear in the v2 docs, and we've now updated the current Express documentation to be clearer:

Use this property to set variables accessible in templates rendered with res.render. The variables set on res.locals are available within a single request-response cycle, and will not be shared between requests.

In order to keep local variables for use in template rendering between requests, use app.locals instead.

This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on to templates rendered within the application.

(Emphasis added.)

The guide

Further evidence of extending req being the standard approach is found in the guide on Writing Middleware, which states:

Next, we’ll create a middleware function called “requestTime” and add a property called requestTime to the request object.

const requestTime = function (req, res, next) {
 req.requestTime = Date.now()
 next()
}

When this was mentioned in discussion in the answers on this here question, one user responded: "This was the way you'd do it before they added res.locals so might be old docs. res.locals is a namespace specifically for this."

This doesn't track with the history of the codebase, however: locals have been present since v2, which is significantly before e.g. express.json was included in the library, at which point it would have made sense to change the behvaior, if it was indeed correct to save values in res.locals.

Closing notes

Shoutout to @real_ate who wrote in the comments, but was overlooked.

Solution 5:[5]

That's because req and res are two different objects.

You need to look for the property on the same object you added it to.

Solution 6:[6]

The trick is pretty simple... The request cycle is still pretty much alive. You can just add a new variable that will create a temporary, calling

app.get('some/url/endpoint', middleware1, middleware2);

Since you can handle your request in the first middleware

(req, res, next) => {
    var yourvalue = anyvalue
}

In middleware 1 you handle your logic and store your value like below:

req.anyvariable = yourvalue

In middleware 2 you can catch this value from middleware 1 doing the following:

(req, res, next) => {
    var storedvalue = req.yourvalue
}

Solution 7:[7]

This example app uses the requestTime middleware function, which sets a value requestTime on req.

The endpoint function for / uses the property that the middleware function adds to req (the request object).

var express = require('express')
var app = express()

var requestTime = function (req, res, next) {
  req.requestTime = Date.now()
  next()
}

app.use(requestTime)

app.get('/', function (req, res) {
  var responseText = 'Hello World!<br>'
  responseText += '<small>Requested at: ' + req.requestTime + '</small>'
  res.send(responseText)
})

app.listen(3000)

Solution 8:[8]

As mentioned above, res.locals is a good (recommended) way to do this. See here for a quick tutorial on how to do this in Express.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Mortensen
Solution 2 Niels Abildgaard
Solution 3 Niels Abildgaard
Solution 4
Solution 5 SLaks
Solution 6 Peter Mortensen
Solution 7 Niels Abildgaard
Solution 8 nax3t