Я получаю «Не могу прочитать список свойств неопределенных» при использовании MongoDB - PullRequest
0 голосов
/ 05 сентября 2018

Я пишу 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)

Я нахожу это очень странным. Reaction.list четко определен как массив в базе данных, и это сообщение об ошибке появляется после сообщения «Подключено к базе данных!». Затем я решил, что это произойдет из-за асинхронной природы обратных вызовов в db.collection().get(), поэтому я попытался определить обратный вызов как асинхронный и поставить reactions = await results[0]. Это не сократило это.

Может кто-нибудь сказать мне, что происходит?

Дополнительная информация:

  1. У меня также есть сайт для моего бота, использующий экспресс в том же каталоге.

1 Ответ

0 голосов
/ 05 сентября 2018

Реакции заполняются этим призывом.

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

Если по какой-либо причине этот вызов завершится неудачно или не завершится до того, как будет вызван ваш реагирующий метод, вы получите ошибку.

Прежде чем пытаться получить доступ к свойству, убедитесь, что для реакций установлено значение.

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();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...