ndemoreau
ndemoreau

Reputation: 3869

meteor how to manage async updates in a loop

I have this loop:

properties.forEach(function(property) {
    console.log("property: " + property);
    var upsertValues = {};
    upsertValues["ID"] = property.ID;
    Properties.upsert(upsertValues,
        {$set: property}, 
        function(err, nbr) {
            if(err)
                console.log(err);
            else
                console.log("upsert successful" + nbr);
        });
    });
    setTimeout(function () {
        Fiber(function() {
            Meteor.call("removeOldProperties", modification_date);
        }).run();
    }, 30000)
})

Basically, it updates a bench of documents and at the end, it removes all the once who have not been updated.

I had to use a TimeOut because without that, I removes the documents before their update, as all the Meteor.upsert statements are async.

Is there a better way to do it (without having to use this timeout) ?

Thanks,

Upvotes: 0

Views: 218

Answers (1)

Matt K
Matt K

Reputation: 4948

Couple thoughts:

  • upserts are fast, no need for a callback
  • Fiber is for the server
  • I don't understand how your upsertValues was a valid query. Is this referring to the document _id? If so, convention is to keep using the name _id, if not, I'd use a more descriptive name. Was this code functioning??

What remains:

var upsertsCompleted = 0;
properties.forEach(function(property) {
  Meteor.call("upsertProperties", property, function() {
    if (++upsertsCompleted === properties.length) {
    Meteor.call("removeOldProperties", modification_date);
  }
}

Meteor.methods({
  upsertProperties: function (property) {
    return Properties.upsert(property.ID, {$set: property});
  }
});

Upvotes: 1

Related Questions