Router mergeParams=true does not work

express 4.12.2. According to the Router doc about mergeParams option:

Preserve the req.params values from the parent router. If the parent and the child have conflicting param names, the child’s value take precedence.

May be I miss something, but it does not behave in that way at all:

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


app.get('/users/:username', function(req, res, next) {
        console.log('> app.get');

    if (req.params.username !== 'alice') {
        throw new Error('app.get: username != alice');
    }

    next();
});

var router1 = express.Router({mergeParams: true});
app.use(router1);

router1.get('*', function(req, res, next) {
        console.log('> router1.get');

        // This throws.  
    if (req.params.username !== 'alice') {
        throw new Error('router1.get: username != alice');
    }

    next();
});

app.listen(5000, '0.0.0.0');

Now send a GET request with url “/users/alice” and it will print:

> app.get
> router.get
Error: router1.get: username != alice

Author: Fantashit

1 thought on “Router mergeParams=true does not work

  1. Yes, sorry for the noise.

    I’m not sure if there is such thing as “noise” 🙂 So to answer this, what mergeParams does is merge any req.params that exists at the time the router is entered. The reason it wasn’t doing anything in your example above is because app.use(router1); does not have any parameters. You can see this by doing something like app.use(function (req, res, next) { console.dir(req.params); next() }) and seeing it as nothing there.

    To expand on your example, there are two possible solutions to achieve this, and the correct one for your situation depends on exactly how you are looking for the sub router to behave:

    var express = require('express');
    var app = express();
    
    app.get('/users/:username', function(req, res, next) {
            console.log('> app.get');
    
        if (req.params.username !== 'alice') {
            throw new Error('app.get: username != alice');
        }
    
        next();
    });
    
    var router1 = express.Router({mergeParams: true});
    // now router1 will actually inherit parameters, since it's defined on a path with them
    app.all('/users/:username', router1);
    
    router1.get('*', function(req, res, next) {
            console.log('> router1.get');
    
        if (req.params.username !== 'alice') {
            throw new Error('router1.get: username != alice');
        }
    
        next();
    });
    
    app.listen(5000, '0.0.0.0');

Comments are closed.