0

I am working on functionality to fetch data for symbols present in an array. Please have a look at my code below.

I am iterating through the array using a for loop, but all the calculation in my code is happening only for the last element of the arra (please check comments in code). I am not 100% sure about the reason for this issue, but I believe it is because of the asynchronous processing of Node.js.

    var symbol = ['symbol1', 'symbol2','symbol3'];
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth() + 1;
    var yyyy = today.getFullYear();
    if (dd < 10) {
        dd = '0' + dd
    }
    if (mm < 10) {
        mm = '0' + mm
    }
    var today1 = yyyy + '-' + mm + '-' + dd;

    //for loop start
    for (sname in symbol) {
        sname = symbol[sname].substring(4);
        sname1 = sname.replace("%26", '&');
        History.find({ "symbol": sname1 }, function(err, stock) {
            if (err) {
                next();
            }
            if (stock != '') {
                var objStr = stock[0].values.sort(custom_sort).reverse();
                objStr = JSON.stringify(objStr[0]);
                var jsonObj = JSON.parse(objStr);
                var date = new Date(jsonObj.Date);
                var fromDate = date.date("YYYY-MM-DD");
                console.log(sname + ' and ' + sname1); //It should print symbol1,symbol2.

                // But I am getting symbol3 all the time.
                console.log(fromDate);
                console.log(today1);
                yahooFinance.historical({
                    symbol: sname + '.NS',
                    from: fromDate,
                    to: today1
                }, function(err, quotes) {
                    if (err) {
                        console.log("Error in fetching data");
                    }
                    if (quotes == '') {
                            console.log("No latest records found to insert");
                    }
                    for (var objCounter in quotes) {
                        var insertObj = {
                            'Date': quotes[objCounter].date.date("YYYY-MM-DD"),
                            'Open': quotes[objCounter].open,
                            'Close': quotes[objCounter].close,
                            'High': quotes[objCounter].high,
                            'Low': quotes[objCounter].low,
                            'AdjClose': quotes[objCounter].adjClose,
                            'Volume': quotes[objCounter].volume
                        };
                        History.findOneAndUpdate({ symbol: sname1 }, { $push: { values: insertObj } }, { safe: true, upsert: true },
                            function(err, model) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    console.log("Record inserted for " + sname1)
                                }
                            }
                        );
                    }
                });
            }
            else {
                console.log("Not Found");
            }
        });
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jitesh
  • 395
  • 2
  • 5
  • 18

1 Answers1

0

You can use bind to solve your problem

Just bind the callback method inside History.find() with your variables you want to access. After binding you can access your variables using this keyword

Below is the sample code.

var symbol = ['symbol1', 'symbol2', 'symbol3']
var today = new Date()
var dd = today.getDate()
var mm = today.getMonth() + 1
var yyyy = today.getFullYear()
if (dd < 10) {
  dd = '0' + dd
}
if (mm < 10) {
  mm = '0' + mm
}
var today1 = yyyy + '-' + mm + '-' + dd
// for loop start
for (sname in symbol) {
  sname = symbol[sname].substring(4)
  sname1 = sname.replace('%26', '&')
  History.find({ 'symbol': sname1 }, function (err, stock) {

    //access your sname and sname1
    var sname = this[0] 
    var sname1 = this[1]
    if (err) {
      next()
    }
    //your code....

  }.bind([sname,sname1])) //bind whatever variables you want to bind in this keyword with the callback function.
}
Ayush Nawani
  • 654
  • 6
  • 16