vzhen
vzhen

Reputation: 11157

How to update several nodes in firebase using then

I want to update several nodes in firebase since data is denormalized. So when updating each node have to wait until the previous updates is success.

So I have something below (what I currently use), you can see it is not readable if getting more nodes to update.

if(foo1) {
  firebaseRef.update(data, function(error) {
    if(error){
      console.log(error);
    } else {
      firebaseRef.update(data, function(error){
        if(error){
          console.log(error);    
        }else{
          //Update Another
        };
      });
    };
  });
};

So any idea how to use .then in angularFire or pure firebase js api something like this.

firebaseRef().then(function(){
    return doSomething;
}).then(function(){
    return doSomething;
}).then(function(){
    return doSomething;
}).then(function(){
    return doSomething;
});

Upvotes: 0

Views: 211

Answers (1)

Kato
Kato

Reputation: 40582

There are no futures in Firebase or AngularFire, at present. So you would need to use a decorator/wrapper strategy.

jQuery:

function update(ref, data) {
   $.Deferred(function(def) {
      ref.update(data, function(err) {
         if( err ) def.reject(err);
         else      def.resolve();
      });
   });
}

var fb = new Firebase(URL);
update(fb.child('path1'), 'foo')
   .then(update.bind(null, fb.child('path2'), 'bar'))
   .then(update.bind(null, fb.child('path3'), 'foobar'))
   .done(function() { console.log('yay!'); });

Angular:

angular.service('update', function($q, $timeout) {
   return function(ref, data) {
      var def = $q.defer();
      ref.update(data, function(err) {
        if( err ) def.reject(err);
        else      def.resolve();
      });
      return def.promise;
   }
});

angular.controller('ctrl', function(update) {
   var fb = new Firebase(URL);
   update(fb.child('path1'), 'foo')
       .then(update.bind(null, fb.child('path2'), 'bar'))
       .then(update.bind(null, fb.child('path3'), 'foobar'))
       .done(function() { console.log('yay!'); });
});

Bind polyfill (rather handy with Futures): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility

You could also pull this off without using .bind if you like this syntax better:

function updateHandler(ref, data) {
   return function() {
      $.Deferred(function(def) {
         ref.update(data, function(err) {
            if( err ) def.reject(err);
            else      def.resolve();
         });
      });
   }
}

var fb = new Firebase(URL);
updateHandler(fb.child('path1'), 'foo')()
   .then(updateHandler(fb.child('path2'), 'bar'))
   .then(updateHandler(fb.child('path3'), 'foobar'))
   .done(function() { console.log('yay!'); });

Upvotes: 2

Related Questions