Srihari Mohan
Srihari Mohan

Reputation: 145

Unhandled Promise rejection of a property undefined

setInterval(function(){

    for(i=1;i<=len;i++)
    {

        plug[i].getSysInfo().then(data => {

            var json = JSON.stringify(data,undefined,2);

            var obj = JSON.parse(json);
            var _macadd = obj.mac;

            plug[i].getConsumption().then(data => {

                var json = JSON.stringify(data,undefined,2);
                var obj = JSON.parse(json);
                var _current = obj.current;
                var _voltage = obj.voltage;
                var _power = (obj.power).toPrecision(5);
                var _total = obj.total;
                var _err_code = obj.err_code;
                console.log(_power);
                //console.log(_macadd);
                //console.log(voltage);
                if(_power > 1800)
                {
                    _power = 0.00;
                }
                //  var fs = require('fs');
                //  fs.writeFile("emeter.json", json);

                var sql1 = "INSERT INTO emeter SET ? ";
                var post1  = { macaddress: _macadd,current: _current,voltage: _voltage,power: _power, total: _total,err_code: _err_code};


                var tmp = JSON.stringify(post1,undefined,2);
                console.log(tmp);
                con.query(sql1, post1, function (err, result) {
                    if (err) throw err;
                    console.log("inserted");
                });

            });
        });
    }

},30000);

While I run this, I am getting below error Unhandled promise rejection Type error: Cannot read property of 'getconsumption' of undefined.

The above code worked well when I replace the index with one value.To retrieve just one value it is working. When it is in For loop then the error message is returned. Please help me in solving this.

Upvotes: 0

Views: 339

Answers (1)

jfriend00
jfriend00

Reputation: 708116

You're trying to use a for loop index value inside an asynchronous callback. The problem is that the .then() handlers are called AFTER the for loop has already finished and thus the for loop index is at its terminal value (beyond the end of the array) when you try to use it.

There are many ways to fix this. One simple way would be to change this:

for(i=1;i<=len;i++)

to this:

for(let i=1;i<=len;i++)

Using ES6 let creates a new unique variable for each execution of the for loop so that each one maintains its own copy of the index, even for the duration of the asynchronous calls within that for loop block.


In ES5 (where you don't have let), you could change your loop to use .forEach():

plug.forEach(function(val, index) {
    // use val and index here rather than plug[i]
});

This also creates a new val and index variable for each invocation of the loop.

Upvotes: 2

Related Questions