Express.js无法读取未定义的属性'req'

时间:2017-01-23 08:13:33

标签: javascript node.js express

我的Express.js应用已投掷Cannot read property 'req' of undefined。实质上,它会侦听GET请求,获取content查询,然后使用表进行回复。以下是提出问题的部分。

index.js

var panels = require('./modules/panels.js');
app.get('/panel', function (req, res) {
    var user;
    if (user = req.session.user) {
        panels.getContents(req.query.content, user.innId, res.send);
    } else {
        res.sendStatus(401);
    }
});

模块/ panels.js

exports.getContents = function(panelName, innId, callback) {
    var response = "";
    switch (panelName) {
        case 'tenants':
            con.query(queryString, queryParams, function(err, rows) {
                if (err) {
                    handle(err);
                } else {
                    if (rows.length == 0) {
                        var tenants = 0;
                        var debtors = 0;
                    } else {
                        var tenants = rows[0].tenants;
                        var debtors = rows[0].length;
                    }
                    response = convertToHTMLTable(rows);
                }
                callback(response); /*THE ERROR POINTS HERE */
            });
            break;

        /* other cases here */

        default:
            response += "Invalid Request";
            callback(response);
    }
}

我做错了什么?我的猜测是我不想将res.send作为回调传递。那么,我该如何解决呢?

3 个答案:

答案 0 :(得分:24)

我也遇到了这个错误,在稍微咀嚼错误信息并盯着我的代码太长时间后,它点击了。

我(和上面的提问者)的代码看起来像这样:

handler(req, res) { somethingAsync .then(res.send) // <-- storing send() divorced from parent object "res" }

问题是,当res.send稍后被调用时,它与动态范围脱节 - 这意味着在this方法内调用send,这通常会引用{ {1}},现在请参阅res。显然,global包含对res.send的引用,给出错误消息。

等效方案:

this.req

或者,换句话说:

res = {
    send: function() { 
        console.log(this.originalMessage.req);
    },
    originalMessage: { req: "hello SO" },
};

res.send();
// # "hello SO"
const x = {};
x.send = res.send;
x.send();
// # Uncaught TypeError: Cannot read property 'req' of undefined

两个解决方案:

new Promise(_ => _()) .then(_ => console.log(this.msg.req)); // # Uncaught (in promise) TypeError: Cannot read property 'req' of undefined

理论上更惯用的方法是

// ES6 handler(req, res) { somethingAsync .then(() => res.send()) // <- send is called as a method of res, preserving dynamic scope }

动态范围的恶劣小问题,那一个。好像快递应该放弃那里的动态范围,或者至少抛出一个更好的错误......

答案 1 :(得分:2)

index.js

中试试
panels.getContents(req.query.content, user.innId, res);

并进入panels.js

exports.getContents = function(panelName, innId, response) {
    var response = "";
    switch (panelName) {
        case 'tenants':
            con.query(queryString, queryParams, function(err, rows) {
                if (err) {
                    handle(err);
                } else {
                    if (rows.length == 0) {
                        var tenants = 0;
                        var debtors = 0;
                    } else {
                        var tenants = rows[0].tenants;
                        var debtors = rows[0].length;
                    }
                    response.send(convertToHTMLTable(rows));
                }
            });
            break;

        /* other cases here */

        default:
            error += "Invalid Request";
            response.send(error)
    }
}

答案 2 :(得分:1)

当您将res.send作为参数传递给getContents函数(panels.getContents(req.query.content, user.innId, res.send);)时,它会传入一个新变量,您将其称为callback

因此,res.send现在已从原来的/应该的lexical context / binding剥离 在这种情况下为res对象,并且看来res.send使用reqres对象中使用this.req属性。

您在这里所做的是无意地将函数this的{​​{1}}的值更改为全局对象。

解决方案

有两种方法可以解决此问题

  • send

//或

  • panels.getContents(req.query.content, user.innId, () => res.send);

在第二个解决方案中,您将函数panels.getContents(req.query.content, user.innId, res.send.bind(res));绑定为始终将res.send的任何值视为this对象(res