1

I have "$scope.postits" array which I want to be persisted at every change. So, I put $scope.$watchCollection on this element to listen for changes and save data. The problem is that $watch is triggered 3 times on page load (my test array has 3 entries). How to prevent that ? What's wrong with my code ?

view:

<div ng-controller="postitController as postit" class="container animate-bottom">
    <h2>Post-it !</h2>
    <div class="btn-container">
        <button ng-click="addPostit()" id="add-new-note" class="btn btn-primary">Add postit</button>
    </div>
    <div class="post-it-container">
        <div ng-repeat="postit in postits" class="postit">
            <a ng-click="removePostit(postit)" class="delete-postit glyphicon glyphicon-remove"></a>
            <textarea ng-model="postit.content" ></textarea>
        </div>
        <div ng-if="postits.length==0" class="no-postit well lead">Keep cool and have a beer there's no postit here !</div>
    </div>  
</div>

JS controller :

app.controller('postitController', function($scope, $http, $timeout) {
    $scope.postitsLoaded = false;
    var storage = {
        endpoint: "localhost/backend/ws.php",
        get: function() {
            $http({
                method: 'GET',
                url: this.endpoint
            }).then(function successCallback(response) {
                $scope.postits = response.data;
                $scope.postitsLoaded = true;
                console.log("init done") ;
            }, function errorCallback(response) {
                console.log(response);
            });
        },
        save: function () {
            $http({
                method: 'POST',
                url: this.endpoint,
                data: "postits="+ angular.toJson($scope.postits),
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then(function successCallback(response) {
                console.log(response);
            }, function errorCallback(response) {
                console.log(response);
                alert("error");
            });
        }
    }
    $scope.$watchCollection("postits", function (newValue, oldValue) {
        if(newValue === oldValue || !$scope.postitsLoaded){
            console.log("return") ;
            return;
        }   
        console.log("watch triggered") ;
        storage.save();
    });
    $scope.addPostit = function() {
        $scope.postits.push({id:100,content:"foobar"});
        storage.save();
    };
    $scope.removePostit = function(postit) {
        $scope.postits.splice($scope.postits.indexOf(postit), 1) ; 
        storage.save();
    };
    storage.get();
});
ben.IT
  • 1,490
  • 2
  • 18
  • 37

1 Answers1

1

This is finally working with $watch and the third parameter set to true :

    $scope.$watch("postits", function (newValue, oldValue) {
    //this prevent $watch to be triggered on init 
    if(newValue === oldValue || oldValue === undefined  ){
        console.log("return") ;
        return;
    }   
    console.log("watch triggered") ;
    console.log(oldValue);
    console.log(newValue);
    storage.save();
},true);

with that solution there is not need to use any flag.

ben.IT
  • 1,490
  • 2
  • 18
  • 37