0
votes

I'm using AngularFire. I have some code which is supposed to add a new record to an array of records and using the promise then function, it is supposed to re-evaluate the array to find out which one has the most recent datestamp in the collection.

this.addRecord = function() {

    // Add a new record with the value the user has typed in
    $scope.records.$add({
        "date": (new Date()).toString(),
        "value": $scope.newValue

    }).then(function( ref ) {

        // Use underscore.last to determine which is the 
        var _newestValue = _.max( $scope.records, function(record) {
            return record.date;
        })[0].value;
        sync.$update({ 'newestValue': _newestValue });

    });

    // Have angular clear the field 
    $scope.newValue = '';
}

The problem is that when the promise.then() calls, my local copy of $scope.records is not yet updated with the newest record. So while firebase out on the server now has the new record, when I iterate on $scope.records I get all the records except for the one I just added. After the .then() completes, I can see that the record has been added.

Maybe I'm using the promise wrong? I was under the impression that when AngularFire finally calls the .then() that it would be after angular had added the new record on the server and synced up the local collection.

What's the right way to do this? I just need to reliably know when the record has been added locally. Thanks in advance!

1
You should probably use $watch for that (firebase.com/docs/web/libraries/angular/…). The example in the right-hand side of that link looks pretty relevant to your case. - Frank van Puffelen
I don't see anything wrong with your use of promises, and the code sample in the documentation seems to imply that the collection should be updated by the time then is called. Strange. - JLRishe
You're right @JLRishe, I had overlooked the use of list.$indexFor(id); in the callback in that sample. - Frank van Puffelen
Agreed that the sample does not match the current implementation (then is fired when the server reports that the write is successful, but not after the local data is updated). However, Frank's answer is still the correct one. $watch ftw. - Kato
Hey thanks for the suggestions! Using $watch turned out to be the right way to go. It seems that the promise doesn't actually tell us when the updated model has been returned to the client, only when it has successfully been written to the server. - JonathanRevell

1 Answers

0
votes

So it turns out using model.$watch was the right way to go. $watch only fires when synced changes are made to the model, so you know you can reliably count on them.

$scope.records.$watch( watchCallback );

watchCallback = function() {
    if($scope.loadingModel) return; //Block updates during load

    var _newestValue = _.max( $scope.records, function(record) {
        return record.date;
    })[0].value;
    sync.$update({ 'newestValue': _newestValue });
}

AngularFire's model.$add().then() will fire when the changes were sent to the server, not when the local model is synced up to the client. So $add.then would be more appropriately used to confirm that changes were saved, or something along those lines.