Skip to content
This repository has been archived by the owner on Jun 19, 2021. It is now read-only.

Commit

Permalink
Request handlers now receive a state object
Browse files Browse the repository at this point in the history
Controllers now pass the request state as an additional parameter
to the route handlers. The state can be used to store temporary data,
which the different route callbacks and handlers can use while
handling the request:

get('/records', function(req, res, params, state) {
  state.user = 'john';
  req.next();
}, function(req, res, params, state) {
  res.end(state.user);
});
  • Loading branch information
mendezcode committed Jan 17, 2015
1 parent f3b0f7a commit 30d3b42
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 4 deletions.
9 changes: 6 additions & 3 deletions lib/controller.js
Expand Up @@ -204,24 +204,27 @@ Controller.prototype.filter = function(cb) {
*/

Controller.prototype.runFilters = function(req, res, params, callback) {

var self = this,
filters = (req.__skipFilters) ? [] : this.filters,
fCount = filters.length;

var state = {}; // Request state

// Work with a copy of callback array
var chain = callback.slice(0);

if (chain.length > 1) {
req.next = function() {
var cb = chain.shift();
if (cb instanceof Function) cb.call(self, req, res, params);
if (cb instanceof Function) cb.call(self, req, res, params, state);
}
}

if (fCount === 0) {

// No filters to run, execute callback directly
chain.shift().call(this, req, res, params);
chain.shift().call(this, req, res, params, state);

} else {

Expand All @@ -233,7 +236,7 @@ Controller.prototype.runFilters = function(req, res, params, callback) {
promise.on('success', function() {
if (++i == fCount) {
// No more filters to run, execute callback directly
chain.shift().call(self, req, res, params);
chain.shift().call(self, req, res, params, state);
} else {
// Run filter
filter = filters[i];
Expand Down
25 changes: 25 additions & 0 deletions test/fixtures/test.skeleton/app/controllers/main.js
Expand Up @@ -359,6 +359,31 @@ function MainController(app) {
res.end('THIS SHOULD NOT RENDER');
});

/* Request State */

var states = [], a = 1000, b = 100, c = 1;

get('/request-state', function(req, res, params, state) {
if (req.queryData.check) {
res.json({
checksPassed: ! (states[0] === states[1] && states[1] === states[2] && states[0] === states[2]), // states should be different
length: states.length
});
} else {
states.push(state);
state.a = ++a;
req.next();
}
}, function(req, res, params, state) {
state.b = ++b;
req.next();
}, function(req, res, params, state) {
state.c = ++c;
req.next();
}, function(req, res, params, state) {
res.json(state);
});

}

module.exports = MainController;
52 changes: 51 additions & 1 deletion test/unit/controller.js
Expand Up @@ -3,6 +3,9 @@ var app = require('../fixtures/bootstrap'),
vows = require('vows'),
assert = require('assert'),
util = require('util');

var Multi = protos.require('multi');
var EventEmitter = require('events').EventEmitter;

app.logging = false;

Expand Down Expand Up @@ -112,6 +115,53 @@ vows.describe('lib/controller.js').addBatch({
assert.equal(alias, 'blog');
}

}
},

'Request State': {

topic: function() {

var promise = new EventEmitter();
var multi = new Multi(app);

multi.curl('-i /request-state');
multi.curl('-i /request-state');
multi.curl('-i /request-state');
multi.curl('-i -G -d "check=true" /request-state');

multi.exec(function(err, results) {
if (err) {
console.exit(err);
} else {
promise.emit('success', results);
}
});

return promise;

},

'Is properly set for each request': function(results) {

var r1 = results[0],
r2 = results[1],
r3 = results[2],
r4 = results[3];

assert.isTrue(r1.indexOf('HTTP/1.1 200 OK') >= 0);
assert.isTrue(r1.indexOf('{"a":1001,"b":101,"c":2}') >= 0);

assert.isTrue(r2.indexOf('HTTP/1.1 200 OK') >= 0);
assert.isTrue(r2.indexOf('{"a":1002,"b":102,"c":3}') >= 0);

assert.isTrue(r3.indexOf('HTTP/1.1 200 OK') >= 0);
assert.isTrue(r3.indexOf('{"a":1003,"b":103,"c":4}') >= 0);

assert.isTrue(r4.indexOf('HTTP/1.1 200 OK') >= 0);
assert.isTrue(r4.indexOf('{"checksPassed":true,"length":3}') >= 0);

}

}

}).export(module);

0 comments on commit 30d3b42

Please sign in to comment.