How to undo changes when an error occurs in the promise chain

In my angular app, I want to make changes to multiple locations in my firebase using a combination of transactions and set. I wrote a promise chain with a little help . Now I need to handle any errors that may occur.

In case of an error in any of the promises, I would like to roll back any changes made to firebase (successful promises) and warn the user about the error.

Current code below

$scope.addNewPost = function() {
  var refPosts = new Firebase(FBURL).child('/posts').push();
  // Get tags into array for incrementing counters
  var tags = $scope.post.tags.split(', ');
  var allPromises = [];
  // Iterate through tags and set promises for transactions to increment tag count
  angular.forEach(tags, function(value, index){
    var dfd = $q.defer();
    var refTag = new Firebase(FBURL).child('/tags/' + value);
    refTag.transaction( function (current_value) {
      return current_value + 1;
    }, function(error, committed, snapshot) {
      if (committed) {
        dfd.resolve( snapshot );
      } else {
        dfd.reject( error );
      }
    });
    allPromises.push( dfd.promise );
  });

  // Add promise for setting the post data
  var dfd = $q.defer();
  refPosts.set( $scope.post, function (error) {
    if (error) {
      dfd.reject(error);
    } else {
      dfd.resolve('post recorded');
    }
  });
  allPromises.push( dfd.promise );

  $q.all( allPromises ).then(
    function () {
      $scope.reset(); // or redirect to post
    },
    function (error) {
      // error handling goes here how would I
      // roll back any data written to firebase
      alert('Error: something went wrong your post has not been created.');
    }
  );
};

So I need to know how I can undo any changes that happen to my firebase data if one of these promises fails. Firebase can have any number of updates. (for example: 3 tags that are incremented using a transaction and post data is set)

, , ? .

--------------- ---------------

? , , , - . Then?

refPosts.set( $scope.post, function (error) {
  var forceError = true;
  if (forceError) {
    dfd.reject(forceError);
  } else {
    dfd.resolve('post recorded');
  }
  allPromises.push( dfd.promise );
});
+2
1

, :

allPromises.push( dfd.promise );
  • forEach, .
  • set(), .

, $q.all() promises. forceError, .

0

All Articles