错误无法设置undefined的属性

时间:2016-12-11 18:08:01

标签: javascript node.js mongoose

嗨我在Node.Js中有这个代码,在这里我用mongoose实现查找查询

router.post('/query',function(req,res,next){
    if (req.body){
        var result=[];
        console.log(req.body.filters);
        Pollee.find(req.body.filters)
        .select('id age birthday user')
        .populate('user','email')
        .lean(true)
        .exec(function(err,pollees){
            if(err) {
                console.log(err);
                return next(err);
            }
            for (var i = 0; i < pollees.length; i++){              
            var query =  test(pollees[i]._id);
            query.exec(function(err,inters){
                if(err)
                    return console.log(err);
                inters.forEach(function(inter){
                    pollees[i].interaction = inter; 
                });
            });
            }
            res.json(pollees);    
            };
        }) 
    }
});

function test(id){
   var promise = Interaction.find({pollee:id}).select('status other');
   return promise;
}

当我尝试在pollees [i]上传递此查询的结果时,我的问题出现在Interaction.find中; .interaction = inter;控制台设置我错误

  

无法设置属性pollees [i] .interaction = inter;未定义的

有什么想法吗?

我使用的模型

var interactionSchema = new Schema({
    pollee: { type: ObjectId, ref: 'Pollee' },
    answers: { type: [ObjectId], ref: 'Answer', autopopulate: true },
    status: type: String
});

var PolleeSchema = new Schema({
    firstName: String,
    lastName: String,
    gender: String,
    user: { type: ObjectId, ref: 'User', required: true }, 
    interactions: { type: [ObjectId], ref: 'Interaction', autopopulate: true }
});

var userSchema = new Schema({
    email: String,
    pollee: { type: Schema.Types.ObjectId, ref: 'Pollee', autopopulate: true }
});

非常感谢!

1 个答案:

答案 0 :(得分:0)

我要说明以下问题:在代码的for周期中,您正在调用异步方法query.exec()。当它执行它的回调时,循环已经完成并且值为i === pollees.length。因此,pollees[i]指向不存在的数组元素(未定义),并且当您尝试设置它的属性interaction时,您会收到错误“无法设置未定义的属性”。 解决此问题的方法之一是使用.bind

query.exec(function(i, err,inters){ //i is among the params in your callback
    if(err)
        return console.log(err);
    inters.forEach(function(inter){
        pollees[i].interaction = inter; 
    });
}.bind(null, i)); //you're binding the variable 'i' to the callback

编辑:

为了使res.json(pollees);起作用(这是一个不同的问题),你应该将所有回调包装在Promise中。它应该看起来像这样:

var queries = []; //an array of promises
for (var i = 0; i < pollees.length; i++){              
    queries.push(test(pollees[i]._id)); //add a promise to the array
}
//wait for all promises to resolve
Promise.all(queries).then(function(results) {
    results.forEach(function(inter, index){
        pollees[index].interaction = inter; 
    });
    res.json(pollees); //return response
});