Angular's watch feature fails to trigger when the value is modified

My setup includes two sliders, one for brightness and the other for contrast. They are linked to a "brightness" model and a "contrast" model. These sliders are located within a tab interface, and I noticed that every time the tab was changed, the values were being reset. To address this issue, I decided to implement a factory service to store the values and ensure that the factory gets updated with the new value whenever the sliders are adjusted. I can confirm that the slider models are being updated because there is a box next to each slider displaying the current value of the model. However, after the value is set by the service, the console seems to log only once and not thereafter.
Controller Code:

'use strict';

angular.module('oct').controller('LeftCtrl', ['$scope', '$timeout', '$mdSidenav', '$log', 'OctSettings', function($scope, $timeout, $mdSidenav, $log, OctSettings) {
    $scope.resolutions = ['Resolution 1', 'Resolution 2', 'Resolution 3'];
    $scope.toggleDropdownArray = ['', '', '', ''];
    $scope.isThetaView = true;
    $scope.isCartView = true;
    $scope.isLongView = true;

    $scope.brightness = Number(OctSettings.image.brightness);
    $scope.contrast = Number(OctSettings.image.contrast);

    $scope.$watch('brightness',
        function(newVal, oldVal) {
            console.log(oldVal);
        });

    $scope.close = function() {
        $mdSidenav('left').close()
            .then(function() {
                $log.debug('close LEFT is done');
            });
    };

    $scope.toggleDropdown = function(index) {
        if($scope.toggleDropdownArray[index] === 'toggle-up') {
            $scope.toggleDropdownArray[index] = 'toggle-down';
        } else {
            $scope.toggleDropdownArray[index] = 'toggle-up';
            for(var i=0; i<$scope.toggleDropdownArray.length; i++) {
                if(i !== index) {
                    $scope.toggleDropdownArray[i] = 'toggle-down';
                }
            }
        }
    };
}]);

HTML incorporating Angular Material for Slider Display:

<md-tab label="Image">
    <md-content class="md-padding settings-tabs-pg-content">
        <div class="brightness-div" layout="">
            <div flex="10" layout="" layout-align="center center"><span class="md-body-1 fa fa-sun-o"><md-tooltip>Brightness</md-tooltip></span></div>
            <md-slider flex="" min="0" max="100" ng-model="brightness" aria-label="brightness" id="brightness-slider" class="">
            </md-slider>
            <div flex="20" layout="" layout-align="center center">
                <input type="number" ng-model="brightness" aria-label="brightness" aria-controls="brightness-slider">
            </div>
        </div>
        <div layout="">
            <div flex="10" layout="" layout-align="center center">
                <span class="md-body-1 fa fa-adjust"><md-tooltip>Contrast</md-tooltip></span>
            </div>
            <md-slider flex="" min="0" max="100" ng-model="contrast" aria-label="contrast" id="contrast-slider" class="">
            </md-slider>
            <div flex="20" layout="" layout-align="center center">
                <input type="number" ng-model="contrast" aria-label="contrast" aria-controls="contrast-slider">
            </div>
        </div>
        <div>
            <a class="window-leveling-btn">Window Leveling</a>
        </div>
    </md-content>
</md-tab>

Answer №1

It's unclear why your $watch function isn't working as expected. Consider a different approach to solving your issue.

Instead of initializing the value of $scope.brightness from your service and then replacing it with the slider input, try initializing $scope.image from the service and updating values on that object. This way, you can directly update the service value through the binding in your HTML.

For examples of both methods, take a look at this codepen: http://codepen.io/troylelandshields/pen/YXeLqG

Keep in mind that the $scope.$watch in the second example is just for demonstration purposes and not necessary to update the service.

angular.module('app', [])
.factory('fact', function(){
      return {
        image:{
          brightness:5
        }
      }
    })
.controller('ctrl', function($scope, fact){
  $scope.num = fact.image.brightness;

  $scope.image = fact.image;

  $scope.$watch('num', function(newVal, oldVal){
    $scope.msg = "Scope value: " + newVal + " , serviceVal: " + fact.image.brightness;
  })

  $scope.$watch('image.brightness', function(newVal, oldVal){
    $scope.msg = "Scope value: " + newVal + " , serviceVal: " + fact.image.brightness;
  })

})

Answer №2

After making some adjustments, I managed to successfully resolve the issue by updating the ng-models to image.brightness and image.contrast. The process is detailed in a helpful $watch not firing on data change. Although I was familiar with this problem, I mistakenly believed that because I was monitoring a number rather than an object, I did not need to make these changes. Despite not fully grasping the reasoning behind it, the solution is now functioning as intended.

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

Despite implementing an event listener, the Google Maps API is failing to resize properly when created using AJAX

Currently, I am facing an issue with the Google Maps API as the map generated is not resizing to fit the div. Instead, it shows a large grey area which is quite frustrating for me. Can someone please assist me in resolving this problem? Below is the code ...

What is the correct method to remove an item from local storage?

Using localStorage, I have stored multiple objects in an array. Is there a way to remove just one object from this array? If I use localstorage.removeItem(keysofthelocalstorage), I can delete the entire array, but I specifically want to remove only certai ...

Is it possible to retrieve the createdAt timestamp without displaying the 'GMT+0000 (Coordinated Universal Time)'?

After conducting an extensive search, I have yet to find a satisfactory answer. My goal is to configure it without including the CUT time. {name: "Registered:", value: `${user.createdAt}`}, {name: "Joined:", value: `${message.guild.joinedAt}`} Presently, ...

Console command to change paragraph tag color---Modifying the color

I am attempting to change the color of all paragraph tags on a webpage to white by utilizing the console. My initial attempt was: document.p.style.color = 'white'; However, this method did not have the desired effect. Interestingly, I have had s ...

Using TypeScript to call Node.js functions instead of the standard way

Can someone assist me with the issue I'm facing? I have developed a default node.js app with express using Visual Studio nodejs tools, and now I am attempting to call the setTimeout function that is declared in node.d.ts. The code snippet in question ...

Is there someone who can assist me in transferring data from an Axios JSON response to plot points on a line chart using Chart js?

I'm currently in the process of developing a React application that includes a line chart showcasing the timeline of data recordings starting from a specific point in time up to the present day. To achieve this, I am leveraging the Chart.js JavaScript ...

Property-based Angular Material row grouping in a mat-table is a powerful feature that enhances

Is there a way to organize the data in one row with the same ID? Currently, my data looks like this: Data Set: { "id": "700", "desc": "Tempo", "richiesta": "20220087", "dataElab": &quo ...

What is the best way to select the child of the second-to-last child?

In the structure of my HTML code, I have an unordered list with a class "menu" containing several list items and corresponding anchor tags like this <ul class="menu"> <li> <a href="#1"></a> </li> <div&g ...

Changing the color of a Navlink when focused

Can anyone help me modify the background color of a dropdown nav-link in Bootstrap? I am currently using the latest version and want to change it from blue to red when focused or clicked. I have included my navbar code below along with additional CSS, but ...

TemplateUrl not rendering in Component's code

I am currently in the process of learning Angular 2. I attempted to create a component called "Header" consisting of two files named "Header.component.ts" and "Header.component.html". In addition, I made configurations in the app.module.ts file as shown be ...

Understanding the implementation of public and private methods in mixins in Vue2

While I've come across documentation on the following implementation, I find myself struggling to visualize how it can be executed. // A more advanced alternative! var myGreatMixin = { // ... methods: { publicMethod() { // ... myPr ...

Modal windows allow for passing variables through the use of resolve binding

I am currently working with the following directive: angular.module('ui.bootstrap.demo').directive('warningDirective',function() { return { restrict: 'EA', scope: { showwarning: '=', warningmes ...

What is the best way to include a new user in my list of friends within the User schema?

Working on my customized social media platform, I have implemented a feature where users can send friend requests by clicking on a button. <form action="/requests" method="POST"> <input type="hidden" name="send ...

Deactivate the Autofill feature on Google Toolbar

Dealing with the Google Toolbar's autofill feature has been a constant frustration in my web development journey over the years. I have resorted to creating a timer control to monitor changes, as the developers overlooked firing change events on contr ...

Interactive Icon Feature Instead of Annoying Pop-Ups in JavaScript

Hello there! I need assistance fixing a code issue. Currently, the code automatically pops up when the page is opened. Is there a way to make it clickable instead of popping up automatically? <script type="text/javascript" src="//www.klaviyo.com/media/ ...

Is it necessary to run npm install when a package does not have any dependencies?

If I have an npm package that contains all its dependencies bundled into one file using webpack, and I unpack it into the directory ./my-awesome-package/, should I still run npm install ./my-awesome-package/? I am aware of being able to specify preinstall ...

Can you provide tips on using Ajax to store a cache file?

I've created a javascript/ajax function that retrieves a json file from an external server. The functionality I'm trying to implement includes: Fetching the json file from the external server Saving the json file on the local server Checking if ...

Securing Angular 2+: Safeguarding Server-Side Lazy Loaded Modules

In my Angular 2+ application, users input personal data that is then analyzed in a different section of the app restricted to authorized personnel. The challenge lies in preventing unauthorized individuals from gaining insight into the analysis process. We ...

Permuting sentences to create intricate anagrams

I am faced with a task of creating the correct phrase for a sentence anagram using an array of nearly 2700 strings. The list consists of almost 100k words that could potentially fit. My goal is to combine these words in groups of 1, 2, and 3 words togethe ...

Jquery Plugin for Click Selection Activation

After receiving no response to my previous inquiry, I decided to proceed with this particular plugin setup. (function ( $ ) { $.fn.myPlugin = function (options) { options = $.extend( {}, $.fn.myPlugin.defaults, options ); return this.each(function (i ...