What is causing the change in the watcher's source?

How can the source of a change to a watched property be detected in AngularJS?

For instance, suppose I have the global value:

let watchMe = 0;

and it is being watched in a component as follows:

$scope.$watch(() => {
  return watchMe;
}, (newValue, oldValue) => {
  if(newValue !== oldValue) {
    console.log(`watchMe changed to ${newValue}, but who made the change??`);
  }
});

Answer №1

It simply can't be done.

One method to identify it is by utilizing functions that assign the value. By tracking where this particular function was invoked, you can pinpoint which section of your code triggered the function.

Answer №2

When working with Angular's $watch callback, the method signature is defined as function(newVal, oldVal, scope). This limited information makes it difficult to pinpoint what specifically caused a value change within the $watch callback.

One alternative approach is to use $broadcast and $on to manage value changes if the watchMe value is only altered in a few locations. By utilizing $broadcast, you can pass additional data along with the event to help identify the source of the change.

The benefit of using $broadcast is its ability to carry arbitrary data alongside the event. This data, combined with the event itself, can aid in identifying the reason for the modification.

angular.module('myApp', [])
  .controller('BugController', ['$scope', '$rootScope', '$interval', BugController]);

function BugController($scope, $rootScope, $interval) {
  $scope.bugCount = 5;
  $scope.message = "Let's fix those bugs!";

  $scope.changeBug = function(change, person) {
    var oldValue = $scope.bugCount;
    var newValue = $scope.bugCount = Math.max(0, $scope.bugCount + change);

    if (oldValue !== newValue) {
      //$broadcast an event.
      //parameters indicate the change in value and who changed it.
      $rootScope.$broadcast('bugs-changed', newValue, oldValue, person);
    }

  };

  //Listen for bugs-changed events
  //Use the included parameters to identify who caused the value to change.
  $scope.$on('bugs-changed', function(event, newValue, oldValue, person) {
    $scope.message = person +
      ' changed bugCount from ' +
      oldValue + ' to ' + newValue + '.';
      
    if (newValue > oldValue) {
      $scope.message += ' Dang it, ' + person + '!';
    }
    else {
      $scope.message += ' Good job, ' + person + '!';
    }
  });
  
  //And random bugs pop up over time
  $interval(function() {
    $rootScope.$broadcast('bugs-changed', $scope.bugCount + 1, $scope.bugCount++, 'Time')
  }, 5000);

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">

  <div ng-controller="BugController">
    <div>Bugs: {{bugCount}}</div>
    <p>{{message}}</p>
    <p>
      Alex
      <button ng-click="changeBug(1, 'Alex')">Add bug</button>
      <button ng-click="changeBug(-1, 'Alex')">Fix bug</button>
    </p>

    <p>
      David
      <button ng-click="changeBug(1, 'David')">Add bug</button>
      <button ng-click="changeBug(2, 'David')">Fix bug</button>
    </p>

  </div>

</div>

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

Firefox does not support jQuery AJAX functionality, unlike Internet Explorer where it works smoothly

Can anyone help me figure out how to ensure that this code works smoothly on both IE and Firefox? The confirm prompts are functioning in Firefox, but the AJAX request isn't triggering. According to Firebug, there's an error at line 9631 of jquery ...

Transferring a Query between Domains with the Help of JavaScript

It is necessary to develop a function that generates a query based on the user's input of "Test" in an INPUT on Site A (SiteA.com) and then redirects to Site B within the same window, passing along the query (SiteB.com/search.aspx?k=test). Code snipp ...

Optimize your website by reducing the size of CSS, JavaScript, and HTML files through NUXT's

I'm currently working on a project in NUXT utilizing yarn for managing packages. My objective is to compress (and potentially merge) js, css, and html files to enhance load time efficiency. I came across "https://www.npmjs.com/package/nuxt-compress" ...

The navigation controller, responsible for updating navbar values, is only executed once

My goal is to construct a simple Angular application and familiarize myself with the basics. To start, I'm utilizing Yeoman's angular-generator for scaffolding. This generator comes with a predetermined .config featuring $routeProvider, which I ...

"Combining the power of Laravel 5.1 with the versatility of Angular 2

I am working with Laravel 5.1 and Angular JS 2.1, but I am facing an issue where my view is not recognizing angular directives. Despite exploring various solutions on stackoverflow, I have been unable to find a resolution. Can anyone offer any suggestions ...

Having trouble getting the JavaScript slider to animate

My code works perfectly in Codepen but when I try to implement it on my website, it shows as a static image. You can view the code here: https://codepen.io/anon/pen/zPMKpv I'm using the exact same code on my website located at: Does anyone have any ...

Question about jQuery's XHR

Currently working on a basic jQuery script to parse JSON data and format it. However, I keep encountering an error in Chrome that says: Resource interpreted as Script but transferred with MIME type text/html. After researching on SO, it seems to be a comm ...

Attempt to make a Restangular request again using an interceptor

Within the official restangular documentation, a code sample is provided to retry a request in the ErrorInterceptor. The code snippet can be found here: var refreshToken = function() { var deferred = $q.defer(); // Logic to refresh access token ...

Running multiple server and client codes on node.js simultaneously

I'm exploring the idea of establishing a network of nodes on my computer that have dual functionality as both clients and servers. Each node should be able to execute its unique server code and client code, allowing it to send requests to its individu ...

There was an error in the code: Unexpected token M

Is there a solution for this error that anyone can share? The Google Developer Tools are not able to identify the exact location of the problematic code, making troubleshooting difficult. I am using Meteor and MongoDB. I have looked into Unexpected toke ...

Determining the Maximum Number of Characters Allowed in a Div Using jQuery

Could anyone provide guidance on how to populate a div with single characters? I want the div to span the width of the viewport. The code to get the width is: $(window).width(); I would like JavaScript to generate HTML similar to this: <div id="text ...

AngularJS 2: Updating variable in parent component using Router

My current app.component looks like the following: import { Component, Input } from '@angular/core'; import {AuthTokenService} from './auth-token.service'; @Component({ selector: 'app-root', templateUrl: './app ...

Using Sass variables becomes ineffective when they are passed through props

Trying to create a reusable component in Vue.js using Sass variables as props: ButtonFilled(:title="'Next'" :backgroundColor="'$green'") However, when trying to obtain the variable from props as shown below, it does ...

Video background mute feature malfunctioning

I've searched through numerous resources and reviewed various solutions for this issue, yet I still haven't been able to figure it out. Could someone please guide me on how to mute my youtube embedded video? P.s. I am a beginner when it comes to ...

When encountering duplicates within an array, I must ensure that the complete structure of the array is preserved and stored in MongoDB

I have encountered a situation where I am looping through an array and need to save the data in a MongoDB database. However, I need to avoid duplicating the array's indexes. I was thinking of using a filter to achieve this, but I'm concerned abou ...

Tips for editing events in the "react-big-calendars" component

I am looking to implement a feature where users can click on events in a calendar and then edit either the dates or event titles. Can this functionality be achieved using "react-big-calendar"? If not, are there any other packages you can recommend? <Cal ...

NextJS Router delays data reloading until page receives focus

Struggling with creating an indexing page in NextJS. Attempting to retrieve the page number using the router: let router = useRouter() let page = isNaN(router.query.page) ? 1 : parseInt(router.query.page); This code is part of a React Query function withi ...

Accessing the properties of a module in Javascript - a foolproof guide to making the most

In the constants.js file, I have defined the following code: var constants = ( conversationUsername: "user1", conversationPassword: "pass1", conversationVersionDate: "date1", conversationWorkspaceId: "work1" }; module.exports.constants ...

The curious conduct of wild safari creatures

I have been using JavaScript to split my ePub chapter into pages by wrapping the code with new divs that represent separate pages. I have also created CSS styles for these new divs. Everything works perfectly when the file has a filename extension of &apos ...

Alert: The job "karma" does not exist in the grunt test execution

http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower After reading through an intriguing guide on Angular, Yeoman, Bower, and Grunt, I successfully initiated an Angular application. Most aspects are functioning well, ...