1

According to this: How to deep watch an array in angularjs? it should work but i dont know what i am doing wrong...

    $scope.$watch('statuses', function(newVal, oldValue) {
      if (oldValue==newVal) return false;

      console.log("st changed");
    },true);

And let's say i somehow asynchronly update the $scope.statuses for example after 3seconds

setTimeout(function() {
    $scope.statuses.push("ahhh");
},3000);

And nothing happens...any ideas why please?

Community
  • 1
  • 1
Lukas Lukac
  • 7,766
  • 10
  • 65
  • 75

3 Answers3

2

Use the following code:

setTimeout(function() {
  $scope.$apply(function () {
    $scope.statuses.push("ahhh");
  }
},3000);

You have to use $apply since AngularJS is unaware of update to $scope

As a convenience, AngularJS provides $timeout, which is like setTimeout, but automatically wraps your code in $apply by default.

Sai
  • 2,068
  • 19
  • 24
1
 $scope.statuses = [];

                $scope.$watch('statuses', function(newVal, oldValue) {
                  console.log(newVal, oldValue);
                  if (oldValue==newVal) return false;

                  console.log("st changed");
                },true);


                setTimeout(function() {
                    $scope.statuses.push("ahhh");
                    $scope.$apply();
                },3000);

$apply function serves for notification of update to $scope.

live sample http://plnkr.co/edit/LUjESyZOPfIALE2q5YYi?p=preview

if statuses will host just primitive values, better use $watchCollection

Eugene P.
  • 2,645
  • 19
  • 23
  • no primitive, it was just for ilustration but i dont understand why to use watch when i still have to use $apply... ? – Lukas Lukac Feb 22 '14 at 23:34
  • difference between $watch and $watch collection, well documented here http://www.bennadel.com/blog/2566-Scope-watch-vs-watchCollection-In-AngularJS.htm $apply you have to use each time when you produce new scope. making a function for example. as function itself creates a scope(context) – Eugene P. Feb 22 '14 at 23:36
  • missunderstanding :) My point is... i don't need to use watch if i use $apply right? The watch is there only if i need to do something when watched object changes? – Lukas Lukac Feb 22 '14 at 23:38
  • nope. $apply is just bridge for you from your timeout function(where you did some changes) to watch callback(where you catch changes). So, you have to use both. Or as guys mentioned in other answer. $timeout. is another option. ) – Eugene P. Feb 22 '14 at 23:40
  • Hmmm... but then i should write something in the watch function what will update my scope or...? Because when i do this $scope.statuses.push("ahhh"); $scope.$apply(); it will automaticly update my scope even without the watch function. – Lukas Lukac Feb 22 '14 at 23:45
  • watch equals 'track' just for simplicity. You don't need to write $apply inside $watch, cuz u're already in correct scope. I assume you will not do something like adding items to array inside $watch. as it will blow $digest function(simply saying you will get infinity cycling and error) – Eugene P. Feb 22 '14 at 23:49
  • yes but you said i need to use both $watch and $apply functions...(not one inside another...) but i have just $apply and it works... i deleted the $watch... and i am curious why that works. – Lukas Lukac Feb 22 '14 at 23:54
  • hehehe. $apply will work for any other cases. I was thinking your goal is to track changes, as mentioned in a question(that's why I told 'use both'). But As I got you now: $apply is only what are you looking for. Missunderstanding. – Eugene P. Feb 22 '14 at 23:56
  • hh :) okay so to close this up. $apply is always required... it "rebinds" the scope and watch is required only then if i need to track changes made by apply right? – Lukas Lukac Feb 22 '14 at 23:59
1

Use $timeout which is the Angular version of setTimeout. When you use $timeout, AngularJS rebinds everything after the callback.

Having to manually call $apply is always a sign that you did not do something the angular way. It's a way to tell Angular: I've done something behind your back; please refresh.

Sylvain
  • 19,099
  • 23
  • 96
  • 145