Question: Why does the express router call the params keys?

So I am debugging how to test an express router object. Essentially to have 100%% coverage. Anyways, what I noticed while debugging is that the router object creates a stack of routes. Cool, except when I look at the stack, params are undefined while keys is an array of my params. Pretty misleading. Then in my service, I can request these so called keys as req.params.

Just wonder why the params do not get populated here. Is this params property only for inherited params? like from router.param

Author: Fantashit

1 thought on “Question: Why does the express router call the params keys?

  1. @JemiloII In Layer.prototype.match() of router/layer.js,

    Layer.prototype.match = function match(path) {
      var match
      if (path != null) {
        match = this.regexp.exec(path) // try match the path
      if (!match) { // current match failed, layer.params is undefined and not populated
        this.params = undefined;
        this.path = undefined;
        return false;
      // If matched
      var keys = this.keys;
      var params = this.params;
      for (var i = 1; i < match.length; i++) {
        var key = keys[i - 1];
        var prop =;
        var val = decode_param(match[i]) // using the grouping of regexp
        if (val !== undefined || !(, prop))) {
          params[prop] = val; // populate layer.params HERE!
      return true;

    Also after reviewing the logic of router.handle(), I believe the steps could indeed be understood as:

    1. router.handle() is invoked with a new given path that requires inspection
    2. A path match on some layer stored on the stack is found
      2.1 before this path match returned true, layer.params is populated using the param names stored in layer.keys as keys to establish key value mappings
    3. router.handle then merges current layer.params into req.params
      3.1 router.handle first try processing all param handlers added through router.param()
      3.2 router.handle then calls your provided path handlers, by internally calling layer.handle_request(req, res, next), and that all param data could be accessed through req.params
    4. if you call next() in your provided handler, the router.handle() continues tracing down the router.stack. For each extra match, goto 2. Else done.

    So basically I believe you are correct.

Comments are closed.