Godfried
Godfried

Reputation: 151

Loop through array Node.js

I'm currently pulling weather data from Wunderground and storing in MongoDB. I have thirty locations to gather data for but can only run 10 queries per minute so I'm trying to set a "timer" to query each zip code in the array every 10 seconds or so.

Right now my code can successfully gather the data and write it to Mongo so that's not the problem. The issue is in setting up the delay between each api call. Since I'm fairly new to javascript and even newer to asynchronous processing this is giving me some trouble. I've tried using setInterval() without much success.

MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err,db) {
var zip = ["zip1","zip2","zip3","zip4","zip5","zip6","zip7"] ;
for(var i = 0; i<zip.length; i++) {

  // Define the Wunderground method.
  var method = "/api/" + apiKey + "/conditions/q/" + zip[i] + ".json";

  // Define the HTTP post properties.
  var options = {
    host: 'api.wunderground.com',
    path: method,
    method: 'GET',
    port: 80
  };

  // Create the HTTP POST.
  var request = http.request(options, function (response) {
    var str = '';

    // Create the listener for data being returned.
    response.on('data', function (chunk) {
      str += chunk;
    });

  // Create the listener for the end of the POST.
  // Send data to MongoDB

    response.on('end', function (){
      var myObject = JSON.parse(str);

            var location = myObject.current_observation.display_location.full
            db.collection('weathercollection').save(myObject, function(err, records) {
              console.log(location);
            });       
    db.close;
    });             // close response.on
  });               // close var request
  request.end();    // Close the HTTP connection.
};                  //close for loop
});

Upvotes: 0

Views: 6104

Answers (2)

adeneo
adeneo

Reputation: 318202

I'd suggest something like :

MongoClient.connect('mongodb://127.0.0.1:27017/test', function (err, db) {
    var zips = ["zip1", "zip2", "zip3", "zip4", "zip5", "zip6", "zip7"];
    getWeather(zips, zips[0], db);
});

function getWeather(zips, zip, db) {
    var options = {
        host   : 'api.wunderground.com',
        path   : "/api/" + apiKey + "/conditions/q/" + zip + ".json",
        method : 'GET',
        port   : 80
    };

    var request = http.request(options, function (response) {
        var str = '';

        response.on('data', function (chunk) {
            str += chunk; // why get chucked data if you need it all ?
        });

        response.on('end', function () {
            var myObject = JSON.parse(str);

            var location = myObject.current_observation.display_location.full
            db.collection('weathercollection').save(myObject, function (err, records) {
                console.log(location);
            });
            db.close;
            request.end();
            var next_zip = zips.indexOf(zip) == zips.length ? 0 : zips.indexOf(zip) + 1;
            setTimeout(function () {
                getWeather(zips, next_zip, db);
            }, 10000);
        });
    });
}

Upvotes: 2

Abdullah Jibaly
Abdullah Jibaly

Reputation: 54790

One approach is to use a setTimeout instead of your for loop:

Current:

for(var i = 0; i<zip.length; i++) {
    //Make request...
}

New:

var i = 0;
(function loopFn() {
  // Make request...
  i++;
  if (i < zip.length) setTimeout(loopFn, 10000);
})();

Upvotes: 1

Related Questions