使用 MongoDB 时出现“无法读取未定义的属性‘列表’”

Posted

技术标签:

【中文标题】使用 MongoDB 时出现“无法读取未定义的属性‘列表’”【英文标题】:I get a "Cannot read property 'list' of undefined" while using MongoDB 【发布时间】:2019-02-10 12:56:45 【问题描述】:

我正在编写一个 Discord Bot,它使用 MongoDB 作为自定义命令和自定义反应的数据库。这是一个困扰我一段时间的问题。奇怪的是,这个问题有时会出现,而不是其他时候。基本上,我的代码如下:

const MongoClient = require('mongodb').MongoClient;
var db;
var cc;
var reactions;

MongoClient.connect('mongodb://<username>:<password>@ds020218.mlab.com:20218/zilla-bot-gamma',  useNewUrlParser: true , (err, client) => 
    if(err) console.log(err);
    console.log('Connected to database!');
    db = client.db('zilla-bot-gamma');

    db.collection('cc').find().toArray((err, results) => 
        if(err) console.log(err);
        cc = results[0];
    );

    db.collection('reactions').find().toArray((err, results) =>  
        if(err) console.log(err);
        reactions = results[0];
    );
);

exports.reactEmoji = function(messageContent) 
    var reactEmojicontents = [];
    var j=0;
    for(var i=0; i<reactions.list.length; i++) 
        if(messageContent.toLowerCase().indexOf(reactions.list[i].trigger) >= 0) 
            reactEmojicontents[j] = reactions.list[i].output;
            j++;
        
    

    if(reactEmojicontents[0]) 
        return reactEmojicontents;
    

    return 'None';

我的名为 reactions 的数据库集合将是:


    "_id": 
        "$oid": "hidden"
    ,
    "list": [
        
            "trigger": "jason",
            "output": "407194701515587584"
        ,
        
            "trigger": "nitro",
            "output": "476637660417359872"
        ,
        
            "trigger": "pritt",
            "output": "????"
        ,
        
            "trigger": "kappa",
            "output": "392389534064574473"
        ,
        
            "trigger": "zilla",
            "output": "392389485578420224"
        ,
        
            "trigger": "tamz",
            "output": "392363229906599948"
        ,
        
            "trigger": "hello",
            "output": "484051886677426176"
        ,
        
            "trigger": "node",
            "output": "484966646029484033"
        ,
        
            "trigger": "heroku",
            "output": "485798141791043584"
        ,
        
            "trigger": "even",
            "output": "486235385098403847"
        
    ]

运行此脚本后,我在 cmd 上收到以下消息:

Connected to database!
C:\JSFolder\ZillaBotGamma\Messages\msghandle.js:332
    for(var i=0; i<reactions.list.length; i++) 
                             ^

TypeError: Cannot read property 'list' of undefined
at exports.reactEmoji (C:\JSFolder\ZillaBotGamma\Messages\msghandle.js:332:30)
at Client.bot.on (C:\JSFolder\ZillaBotGamma\main.js:228:24)
at Client.emit (events.js:159:13)
at MessageCreateHandler.handle (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\packets\handlers\MessageCreate.js:9:34)
at WebSocketPacketManager.handle (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:103:65)
at WebSocketConnection.onPacket (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
at WebSocketConnection.onMessage (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
at WebSocket.onMessage (C:\JSFolder\ZillaBotGamma\node_modules\ws\lib\event-target.js:120:16)
at WebSocket.emit (events.js:159:13)
at Receiver._receiver.onmessage (C:\JSFolder\ZillaBotGamma\node_modules\ws\lib\websocket.js:137:47)

我觉得这很奇怪。反应列表明确定义为数据库中的数组,显示“已连接数据库!”后弹出此错误消息。然后我认为这是因为db.collection().get() 中回调的异步性质,所以我尝试将回调定义为异步并放置一个reactions = await results[0]。这并没有削减它。

谁能告诉我发生了什么事?

一些附加信息:

    我还在同一目录中使用 express 为我的机器人托管一个网站。

【问题讨论】:

附注:刚写完这个问题,我尝试再次运行我的脚本,它没有错误。这个错误似乎不时随机发生,我不知道是什么原因造成的。 How do I return the response from an asynchronous call?的可能重复 【参考方案1】:

此调用正在填充反应。

  db.collection('reactions').find().toArray((err, results) =>  
        if(err) console.log(err);
        reactions = results[0];
    );

如果由于某种原因在调用 reactEmoji 方法之前此调用失败或未完成,那么您将收到错误消息。

在尝试访问其上的属性之前,您应该确保反应设置了一个值。

if(Boolean(reactions)) 
   for(var i=0; i<reactions.list.length; i++) 
        if(messageContent.toLowerCase().indexOf(reactions.list[i].trigger) >= 0) 
            reactEmojicontents[j] = reactions.list[i].output;
            j++;
        
    
 

然后您可以填充列表并调用该方法。我会亲自创建一个名为 getReactions() 的方法,该方法返回一个承诺或在未设置反应时使用回调。

编辑:像这样的东西

  async function getReactions() 
   return new Promise(function (resolve, reject)
     db.collection('reactions').find().toArray((err, results) =>  
        if(err) reject(err.message);
        resolve(results[0]);
     );
   );
  

你可以这样称呼它。

let reactions = await getReactions();

【讨论】:

就是这样。我使用空对象模板将var reactions; 替换为var reactions = list: [];。那成功了。非常感谢! 没问题 :) 很高兴它有帮助

以上是关于使用 MongoDB 时出现“无法读取未定义的属性‘列表’”的主要内容,如果未能解决你的问题,请参考以下文章

尝试更新firestore中的数组时出现“TypeError:无法读取未定义的属性'arrayUnion'”

在项目目录中运行“npm install”时出现错误“无法读取未定义的属性'0'”

为啥在尝试安装 React 时出现“无法读取未定义的属性(读取'服务器')”?我该如何解决?

在angular2应用程序中运行ng serve时出现错误'无法读取未定义的属性'长度''

未捕获的类型错误:无法读取未定义的属性“ui”。选择croparea时出现JQuery JCrop问题

在 Node.js 应用程序中使用 Webpack 时出现类型错误“无法读取未定义的属性‘jquery’”