1. Common obstacles in the functionality of data binding2. Constraints

Working on a basic controller to perform some calculations, which is a simplified version of a more complex project. The issue I'm facing is that the result displayed in the HTML gets recalculated every time there's a change, but when calculating within the $scope as a variable, it doesn't update. Refer to the markup comments for details.

Any insights on what could be causing this behavior?

Markup

<body ng-app="myApp"> 
<div ng-controller="mainController">
  <h3> Numbers </h3> 
  <label> a </label>
  <input type="number" ng-model="numbers.a"/>

  <label> b </label> 
  <input type="number" ng-model="numbers.b">
<br>
<br>
  <span> Result : {{result}} {{numbers.a*numbers.b}} </span> // the first one does not update, but the second does. 

  <h3> Nums </h3> 

    <label> a </label>
  <input type="number" ng-model="a1">

  <label> b</label> 
  <input type="number" ng-model="b1">

<br>  
  Result2:  {{result2}} {{a1+b1}}
<ul> 
  <li ng-repeat=" i in cool"> {{i}} </li>
  </ul>
  </div>
</body> 

Javascript:

angular.module('myApp',[])

.controller('mainController', ['$scope', function($scope) {
  $scope.numbers = {a:11, b:10}; 
  $scope.a1 = 5; 
  $scope.b1 = 7; 
  $scope.result = $scope.numbers.a*$scope.numbers.b; 
  $scope.result2 = $scope.a1 +$scope.b1 ;

  $scope.cool = [$scope.result + $scope.result2, 
               $scope.result - $scope.result2]
}]);

http://codepen.io/Tallyb/pen/rVdebm

Answer №1

The variable result does not update because the mainController function is only evaluated once, which happens when Angular first interprets the HTML and discovers the ng-controller="mainController" expression.

To automatically update the result, you need to set up watch listeners in the controller as shown below:

angular.module('myApp',[])

.controller('mainController', ['$scope', function($scope) {
  // ...
  $scope.$watch('[numbers.a, numbers.b]', function () {
    $scope.result = $scope.numbers.a * $scope.numbers.b;
  });

}]);

An expression like {{numbers.a*numbers.b}} will update automatically as Angular sets up watch listeners for it. The expression syntax in HTML is just syntactic sugar - Angular internally uses $watch functions for every expression found in the HTML.

Refer to the $watch documentation for more details.

I personally avoid using the $watch syntax mentioned above as it can make the controller bulky. Instead, I prefer calling a function from the HTML like this:

{{ calculateResult() }}

In the controller, define the function as follows:

angular.module('myApp',[])

.controller('mainController', ['$scope', function($scope) {
  // ...
  $scope.calculateResult = function () {
    return $scope.numbers.a * $scope.numbers.b;
  };

}]);

Side note: If performance is a concern and the calculateResult() function is slow, sticking to the initial version might be preferable.

Answer №2

When the controller is initialized, the calculations are performed only at that time when the corresponding view is shown. To incorporate these calculations, you need to place them within functions (no $watch needed):

$scope.result = function() {
  return $scope.numbers.a * $scope.numbers.b;
}
$scope.result2 = function() {
  return $scope.a1 + $scope.b1;
}
$scope.cool = function() {
  return [
    $scope.result() + $scope.result2(),
    $scope.result() - $scope.result2()
  ];
}

Then, make sure to refer to them in your view:

<span> Result : {{result()}} {{numbers.a*numbers.b}} </span>

Also:

Result2:  {{result2()}} {{a1+b1}}

Lastly:

<li ng-repeat=" i in cool(result, result2)"> {{i}} </li>

For more information, visit: http://codepen.io/anon/pen/vORXpg

Answer №3

To ensure the correct calculation of the result when numbers are changed, it is essential to have a watch in place. Otherwise, the value of result will be computed only once.

var app = angular.module('my-app', [], function() {})

app.controller('mainController', ['$scope',
  function($scope) {
    $scope.numbers = {
      a: 11,
      b: 10
    };
    $scope.a1 = 5;
    $scope.b1 = 7;

    // Recalculate result if 'a' or 'b' change
    $scope.$watch('[numbers.a, numbers.b]', function() {
        $scope.result = $scope.numbers.a * $scope.numbers.b;
      })
      
    // Recalculate result2 if 'a1' or 'b1' change
    $scope.$watch('[a1, b1]', function() {
      $scope.result2 = $scope.a1 + $scope.b1;
    })

    // Recalculate 'cool' if result or result2 change
    $scope.$watch('[result, result2]', function() {
      $scope.cool = [$scope.result + $scope.result2,
        $scope.result - $scope.result2
      ]
    })
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
  <div ng-controller="mainController">
    <h3> Numbers </h3> 
    <label>a</label>
    <input type="number" ng-model="numbers.a" />

    <label>b</label>
    <input type="number" ng-model="numbers.b" />
    <br/>
    <br/>
    <span> Result : {{result}} {{numbers.a*numbers.b}} </span> // the first one does not update, but the second does.

    <h3> Nums </h3> 

    <label>a</label>
    <input type="number" ng-model="a1" />

    <label>b</label>
    <input type="number" ng-model="b1" />

    <br/>Result2: {{result2}} {{a1+b1}}
    <ul>
      <li ng-repeat=" i in cool">{{i}}</li>
    </ul>
  </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

Setting the overlay video to match the input video size in FFMPEG

Currently, I am incorporating FFMPEG wasm into a NextJS project. However, I believe that general FFMPEG solutions will suffice since FFMPEG wasm is capable of interpreting standard FFMPEG commands. My objective is to superimpose an overlay video onto the ...

Implementing XOR operation in a jQuery script

In need of a small script modification where one value needs to be XORed. A previous suggestion no longer applies due to changes made in the script. <input type='button' value='Ein / Aus' class='taster' csv='Lampe&apo ...

The lack of definition for e.PreventDefault causes an error

In my code, I have a registerAjax(e) function: function registerAjax(e) { e.preventDefault(); let userData = { username: $("#username").val(), password: $("#password").val(), }; $.ajax({ method: "POST", url: kinveyBaseUrl + "user/" + kinve ...

Is there potentially a memory leak in this code? If there is, what steps can be taken to eliminate it?

Recently I inherited a project from my senior colleagues that focused on seamless page reloading using AJAX. The code is filled with numerous functions like this one: function iCreateProblems() { //some random code document.getElement ...

Laravel: The current configuration does not support the experimental syntax 'classProperties' at this time

When compiling my javascript files using npm run dev, I encountered a warning in my resource/app.js file where I require my custom validation script. The warning stated the following: Module build failed (from ./node_modules/babel-loader/lib/index.js): Syn ...

Tips to prevent browser from freezing while creating a large number of HTML elements

I am currently utilizing Selection.js to develop a customizable grid on my website. To make this work effectively, I need a specific number of div elements to establish the selectable area. In my scenario, I generate all the divs using a for loop and then ...

The absence of the iframe in ie8 is causing problems that cannot be fixed with relative positioning

On a website, I am integrating an external 2-factor authentication solution called Duo Web using their PHP and Javascript. It works smoothly on all browsers except for IE8. When the user passes the initial login screen, the 2FA login page loads, but the if ...

Code snippet for fetching JavaScript file using Angular's caching mechanism

Currently in my project, I am utilizing $.getScript to dynamically load specific sections of code. Here's a snippet of how it looks: var mainJs = "/main.js"; $.getScript( mainJs ) .then(function () { console.log("main.js loaded"); }); ...

Trigger animation once you've scrolled past a designated point in the document

I created a count-up counter animation using JavaScript, but the issue is that the counter starts animating as soon as I refresh the page regardless of where I am on the page or if the counter is even visible. I would like the counter to only start workin ...

Emphasize a passage by clicking on a different section of text

Seeking Assistance I am currently customizing this template which incorporates the MixItUp plugin. My query pertains to highlighting the "filter tab" upon clicking on the corresponding text when hovering over each image, a task I find challenging as a new ...

At what point are routed components initialized?

Here is a route setup I am working with: path: ':id', component: ViewBookPageComponent }, After adding this route, an error keeps popping up: Error: Cannot read property 'id' of null I haven't included a null check in the compo ...

Add data to a nested array with Vuex

Currently, I am facing a challenge with adding an object to a nested array in Vue using store / vuex. While I have successfully updated the main comments array with a mutation, I am struggling to identify the specific main comment to which the new reply ob ...

Error arises on Github when submitting a pull request due to a conflicted package

When facing conflicts in the package.json file while submitting a pull request, what is the best approach to resolve them? I usually attempt using git pull origin, but it tends to generate numerous merge commits. ...

Limiting the types of files a user can access through a web browser

Hey there! I have a unique question that sets it apart from others, as it involves restricting file types for users with a browser popup. My goal is to prevent users from selecting certain file types before they choose a file. I've come across some s ...

When attempting to send data to the ServiceStack RESTful service, an error message of 'Access is denied' was received

I created a RESTful service using ServiceStack to send data to a database. It worked perfectly when tested locally. However, after deploying it to a server and running the same jQuery $.ajax call code, I encountered an 'Access is denied' error. I ...

Image-switching button

I'm new to JavaScript and struggling with my first code. I've been staring at it for two days now, but can't figure out what's wrong. The goal is to create an HTML page where the user can change an image by clicking on a button, and th ...

transfer a product attribute value to a different product attribute within the Magento platform

There is an attribute called Weight : Attribute Code: weight Scope: general Catalog Input Type for Store Owner: Text Field Values Required: yes Apply To: Simple Product, Bundle Product Allow HTML Tags on Frontend: yes Also, there is a General Weight attr ...

Creating a dynamic hyperlink variable that updates based on user input

I am attempting to create a dynamic mailto: link that changes based on user input from a text field and button click. I have successfully achieved this without using the href attribute, but I am encountering issues when trying to set it with the href attr ...

Updating a dataview inside a Panel in extjs 3.4

I am facing an issue with my extjs Panel component that includes a dataview item. Initially, it works perfectly fine in displaying images from a store. However, upon reloading the imgStore with new image URLs (triggered by a user search for a different cit ...

Converting the jQuery $.xajax loadmore feature into a custom XMLHttpRequest JavaScript function

I'm facing challenges while trying to create a XMLHttpRequest loadmore function as compared to using $.ajax. I am uncertain about what I might be missing in my code. Below is the function that is based on a previously working $.ajax version that I ha ...