AngularJS: modify the variables to monitor

I want to modify the variables that are being monitored.

JS:

var app = angular.module('myApp', []);

app.controller('MainController', 
  function($scope) {
    
    $scope.current = null;
    $scope.select = function(item) {
      $scope.current = item;
    };
    
    var watch = ['current'];
    $scope.$watchGroup(watch, function() {                 // This does not work
      if ($scope.current !== null) {
        watch = ['current'];
        Array.prototype.push.apply(watch, $scope.current.watch);
        $scope.current.callBack();
      }  
    });
    
    $scope.list = [
        {
          name: 'test-A',
          watch: ['a'],
          callBack: function() {
            $scope.value = 2 * $scope.a;
          }
        },
        {
          name: 'test-B',
          watch: ['b'],
          callBack: function() {
            $scope.value = 3 * $scope.b;
          }
        }
      ];
  
});

HTML:

<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <link data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="096b66667d7a7d7b6879493a273a273e">[email protected]</a>" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
  <script data-require="jquery" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js"></script>
  <script data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ceaca1a1babdbabcafbe8efde0fde0f9">[email protected]</a>" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abcac5ccdec7cad985c1d8eb9a859d859d">[email protected]</a>" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="MainController">
  <div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
      {{current != null ? current.name : 'DropDown'}}
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
      <li ng-repeat="item in list">
        <a href="javascript:void(0)" ng-click="select(item)">{{item.name}}</a>
      </li>
    </ul>
  </div>
  When "test-A" is selected, result is 2 times of A.
  <br> When "test-B" is selected, result is 3 times of B.

  <br>
  <br>
  <br>

  <form class="form-inline">
    <div class="form-group">
      <label>A</label>
      <input type="text" class="form-control" ng-model="a">
    </div>
    <div class="form-group">
      <label>B</label>
      <input type="text" class="form-control" ng-model="b">
    </div>
  </form>

  <br> result : {{value}}
  <br>
</body>

</html>

This is Plunker example.

The result should be 2 times of A when test-A is selected, should be 3 times of B when test-B is selected.

I wish to change which variables are being watched. However, the method indicated in the line This does not work is ineffective. The $watchGroup only triggers when current is altered. I intend for this $watchGroup to trigger when either current or a is modified if test-A is chosen, and when current or b is changed if test-B is selected.

I am aware that

$scope.$watchGroup(['a', 'b', 'current'], ...
works. Nevertheless, I prefer not to activate this $watchGroup when test-A is picked and b is updated, and vice versa.

How can I adjust which variables are monitored?

Answer №1

review the code below for a potential solution that may aid you.

Snippet

var app = angular.module('myApp', []);

app.controller('MainController',
  function($scope) {

    $scope.current = null;
    $scope.select = function(item) {
      $scope.current = item;
    };

    var watch = ['current'];
    $scope.$watchGroup(watch, function() {
      if ($scope.current !== null) {
        watch = ['current'];
        Array.prototype.push.apply(watch, $scope.current.watch);
        $scope.current.callBack();
      }
    });

    $scope.list = [
        {
          name: 'test-A',
          watch: [' is double the value of a'],
          callBack: function() {
            $scope.value = (2 * $scope.a) + ($scope.current.watch);
          }
        },
        {
          name: 'test-B',
          watch: [' is triple the value of b'],
          callBack: function() {
            $scope.value = (3 * $scope.b) + ($scope.current.watch);
          }
        }
      ];

});

I appended ($scope.current.watch) to your output

Check if it has been implemented in your plnkr.

https://plnkr.co/edit/UGPe4lgJPydEeAXOc0xR?p=preview

Answer №2

Modify the line:

$scope.$watchGroup(watch, function() {

to look like this:

$scope.$watch('current', function() { 

The reason for this change is that the value of current is updated when you click on the menu. The variable var watch = ['current']; remains constant and does not reflect this change. To ensure proper functionality of the watch, you need to reference the correct variable, which in this case is $scope.current.

// Your modified code goes here

var app = angular.module('myApp', []);

app.controller('MainController', 
  function($scope) {
    
    $scope.current = null;
    $scope.select = function(item) {
      $scope.current = item;
    };
    
    var watch = ['current'];
    $scope.$watch('current', function() {
      if ($scope.current !== null) {
        watch = ['current'];
        Array.prototype.push.apply(watch, $scope.current.watch);
        $scope.current.callBack();
      }  
    });
    
    $scope.list = [
        {
          name: 'test-A',
          watch: ['a'],
          callBack: function() {
            $scope.value = 2 * $scope.a;
          }
        },
        {
          name: 'test-B',
          watch: ['b'],
          callBack: function() {
            $scope.value = 3 * $scope.b;
          }
        }
      ];
});
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <link data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b3d1dcdcc7c0c7c1d2c3f3809d809d84">[email protected]</a>" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
  <script data-require="jquery" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js"></script>
  <script data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e5c51514a4d4a4c5f4e7e0d100d1009">[email protected]</a>" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9afbf4fdeff6fbe8b4f0e9daabb4acb4ac">[email protected]</a>" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller="MainController">
  <div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
      {{current != null ? current.name : 'DropDown'}}
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
      <li ng-repeat="item in list">
        <a href="javascript:void(0)" ng-click="select(item)">{{item.name}}</a>
      </li>
    </ul>
  </div>

  <br>

  <form class="form-inline">
    <div class="form-group">
      <label>A</label>
      <input type="text" class="form-control" ng-model="a">
    </div>
    <div class="form-group">
      <label>B</label>
      <input type="text" class="form-control" ng-model="b">
    </div>
  </form>

  <br> result : {{current.watch}}
  <br>
</body>

</html>

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

Does AngularJS operate with a database or utilize JSON?

I'm currently working on a web application and I have data coming in either through JSON or directly from the database. I believe that AngularJS can only use this data once, so if there are any changes to the data source, will AngularJS still be able ...

What causes useEffect to trigger twice when an extra condition is included?

Attempting to create a countdown timer, but encountering an interesting issue... This code triggers twice in a row, causing the useEffect function to run twice per second. 'use client' import {useState, useEffect, useRef} from 'react' ...

JavaScript is unable to retrieve values from a dropdown menu with selectable options

After searching on Stack Overflow (jquery select change event get selected option), I attempted to implement the provided code but did not make any progress. As the options are changed, the values concatenate to create a variable that points to a specific ...

Granting Access to an S3 Object (Specific HTML Page) Using AWS Cognito JS

On my website hosted on s3, I have three HTML files - register.html, login.html, and dashboard.html. After successfully registering and logging in, I obtain an access token. What is the best way to limit access to the dashboard.html file and utilize the ...

Issue: Unable to locate the module 'nexmo' & error TS2307: 'nexmo' module not found

Currently, I am utilizing the powerful NestJs Framework alongside typescript. My task involves incorporating two-factor authentication (SMS) using the Nexmo node library. You can find further information on their website: During the development phase, ev ...

Establishing the default scroll position in tables using React.js

How can I set the initial scroll in ReactJS Material-UI tables? I'm working with a table that has numerous columns and I would like to have specific columns in view automatically without having to scroll, essentially establishing an initial scroll. I ...

Encountering a problem with the getJSON() function within the app.js file connected to a solidity

Currently, I am working on developing a simple dapp in Truffle. However, I encountered an error when using $.getJSON() function in my app.js file. Below is a snippet of my app.js: App ={ web3Provider: null, contracts: {}, init: function (){ return A ...

How can you verify the correctness of imports in Typescript?

Is there a way to ensure the validity and usage of all imports during the build or linting phase in a Typescript based project? validity (checking for paths that lead to non-existent files) usage (detecting any unused imports) We recently encountered an ...

Learn how to access an array within an object using JavaScript and an API URL

Trying to fetch data from the swapi API to display film titles using jQuery. Below is the JavaScript code: $(function(){ function promiseTest(){ return $.ajax({ type: 'GET', url: 'https://swapi.co/api/people/', } ...

Creating a loader with a built-in timeout feature in JavaScript

I am retrieving data from an API and managing the loading of the data using a loader in my HTML. If the data array length is undefined, the data will be displayed. However, if there is no data, it continues to load indefinitely... My goal is to implement ...

Using the v-for loop to generate radio inputs results in selecting multiple radio buttons with identical values

Having a bit of trouble explaining, I've developed a basic rating system that utilizes input type ="radio" for an array of products. By using v-for="product in products", I iterate through the array and display all the products on the webpage. ...

Using JavaScript, grammatically add material icons side by side

Looking to dynamically update the contents of a div element by adding two material icons side by side. To test this, I created a simple fiddle that demonstrates what I am trying to achieve: https://jsfiddle.net/zog20r7n/3/ When attempting to modify line ...

Issue encountered: "require" is not recognized when attempting to access my local JSON file in Vue.js

I am venturing into the world of vuejs... I attempted to retrieve data from my JSON file stored locally, but the decision on which specific JSON file's data to fetch is dynamic. I keep encountering an error stating 'require' is not define ...

Using Node.js and JWT: A guide to securely storing and using access tokens in the Authorization header

Has anyone encountered this issue before? I've searched extensively online but haven't found much information on the topic. I'm relatively new to using node and JWTs, and my goal is to generate a JWT and store it in the Authorization header ...

initial cookie value not established in angular js

I need help passing a cookie value from one UI to another page. The specific cookie value I want to retrieve is the user's username, for example: Nithya When I log in to the home page, the cookie value appears empty until I refresh the page. Is the ...

The <br/> tag is not functioning properly when retrieving text from a MySQL query

Currently, I am involved in a project that involves an A.I pushing text onto a MySQL database. Our goal is to display the ongoing writing process on a webpage. We are still actively working on this. We are retrieving the data and regularly checking the da ...

After following the official guide, I successfully installed Tailwind CSS. However, I am facing issues with utilizing the `bg-black` className for styling the background,

Following the installation guide for Tailwind CSS, I ran the command npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p. Despite this, the background className (bg-black) is not working as expected. Here are the file paths: Directory ...

Various spacings between letters are used for various font styles

After carefully choosing a letter-spacing that enhances the readability of my webpage, I encountered an issue when Arial was used as a backup font for browsers that don't support embedded fonts. The letter-spacing got all messed up and caused overflow ...

Adjust choices in a dropdown menu based on the selection of another dropdown menu

I am attempting to create a scenario where selecting an option from one dropdown list will dynamically change the options available in the next dropdown list. You can find my code on jsfiddle <!DOCTYPE html> <html> <body> &l ...

Unable to retrieve new API data when Vue.js script setup parameters change

I am working on fetching data from jsonplaceholder using Axios in Vue. I have created a limit with a select input where the user can specify how many posts they want to see. The default number of posts displayed is 10. Initially, when the page loads, eve ...