0

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

2 Answers 2

2

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);
        });
    });
}
Sign up to request clarification or add additional context in comments.

5 Comments

hmm setTimeout's 2nd parameter is milliseconds, not seconds. also consider something similar to: setTimeout(getWeather.bind(this,next_zip,db),20*1000);
I just typed a random number, assuming that the OP knew how to set the right amount of time. Also, there's no real advantage of using bind() here.
perhaps i'm nitpicking, but by using bind you have one less closure, and thus one less item in the stack; I would say the performance benefit is negligible, but the stack trace/log readability is better.
First of all thank you for the response. Secondly, I am good with parameters of setTimeout. The only issue I'm having now is it doesn't loop through the entire array of zip codes. It grabs data for the first then throws and error on var next_zip = zip.indexOf(zip)...Object 1 has no method 'indexOf'
It's var next_zip = zips.indexOf(zip)
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.