What could be causing my Angular.js controller to run its function twice in this code snippet?

Currently, I have an ng-repeat in place, looping through an array of objects that are associated with the SomeController:

<div ng-controller="SomeController as aCtrl">
  <div ng-repeat="category in aCtrl.categories">
    <p ng-show="aCtrl.checkShouldBeDisplayed(category)">{{category.name}}</p>
  </div>
</div>

The controller has been defined like so:

app.controller('SomeController', function() {

this.categories = [{
  "name": "one",
}, {
  "name": "two",
}, {
  "name": "three",
}, {
  "name": "four",
}];

this.counter = 0;

this.checkShouldBeDisplayed = function(channel) {
this.counter = this.counter + 1;
console.log("Executing checkShouldBeDisplayed " + this.counter);
return true;
};

}); 

It was expected that the checkShouldBeDisplayed function would count up to 4 due to the four elements present in the SomeController.categories array. However, it is counting up to 8 instead – you can view this behavior here: http://plnkr.co/edit/dyvM49kLLTGof9O92jGb (please refer to your browser console for the logs). How can I resolve this issue? Thank you!

Answer №1

It is anticipated; The ng-repeat directive will iterate as determined by the framework; this process, known as dirty checking, is further explained in this informative post.

Therefore, it is advisable to approach the task declaratively rather than imperatively. In essence, the function checkShouldBeDisplayed should simply carry out its designated purpose without depending on the number of times it is invoked. Any need for aggregation or manipulation should be handled elsewhere within the controller.

Answer №2

As stated in the documentation:

The watchExpression is invoked every time $digest() is called and should provide the value to be monitored. (Given that $digest() runs again upon detecting changes, the watchExpression could run multiple times per $digest() cycle and must be idempotent.)
[...]
The watch listener has the ability to modify the model, potentially triggering additional listeners to be fired. This process involves running the watchers repeatedly until no further changes are detected.

All ngShow does is set up a watcher:

scope.$watch(attr.ngShow, function ngShowWatchAction(value){
    $animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide');
});

Your function serves as the watch-expression for ngShow, leading to its execution occurring twice:
1. During the initial $digest, it identifies the new values.
2. Within the subsequent $digest, it confirms that nothing has altered and then ends.


This brief demo demonstrates the presence of two distinct $digest loops.

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

Having trouble with the Bootstrap dropdown not activating the click event?

My issue involves a Bootstrap dropdown where the click event is not triggering. I'm curious about why the click event won't trigger and if there's a solution available to fix this problem. <div class="dropdown d-inline-block"> ...

Steering clear of Unfulfilled Promises in TypeScript. The Discrepancy between Void and .catch:

When it comes to handling promises in TypeScript, I'm used to the then/catch style like this: .findById(id) .then((result: something | undefined) => result ?? dosomething(result)) .catch((error: any) => console.log(error)) However, I have also ...

I am struggling to grasp the concept of how the g flag in JavaScript's string.match(regexp) method operates

In the JavaScript book "The Good Parts", there is an explanation of the method string.match(regexp): The match method works by comparing a string with a regular expression. Its behavior varies based on whether or not the g flag is present. Without the g ...

Transferring data from AJAX to PHP

I am currently developing a project in PHP. I have created an associative array that functions as a dictionary. Additionally, I have a string containing text with placeholders for keys from the array. My goal is to generate a new String where these key wor ...

Generating an interactive button click feature within a cell of a data table

Can someone help me figure out why I am getting a SyntaxError when trying to trigger a function in a datatable cell using an onclick event on a button? The button is successfully created, but the error occurs when clicking it. The problem seems to lie wit ...

Is the Vis.js network function ready to go?

Utilizing the Vis.js network library to display graphs and am curious if there is a dedicated finishedLoading event available for this object? Any suggestions or insights are appreciated! ...

Constantly positioning the text cursor over the Textbox

I am currently in the process of developing a webpage that will feature only one text box for displaying information based on the input data provided. Our strategy involves utilizing either a Barcode Scanner or Magnetic Swipe as well as a Touch Screen Moni ...

Shuffle letters in a word when hovered over, then unscramble them back to their original order

I have noticed a fascinating effect on several websites. To give you an idea, here are two websites that showcase this effect: Locomotive and TUX. Locomotive is particularly interesting to look at as the desired effect can be seen immediately when hovering ...

Is there a way to extract video frames from a WebRTC local stream and transfer them to Python?

I am in the process of developing a video call application similar to Google Meet or Zoom, incorporating object detection using Python Flask or Django. Here is how the application functions: Users can join a channel for the video call The camera ini ...

Troubleshooting: AngularJS View Fails to Update with Defer and Factory

I've encountered an issue where my view doesn't update when I create a new setting without refreshing the page. Can someone provide guidance on how to resolve this issue? If there's a better approach to achieving this, please share that as w ...

Transfering information to handlebars in node.js

Being a beginner in node.js, I am currently working on making a get request in my router (index.js). After successfully obtaining the desired result (verified by logging it in console.log), I proceed to parse it into a JSON object and pass it to a render f ...

Tips for troubleshooting the error "Cannot locate module mp3 file or its associated type declarations"

https://i.sstatic.net/q4x3m.png Seeking guidance on resolving the issue with finding module './audio/audio1.mp3' or its type declarations. I have already attempted using require('./audio/audio1.mp3'), but continue to encounter an error ...

Variables in an Angular application are not appearing in the HTML rendering

Currently learning AngularJS as I develop a web application. After going through tutorials, I started with a basic list but am baffled as to why my browser only shows {{title}}. In my app.js module, here's the snippet where I defined the controller: ...

Removing a row from MySQL using JQuery Ajax

Hello there! I'm currently facing an issue while trying to remove a row from a MySQL database using PHP and AJAX. I initially thought it would be a simple task with $.ajax {}, but unfortunately, the row is not getting deleted for some reason. Here&apo ...

When the Ionic app is relaunched from the side menu, the view fails to refresh

When I open my Side Menu, I initially see two options - scan barcode or search product. Once I choose one, the rest of the view is filled in dynamically. The issue arises when I try to go back to the Side Menu and reload the view to only display the origin ...

Is there a way to retrieve the width of the parent element in ReactJS from a child component?

The issue has been fixed: I forgot to include .current in my ref... I am trying to determine the width of the element that will hold my component. I came across a solution on SO, but unfortunately it did not work for me as it returned undefined: import R ...

Require assistance in understanding JSON data in the form of a variable

Apologies for any language barriers, but I have encountered a problem that I need help with. I am trying to create a highchart from an AJAX call. The following code works perfectly: chartOptions = { chart: { renderTo: 'grafica1', type: 'ar ...

What is the best way to implement a recursive service call that is triggered automatically at regular intervals?

I came across this code snippet: us.isConnected() .then(function (msg) { er.msg = msg }, function (msg) { er.msg = msg }); $interval(function () { us.isConnected() .then(function (msg) { er.msg = msg }, function (msg) { er.msg = msg }); }, ...

Is it possible to modify the host header within an Angular app?

I'm experiencing a vulnerability issue and to resolve it, I need to utilize SERVER_NAME instead of the Host header. Is it possible to accomplish this using Angular? ...

Update the styling of each div element within a designated list

Looking for a way to assist my colorblind friend, I am attempting to write a script. This is the layout of the page he is on: <div class="message-pane-wrapper candy-has-subject"> <ul class="message-pane"> <li><div style=" ...