0

I am trying to have a function in Node.js with Mongoose that is a .save function for an HTTP request and I am trying to extract the geocoordinates and save them as an array in the Mongoose Schema in MongoDB. However, it seems that I am having a syncing issue because the coordinates are printed as undefined at first and I have to refresh the page to have them displayed. I thought callbacks would solve this, but they do not. (I've added the related code snippets below.) Am I doing something wrong with the callbacks or should I do something else? Thanks in advance!

ArticleProvider.prototype.save = function(articles, callback) {
for( var i =0;i< parties.length;i++ ) {
    article = articles[i];
    article._id = articleCounter++;
    article.created_at = new Date();
if (article.coords === undefined){
      geocode(article.address, function(results){
        article.coords = results;
      });
}
 callback(null, articles);
};

var geocoder = require('Geocoder');
function geocode(address, callback) {
    geocoder.geocode( address, function( err , data) {
         // console.log(data.results[0].geometry.location);
          //console.log( [data.results[0].geometry.location.lng, data.results[0].geometry.location.lat]);
          var coords = [data.results[0].geometry.location.lng, data.results[0].geometry.location.lat];
        console.log(coords);
        callback(coords);
    });
}
user2009114
  • 371
  • 1
  • 7
  • 18
  • Not sure exactly, but you have callback(null, articles); Are you sure you want to be returning articles instead of article? – thtsigma Jan 30 '13 at 03:59
  • yes, because I loop through the articles updating the coords, so I want to return them all in the end I believe – user2009114 Jan 30 '13 at 04:03

1 Answers1

1

You're calling the callback callback(null, articles); before geocode calls its callback. You need to make sure all of those finish before you call the callback. I would normally recommend an async library such as Caolan's async (look at async.forEach), but for a single case of it that might be overkill. I would suggest:

ArticleProvider.prototype.save = function(articles, callback) {
  var finishedCount = 0;
  var finishedOne = function() {
    finishedCount++;
    if(finishedCount == parties.length)
      callback(null, articles);
  };
  for( var i =0;i< parties.length;i++ ) {
    article = articles[i];
    article._id = articleCounter++;
    article.created_at = new Date();
    if (article.coords === undefined){
      geocode(article.address, function(results){
        article.coords = results;
        finishedOne();
      });
    }
    else {
      finishedOne();
    }
  }
};

I also fixed your bracket mismatch, which I assume is a copy/paste error.

Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
  • Hey thanks that almost worked, just the callback at the end doesn't need to be there because it is covered in the finishedOne = function() call. Thanks again though! – user2009114 Jan 31 '13 at 01:26