0

There is 1 angular app, with 1 parent controller, and a child controller. In the child, there is 1 $watch WATCH-CHILD for OBJ-CHILD, which triggers an $emit. In the parent, there is a listener for the $emit, we'll call it ON-LISTENER, and a $watch WATCH-PARENT for OBJ-PARENT (which uses true as the 3rd argument).

When the child's OBJ-CHILD is changed, it triggers WATCH-CHILD, which triggers the $emit. The parent listener ON-LISTENER is fired, and changes OBJ-PARENT. It also sets some $location properties. The $watch WATCH-PARENT for OBJ-PARENT is never fired (even though the value has changed), as well as the properties set on $location not changed in the browser URL (I know they are indeed changed inside the JavaScript, cause I print them).

In order to make sure that ON-LISTENER is called within a $digest, I tried to call $digest at the end of ON-LISTENER, and got the expected exception.

Any idea if I'm doing something wrong? I expect the changes that occur in ON-LISTENER to trigger WATCH-PARENT and browser URL change.

I will try to reproduce on jsfiddle and edit this post if successful.

The code looks like:

CHILD:

$scope.$watch('vars.model', function(newValue, oldValue) {
  console.log('model changed');
  $scope.$emit('highlightChange', newValue);
}, true);

PARENT:

$scope.$watch('vars.model.highlight', function(newValue, oldValue) {
  console.log('highlight changed');
}, true);

$scope.$on('highlightChange', function(event, value) {
  console.log('listener', $scope.vars.model.highlight.categoryId, value.categoryId);
  $location.search('category-id', value.categoryId);
  $scope.vars.model.highlight.categoryId = value.categoryId;
}
yinonby
  • 83
  • 1
  • 9

2 Answers2

1

Next time please provide more code which works, that way you can get better answers.

Here is a Demo plunker which I created to test the code which you provided. It works just fine. If you could provide more code then we could find the real reason why it did not work.

I created two controllers parentCtrl and childCtrl which uses your code and object of provided structure.

$scope.vars = {
   model:{
      highlight:{
        categoryId : 5 //This value is set for testing purposes
      }
   }
};

Also, I changed watch target (vars.model -> vars.model.highlight) to be the same as in parent controller

$scope.$watch('vars.model.highlight', function(newValue, oldValue) {
  console.log('child model changed (new/old)', newValue, oldValue);
  $scope.$emit('highlightChange', newValue);
  console.log('Emited change event');
}, true);
Imants Volkovs
  • 838
  • 11
  • 20
0

Thanks for the help. I found out that my event originated from a manual call to $scope.$digest() due to the originating event being triggered from a daterangepicker 'apply.daterangepicker' event. When I changed that to $scope.$apply, the problem seemed to go away. I can assume from that, that $apply() is the one in charge of keep calling $watch as long as there are changes, and that $digest() doesn't do so.

For future reference, I placed the problem here: https://plnkr.co/edit/ItkALhw16Aqukk3EFrRz?p=preview

$scope.digest();

should become

$scope.apply();
yinonby
  • 83
  • 1
  • 9