Ensuring that an object attribute is assigned to $watch in AngularJS to activate triggering

As a newcomer to AngularJS, I recently attempted the following code:

  
  <div ng-controller="ctrl1">
    <div ng-controller="ctrl2">
      <select ng-model="myvar" ng-options="c for c in vars" ></select>
      <div>{{myvar}}</div>
    </div> 
  </div>

  <script src="js/vendor/angular.min.js"></script>     
  <script type="text/javascript">

    var app = angular.module("myapp", [])
    .controller("ctrl1",function($scope, $rootScope) {
      $scope.myvar = 1;
      $scope.vars = [1, 2, 3];

      $scope.$watch("myvar", function(){
        console.log("ctrl1 myvar changed");
      });

    })
    .controller("ctrl2",function($scope, $rootScope) {
      $scope.$watch("myvar", function(){
        console.log("ctrl2 myvar changed");
      });
    })
    .run();

  </script>

Upon changing the select value, I noticed that the $watch in ctrl1 was not triggering. However, when I utilized an object in $scope and watched its property, it worked as expected:

  
  <div ng-controller="ctrl1">
    <div ng-controller="ctrl2">
      <select ng-model="settings.myvar" ng-options="c for c in vars" ></select>
      <div>{{settings.myvar}}</div>
    </div> 
  </div>

  <script src="js/vendor/angular.min.js"></script>     
  <script type="text/javascript">

    var app = angular.module("myapp", [])
    .controller("ctrl1",function($scope, $rootScope) {
      $scope.settings = {
        myvar : 1
      };
      $scope.vars = [1, 2, 3];

      $scope.$watch("settings.myvar", function(){
        console.log("ctrl1 myvar changed");
      });

    })
    .controller("ctrl2",function($scope, $rootScope) {
      $scope.$watch("settings.myvar", function(){
        console.log("ctrl2 myvar changed");
      });
    })
    .run();          

  </script>

I'm seeking clarification on why this difference exists. What am I missing or failing to comprehend here?

Answer №1

Essentially, the key is to utilize an object instead of a primitive in the parent scope in order to be able to update it in the child scope. This explains why your second approach works while the first one does not.

When you use a primitive, it creates a copy within the child scope, causing the watch statement in the parent controller to never trigger when a change occurs in the child controller. You can observe this behavior in this jsfiddle.

HTML

<div ng-app="myapp">
  <div ng-controller="ctrl1">
        <select ng-model="myvar" ng-options="c for c in vars" ></select>
        <div>{{myvar}}</div>
    <div ng-controller="ctrl2">
        <select ng-model="myvar" ng-options="c for c in vars" ></select>
        <div>{{myvar}}</div>
    </div> 
  </div>
</div>

Javascript

var app = angular.module("myapp", [])
.controller("ctrl1",function($scope, $rootScope) {
  $scope.myvar = 1;
  $scope.vars = [1, 2, 3];
  console.log($scope);
  $scope.$watch("myvar", function(){
    console.log($scope.myvar);
    console.log("ctrl1 myvar changed");
  });

})
.controller("ctrl2",function($scope, $rootScope) {
    console.log($scope);
    console.log($scope.myvar);
    console.log($scope);
  $scope.$watch("myvar", function(){
    console.log($scope.myvar);
    console.log($scope.$parent.myvar);
    console.log("ctrl2 myvar changed");
  });
})
.run();

Answer №2

This solution is working perfectly for me, but I may require more information from the HTML code in order to provide a thorough diagnosis.

.controller('MyCtrl2', ['$scope',function($scope) {
      $scope.myvar=1;
      $scope.vars=[1,2,3];
      $scope.$watch('myvar',function(v){
          alert(v);
      })
}]);

 <select ng-options="value for value in vars" ng-model="myvar"></select>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using the spread operator in a component's render function could potentially lead to an endless update loop

Although this issue has been addressed before in a discussion about the "You may have an infinite update loop in a component render function" warning in Vue component, the solution provided did not resolve my problem. I am seeking assistance to ...

Detecting Null Values

Recently, I encountered an issue with a Javascript function I created. Despite my efforts, I was not getting the desired result. The purpose of the function is to check various variables for null values and replace them with blank spaces when necessary. He ...

Tips for updating the Kendo grid to display fresh data once the $scope.gridOptions are updated

I am a beginner with the kendo grid. I have assigned data to the kendo grid inside a service call. There is a search field in the HTML form, where whenever I type a number and press search, the service will be called. The new data will bind to $scope.gridO ...

Saving data for editing on a Laravel page can be achieved by leveraging the powerful features

I have implemented my create page using vue.js. I called the vue.js file using a component. Now, for the edit page, I followed the same procedure by calling the vue component in the blade. However, I am unsure how to save data for the edit page. Can anyone ...

Deactivating AngularJS debug information in a gulp / typescript production compilation

What is the most effective approach to disabling debug data in a gulp production build? The recommended method for disabling debug data is: myApp.config(['$compileProvider', function ($compileProvider) { $compileProvider.debugInfoEnabled(false ...

What is the best way to pull HTML content and insert it into a div container?

Can someone help me with transferring simple HTML content into another DIV? Whenever I try, all I get is [object HTMLDivElement]. What mistake am I making here? this.inner = document.querySelector('div[data-v="1"]') this.tail = document.querySel ...

Finding out the RAM restriction of Docker for Mac through NodeJS

Understanding the Docker Limitation In our development setup, we utilize Docker for Mac to overcome the compatibility issues between Docker/Linux Containers and MacOS/Darwin/Unix. Docker for Mac employs a Linux virtual machine internally to run all contai ...

restore the HTML element to its initial position after being moved

I am utilizing document.getElementById('Droping1').style['-webkit-transform'] = translate(0px,'+Ground+'px)'; in order to relocate an HTML element. How can I return it to its original position for reusability without t ...

Start the Vue component only after ensuring that the element has been fully loaded

I have created a small vue.js component in JavaScript. Is there an elegant way to instantiate the vue component only when the element is loaded? The problem I am facing is that I'm receiving warnings in other HTML files where the element does not ex ...

Steps to creating an elliptical border using CSS

Is there a way to apply CSS styles specifically to the left border of a div to achieve an elliptical shape, while keeping other borders normal? I've managed to create a semi-ellipse with the following code, but the rest of the border remains unchanged ...

Error occurred in child process while processing the request in TypeScript: Debug Failure encountered

I encountered the following error in TypeScript while running nwb serve-react-demo: Child process failed to handle the request: Error: Debug Failure. Expression is not true. at resolveNamesWithLocalCache (D:\Projects\react-techpulse-components& ...

Unusual CSS rendering hiccup

Using jQuery, I am manipulating the display of an <a> element. Depending on certain keypress events, it adds or removes a class from an <input> element (which controls the display) that is related as a sibling to the mentioned <a>. The i ...

In Javascript, what significance does the symbol ":" hold?

While exploring the Ionic framework, I came across the following code snippet: import { AlertController } from 'ionic-angular'; export class MyPage { constructor(public alertCtrl: AlertController) { } I'm curious about the significanc ...

Building a dynamic AngularJS module on-the-fly: A step-by-step guide

I am trying to dynamically create AngularJS modules, and here is what I have so far: <section class="panel portlet-item" id="crashpanel"></section> <script type="text/javascript"> var angularApp = angular.module("Crashpanel", []); angula ...

Using JavaScript's document.write method to display HTML code, along with a variable retrieved from a Flash application

Can I ask two questions at once? Firstly, how can I achieve the following? document.write(' <div id="jwplayer"> <center> <div id='mediaplayer'></div> <script type="text/javascript"> jwplayer('mediapl ...

How can I conceal login and register router-links in the Vue + Laravel SPA project navbar immediately after a user logs in?

Currently, I am working on my Bachelor's degree project and have encountered a specific issue. While the login, register, and logout functions all seem to be working well, there is an inconsistency with the navigation bar not automatically switching b ...

Jquery(Ajax) call encountered a problem when attempting to send the object

Struggling to send data to a MongoLab DB using JS and JQueryAjax call. The issue lies in being able to see the OID in the DB but no data is actually populated. Upon checking the code and network settings, it's evident that the payload always remains e ...

ReactJS encountering an invalid dropzone element

Encountering the error "invalid dropzone element". I added var Dropzone = require('react-dropzone'); to my webpack.config.js file in hopes of activating the Dropzone element. This is what is included in my JavaScript file, copied from a Gith ...

What is the method to determine the overall size of a webpage using the Google PageSpeed API?

"analytics": { "cssResponseBytes": "333 kB", "htmlResponseBytes": "269 kB", "imageResponseBytes": "3.35 MB", "javascriptResponseBytes": "2.29 MB", "numberCssResources": 2, "numberHosts": 80, "numberJsResources": 72, "numberR ...

What steps are involved in creating a function within AngularJS?

Just starting out with AngularJS and looking to implement a shopping cart using WebSQL. Wondering how to create functions for adding items to the cart and removing them. Here's the code snippet I have so far: angular.module('ecommerce').fa ...