简体   繁体   中英

Why am I getting this weird “Cannot set property of undefined” in node.js

I have a very simple nodeunit test, exactly like this:

'use strict';

var controllerUtils = require('../lib/controllerUtils');

function Mock() {
    this.req = { headers: {} };
    this.res = { };
    this.nextWasCalled = false;
    this.next = function() {
        this.nextWasCalled = true;
    };
}

module.exports = {
    'acceptJson': {
        'Verify proper headers were set': function(test) {
            var mock = new Mock();
            controllerUtils.acceptJson(mock.req, mock.res, mock.next);

            test.ok(mock.nextWasCalled);
            test.equal(mock.req.headers.accept, 'application/json');
            test.equal(mock.res.lean, true);
            test.done();
        }
    }
}

But when I call controllerUtils.acceptJson I get the error TypeError: Cannot set property 'nextWasCalled' of undefined .

So I have tested it on chrome's console and on node command line, the test was:

function Mock() {
    this.req = { headers: {} };
    this.res = { };
    this.nextWasCalled = false;
    this.next = function() {
        this.nextWasCalled = true;
    };
}

var m = new Mock();
console.log(m.nextWasCalled); //logs false
m.next();
console.log(m.nextWasCalled); //logs true

I can't figure out why my code is not working since this is a very trivial code and it works great on both chrome's console and node command line.

PS.: Code on controllerUtils.acceptJson :

module.exports.acceptJson = function(req, res, next) {
    req.headers.accept = 'application/json';
    res.lean = true;

    next();
};

controllerUtils.acceptJson gets as parameter a reference to a function. It has no idea in which context it should call that function, so it calls it without any context.

Your next method requires that the context be the object in which it was defined. There are two ways to fix your code:

Bind the function to the context when you pass it as parameter:

controllerUtils.acceptJson(mock.req, mock.res, mock.next.bind(mock));

Bind the function to the context when you define it:

this.next = function() {
    this.nextWasCalled = true;
}.bind(this);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM