0

I'm using Angular, Firebase and 3-way data bindings.

I'm also using filter, so the items active (state 1) are listed on the top, items paused (state 2) are listed on the bottom. Of course this is just an example use of filtering:

<todo ng-repeat="item in todos | orderByPriority | filter: {state: 1}"></todo>

It seems to have strange consequences when using 3-way bindings with Angular and Firebase.

1. When new item is added to collection, all other items on temporarily disappear. Why?

  • http://plnkr.co/edit/aamS7aX5Oun4hCuoDqf5?p=preview
  • http://youtu.be/YauwP5Qw4vA
  • Essential bits of code below:

    $scope.firebaseURL = "https://flickering-date.firebaseio-demo.com/";
    $scope.todos = [
        {name: 'post to stack overflow', state: 1, dateAdded : new Date(2013,1,1)}, 
        {name: 'plunker', state: 2, dateAdded : new Date(2013,2,2)},
        {name: 'github', state: 3, dateAdded : new Date(2013,3,3)},
        {name: 'mailing list', state: 1, dateAdded : new Date(2013,4,4)}
    ];
    $scope.state = 1;
    
    $scope.$firRef = $firebase(new Firebase($scope.firebaseURL + "todos/"));
    $scope.$firRef.$bind($scope, "todos").then(function(unbind) {
      $scope.unbindFunctionUnused = unbind;
    });
    

Linking function in directive:

            var intervalId = $interval(function() {
                var squared = scope.item.counter * scope.item.counter;
                element.find(".squared").html(squared);
                scope.item.counter++;
            }, 1000);

Initially I was thinking it has something to do with Date object but similar strange behaviour occurs for integers too. (see below)

2. Populating square of a number work OK for local array. For array synced with Firebase no value is displayed (it flickers occassionally).

  • http://plnkr.co/edit/UGlk3Yhohs4GHyvHU7BO?p=preview
  • http://youtu.be/6iLOYc14XRY
  • Essential code below

    $scope.firebaseURL = "https://flickering-counter.firebaseio-demo.com/";
    $scope.todosFirebase = [
        {name: 'plunker firebase', counter : 11, state: 1 },
        {name: 'github firebase', counter: 22, state: 2},
        {name: 'stack overflow firebase', counter: 33, state: 3}
    ];
    $scope.todos = [
        {name: 'plunker', counter : 11, state: 1 },
        {name: 'github', counter: 22, state: 2},
        {name: 'stack overflow', counter: 33, state: 3}
    ];
    $scope.state = 1;
    
    $scope.$firRef = $firebase(new Firebase($scope.firebaseURL + "todos/"));
    $scope.$firRef.$bind($scope, "todosFirebase").then(function(unbind) {
      $scope.unbindFunctionUnused = unbind;
    });
    
    $scope.addItem = function() { // note that we add to both instances
        $scope.todosFirebase.$add({name: $scope.newItem, state: $scope.state, counter: 0});
        $scope.todos.push({name: $scope.newItem, state: $scope.state, counter: 0});
    }
    

    Linking function in directive:

            var intervalId = $interval(function() {
    
                var added = new Date(scope.item.dateAdded).getTime();
                var now = new Date().getTime();
                var diff = new Date(now - added);
    
                element.find(".timeelapsed").html(diff.toString());
            }, 1000);
    

Yesterday I asked related question - How to correctly disassociate $firebase AngularJS binding? - it also touches Firebase, Angular and 3-way data binding. Today I wanted to investigate further but I'm kind of stuck...

What I want to do:

  • I add an item to the list
  • It has a counter
  • It refreshes every 1 sec
  • It just works

(for some reason I cannot make it work in my setup)

Community
  • 1
  • 1
Mars Robertson
  • 12,673
  • 11
  • 68
  • 89

1 Answers1

1

enter image description here

I actually wanted to downvote myself for this question :]

The solution is embarrassingly simple:

var _updateFunction = function() {
    var squared = scope.item.counter * scope.item.counter;
    element.find(".squared").html(squared); 
    scope.item.counter++;
}

var intervalId = $interval(_updateFunction, 1000);

_updateFunction(); // <-- cpt Obvious

Related: Execute the setInterval function without delay the first time

Community
  • 1
  • 1
Mars Robertson
  • 12,673
  • 11
  • 68
  • 89