Experiencing difficulties with $watch in my Angular controller

Having trouble getting a $watch function to work properly while testing a controller.

In this scenario, the goal is to display ctrl.value in either ARI format or AEP format, but the underlying $scope.model is always kept in the ARI format. When ctrl.value changes, $scope.model should then be updated accordingly, either with the same value or converted to ARI format before setting it. However, despite my efforts, the $watch function doesn't seem to trigger when ctrl.value changes.

The relevant section of the controller code looks like this. (I've utilized functions within the watch for spying purposes during testing):

.controller('EventLikelihoodController', function($scope) {

    var ctrl = this;
    ctrl.value = $scope.model;
    ctrl.renderingARI = true;

    ctrl.getValue = function() {
        return ctrl.value;
    };
    ctrl.updateModel = function(newValue) {
        if (ctrl.renderingARI) {
            $scope.model = newValue;
        } else {
            $scope.model = ctrl.convertAepToAri(newValue);
        }
    };
    $scope.$watch(ctrl.getValue, ctrl.updateModel);

});

Below is my Jasmine test script:

it('correctly sets the model value', function () {

    spyOn(controller, 'updateModel').andCallThrough();
    spyOn(controller, 'getValue').andCallThrough();

    controller.value = 2;
    scope.$digest();

    expect(controller.getValue).toHaveBeenCalled();
    expect(controller.updateModel).toHaveBeenCalledWith(2);
    expect(scope.model).toBe(2);

    controller.switchRendering();
    scope.$digest();

    expect(controller.updateModel).toHaveBeenCalledWith(4);
    expect(scope.model).toBe(4);

});

The test fails as it expected all spy functions to have been called, which they weren't.

The switchRendering function switches between ARI rendering and AEP rendering. There are other tests confirming that it works correctly (i.e., ctrl.value changes).

I'm uncertain whether the issue lies with the watch statement itself or if it's related to running it within the test environment (I haven't written enough code yet to verify if the controller functions correctly outside of testing...)

Answer №1

It seems like there may be an issue with the watch statement in your code. The this inside the function might not be referring to your controller's this. To fix this, let's manually bind it:

   $scope.$watch(angular.bind(this,ctrl.getValue), ctrl.updateModel);

Also, make sure that in the updateModel() we are updating $scope.model and listening for changes in the value. If this.value needs to be updated in the updateModel(), ensure that it is done correctly. (This applies only if this method is supposed to change the value of ctrl.value)

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

Pairing AngularJS Material with the Ionic framework

Looking to develop an app with Ionic AngularJS material components? Or perhaps using the Material Framework Design Lite for your design? ...

Encountering a CORS error in my Next.js 13.4 application while attempting to retrieve JSON data

Here is the location of the actual fetch request in our search/page. import { useSearchParams } from "next/navigation"; import Footer from "../components/Footers"; import Header from "../components/header"; import { format } ...

Iterate over JSON dates in JavaScript

Trying to utilize JavaScript in looping through a JSON file containing time periods (start date/time and end date/time) to determine if the current date/time falls within any of these periods. The provided code doesn't seem to be working as expected. ...

Smooth Div Scroll experiencing display issues

Trying to integrate the smooth div scroll, specifically the "Clickable Logo Parade" found at: Successfully implemented it on a blank page exactly as desired, but encountering issues when inserting it into the current layout. Could something be causing int ...

Get an MP4 on your iPhone (iOS) by downloading it from a link on a webpage

Despite trying various methods such as the HTML5 download tag, JavaScript, JQuery, and other techniques, I have not been able to successfully download a file to the Album. While photos can be saved by long clicking and selecting "Save Image", videos do n ...

Which architectural style is best to master for developing exceptional JavaScript software?

My familiarity with Model-View-Controller runs deep, having worked with it for years in server-side development using languages like PHP. Now, I find myself diving into JavaScript and embarking on a large project that utilizes SVG, Canvas, and other moder ...

Highlight main title in jQuery table of contents

I have successfully created an automatic Table of Contents, but now I need to make the top heading appear in bold font. jQuery(document).ready(function(){ var ToC = "<nav role='navigation' class='table-of-contents vNav'>" + ...

Angular.js: Applying a style to elements beyond the current scope based on the selected route

I'm looking to dynamically add classes outside of the current scope. Specifically, I need to add classes to the header, main, and footer elements as shown below: <header class="{{pageClass}}"></header> <main class="{{pageClass}}" ng-vi ...

Creating an environment variable using the package.json script

I'm trying to set the process.env.ENV variable as either TEST or null using a script in my package.json file. The command below is not working when I run it through package.json (though it works fine when directly executed in cmd). script { "star ...

Encountering an error while including ngmin in the r.js build file

Currently, I am attempting to utilize ngmin with requirejs's r.js as outlined in a guide found here. Unfortunately, I have encountered issues and cannot seem to make it work. Despite installing both ngmin and requirejs globally and locally using npm, ...

Having difficulty locating audio files within a Next.js project

I am facing challenges when trying to import my audio files into a redux slice. Currently, I am attempting to retrieve my audio files from the app > public > audio directory. I have made efforts to access my audio files through 2 different director ...

Guide on using JSZip and VUE to handle an array of promises and store them in a local variable

My lack of experience with async functions has me feeling a bit lost right now... I'm attempting to loop through files in a folder within a zip file using JSZip, store these files in an array, sort them, and then save them to a local variable for furt ...

Manipulating arrays of objects with handlebars.js

I need help with my node.js app that is returning JSON data for computers. { computers: { john: { cpu: "intel", ram: "8MB", hd: "1TB" }, jane: { cpu: "intel", ram: "12MB", hd: "500GB" }, mary: { ...

Looking for assistance with JQuery and JavaScript?

I oversee a team of employees, each with a 7-day work schedule. To streamline the process, I have developed a PHP form that I would like to use to collect data for verification in JavaScript before submitting it to an SQL database using AJAX. My main cha ...

Suggestions for updating the 'begin' and 'finish' variables transmitted through ajax on fullcalendar?

Shown below is the URL to request JSON data via Ajax: '/php/get-events.php?start=2015-05-31&end=2015-06-07&_=1433154089490'. This query will fetch JSON data from 2015-05-31 to 2015-06-07. However, I am looking to retrieve data over a ...

The error message thrown in Node.js: "Cannot access 'filename' property of undefined object"

Struggling with an issue in nodejs, whenever I try to post with an image, I keep getting the error message "Cannot read property 'filename' of undefined" I've been trying to debug but can't find the root cause of the error. Can someone ...

Loop through a JSON object using a sequence of setTimeout() functions

After running another function, I have retrieved a JSON object stored in the variable 'json_result'. My objective is to log each individual JSON part (e.g. json_result[i]) after waiting for 5 seconds. Here was my initial attempt: for (let key ...

What causes the error message 'avoid pushing route with duplicate key' when using NavigationStateUtils in React Native?

Within my React Native + Redux project, I have set up a reducer for navigation utilizing NavigationStateUtils: import { PUSH_ROUTE, POP_ROUTE } from '../Constants/ActionTypes' import { NavigationExperimental } from 'react-native' impo ...

Completely different method for transmitting an array to NodeJS through AJAX

Recently, I've encountered difficulties when sending arrays to NodeJS using AJAX. It seems that whenever I try to send it with JSON, the error function is always triggered. Despite seeking explanations, I haven't found a satisfactory answer. The ...

JavaScript event/Rails app encounters surprising outcome

I have encountered a strange bug in my JavaScript code. When I translate the page to another language by clicking on "English | Русский" using simple I18n translation, my menu buttons stop working until I reload the page. I suspect that the issue ...