Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined

Tags:

I am following code sample like this from mongoDB js API, very simple code sample:

const getAddressFromDB = async () => {
  const MongoClient = require('mongodb').MongoClient;
  const assert = require('assert');

  let res = []
  let num = 0

  // Connection URL
  const url = 'mongodb://localhost:27017';

  // Database Name
  const dbName = 'addr';

  // Use connect method to connect to the server
  MongoClient.connect(url, function(err, client) {
    assert.equal(null, err);
    console.log("Connected correctly to db");

    const db = client.db(dbName);

    findDocuments(db, function(doc) {
      client.close();
      console.log(doc);
      //return doc
      res = doc 
      num = 1
    });
  });

  const findDocuments = function(db, callback) {
    // Get the documents collection
    const collection = db.collection('documents');
    // Find some documents
    collection.find({}).toArray(function(err, docs) {
      assert.equal(err, null);
      //console.log("Found the following records");
      //console.log(docs)
      //docs.forEach(function(element){
      //  address.push(element.address)
      //});
      //res = docs
      callback(docs);
    });
  }


  if(num == 1){
    return res
  }
}

const helper = async() => {
  let addressList = await getAddressFromDB()
  console.log(addressList)
  addressList.forEach(function(element){
    console.log(element)
    console.log("trying "+element.address)
    checkBalanceAndSendTx(element.address,element.privateKey)
  });
}

helper()

i am trying to get docs from mongoDB on localhost, then pass that array to a for each loop and do something, however, i get TypeError: Cannot read property 'forEach' of undefined, the output from command is like this:

undefined
    (node:6757) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
        at helper (/home/ubuntu/second/web3-node-tutorial/se.js:298:15)
        at process._tickCallback (internal/process/next_tick.js:68:7)
        at Function.Module.runMain (internal/modules/cjs/loader.js:721:11)
        at startup (internal/bootstrap/node.js:228:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)
    (node:6757) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
    (node:6757) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    Connected correctly to db
    [ { _id: 5b24b4e042ed9c0fed9d1f15,
        address: '0x6FD04070704vvvC35194316a9033e10120',
        privateKey: '0xc0ea45525dd0a04d6a0f8228czxc1807f6550948fde824d60167c37097c3' },
      { _id: 5b24b4e34257170ff8816e2c,
        address: '0x45bCbe21basd830831a2783d620afFF549D5Ce',
        privateKey: '0x520dbee37681a33d8c9180419c121d3c5sdfafde7ed3f750f7fc279f757c423' } ]

can someone point out why i get undefined array in getAddressFromDB()? I should be getting the array i want from db since i only return res when num is 1.

like image 694
Tom Dawn Avatar asked Jun 17 '18 08:06

Tom Dawn


People also ask

How do you fix undefined properties Cannot be read?

To solve the "Cannot read properties of undefined" error, make sure that the DOM element you are accessing exists. The error is often thrown when trying to access a property at a non-existent index after using the getElementsByClassName() method. Copied!

What does Cannot read property of undefined mean?

Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property of undefined .


1 Answers

When you await an function like you do with getAddressFromDB, that function needs to return a promise. In your code, you are returning undefined because your return statement is always executed before the callback of the database operation is done executing. Adding async does not change that.

You can fix this by defining a promise and returning it, like this (see comments in the code for further explanation):

// don't call require inside your function, it's common
// practice to do that at the beginning of your module
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

const getAddressFromDB = () => {

    // async functions need to return a promise,
    // so we create one and and wrap everything in it
    return new Promise(resolve => {
        let res = []
        let num = 0

        // Connection URL
        const url = 'mongodb://localhost:27017';

        // Database Name
        const dbName = 'addr';

        // Use connect method to connect to the server
        MongoClient.connect(url, function (err, client) {
            assert.equal(null, err);
            console.log("Connected correctly to db");

            const db = client.db(dbName);

            findDocuments(db, function (doc) {
                client.close();
                console.log(doc);

                // this makes your promise ultimately resolve
                // with the doc from MongoDB
                resolve(doc);
            });
        });

        const findDocuments = function (db, callback) {
            // Get the documents collection
            const collection = db.collection('documents');
            // Find some documents
            collection.find({}).toArray(function (err, docs) {
                assert.equal(err, null);
                callback(docs);
            });
        }
    });
}

const helper = async () => {
    let addressList = await getAddressFromDB()
    console.log(addressList)
    addressList.forEach(function (element) {
        console.log(element)
        console.log("trying " + element.address)
        checkBalanceAndSendTx(element.address, element.privateKey)
    });
}

helper()
like image 191
Patrick Hund Avatar answered Sep 28 '22 19:09

Patrick Hund