How come Angular doesn't properly handle array element modifications through filters?

Despite my efforts to debug, I am still unable to pinpoint the mistake I am making in Angular.js.

I have been closely following the basic Angular tutorial at https://docs.angularjs.org/tutorial/step_03, where all examples run smoothly. However, I decided to experiment with some advanced features of Angular and added my own code to the step 3 examples.

Below are the links to the HTML and controller files:

index.html: https://gist.github.com/tario/f07239992eea75535421

controller.js https://gist.github.com/tario/1b6155b5c97e747abe32

The filter function is defined here: https://gist.github.com/tario/1b6155b5c97e747abe32#file-controllers-js-L16

However, when I try to enable the uppercase feature using the checkbox, I encounter the following error message:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 62; oldVal: 59"],["fn: $watchCollectionWatch; newVal: 65; oldVal: 62"],["fn: $watchCollectionWatch; newVal: 68; oldVal: 65"],["fn: $watchCollectionWatch; newVal: 71; oldVal: 68"],["fn: $watchCollectionWatch; newVal: 74; oldVal: 71"]] http://errors.angularjs.org/1.2.17/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3…20%24watchCollectionWatch%3B%20newVal%3A%2074%3B%20oldVal%3A%2071%22%5D%5D at at Scope.$get.Scope.$digest () at Scope.$get.Scope.$apply () at HTMLInputElement. () at at Array.forEach (native) at forEach () at HTMLInputElement.eventHandler ()

I am uncertain if the way I implemented the filter aligns with best practices. Can you help me understand why it's failing? All I intended to do was create a new array with transformed content from the initial array.

Answer №1

When consulting the Angular documentation regarding this error:

This particular error occurs when the stability of the application's model is compromised, leading to a cascade effect where each $digest cycle triggers a state change followed by another $digest cycle. Angular is designed to detect and prevent such scenarios to avoid an infinite loop that could render the browser unresponsive.

The issue arises during each digest cycle, as your filter consistently produces a new array. Due to AngularJS's dirty checking mechanism, any change in values prompts a new digest cycle, perpetuating the process.

To address this problem, there are two possible solutions:

1) Opt for consistent results by employing the memoize function from Lodash.

Each call to a memoized function involves a resolver function that checks the cache for previous results before computation. If retrieved, the cached result is returned; otherwise, the calculation is performed and the outcome stored for future use.

    phonecatApp.filter('uppercaseAllThings', function () {
        return _.memoize(
        function (items, enabled) {
            if (enabled) {
                var newitems = [];
                angular.forEach(items, function (item) {
                    newitems.push(uppercaseAllAttributes(item));
                });

                return newitems;
            }
            return items;
        },
        function (items, enabled) {
            return enabled + angular.toJson(items)
        });
    });

An explanatory JsFiddle detailing this approach can be accessed here.

2) Alternatively, if uppercase conversion suffices, utilize CSS to conditionally apply styling.

The proposal involves creating a CSS class that leverages the text-transform property.

.uppercase {
   text-transform:uppercase;
}

Incorporate this class into your stylesheet and adjust the HTML structure accordingly:

<li ng-repeat="phone in phones | filter:query | orderBy:orderProp"
    ng-class="{'uppercase':uppercaseEnabled}">
   <span>{{phone.name}}</span>
   <p>{{phone.snippet}}</p>
</li>

A simple JSFiddle elucidating the second solution has been provided.

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

Tips for disregarding modified configuration files in Git

I have a project stored in Git that I plan to install on numerous PCs. Within this project, there is a configuration file called config.ts with the following structure: export var config = { apiUrl: "", local: "", scannerUrl: "", reportPrinter ...

Restrict the duplication of div elements with JQuery

Here is the structure I'm working with: <div class="checkmark-outer"> <div class="checkmark-33"> <div class="fa-stack fa-1x checkmark-icon"> <i class="fa fa-circle fa-stack-2x icon-background"></i> ...

Is it possible to access XMLHTTPRequest.responseText using a standardized method in JSON.parse?

In my ASP.NET web application, I have a simple Javascript function that executes on an input's onblur event: function validateUsername() { var request = new XMLHttpRequest(); if (request == null) { alert("Failed to create request."); ...

How can I use AngularJS to show a JSON value in an HTML input without any modifications?

$scope.categories = [ { "advertiser_id": "2", "tier_id": 1, "tier_name": "1", "base_cpm_price": "", "retarget_cpm": "", "gender": "", "location": "", "ageblock1": "", "ageblock2": "", "ageblock3": ...

Confusing JQuery query about updating image links

Hey there! I'm facing a bit of a challenge and I believe that the brilliant minds here on stackoverflow can help me out. My goal is to dynamically update the href tag for an image based on the user's selection of a product option, like a differe ...

What is a reliable method to retrieve the text from the current LI if all LI elements in the list share the

I'm encountering an issue with retrieving the text from LI elements because I have 10 list items and they all have the same class name. When I attempt to fetch the text using the class name or id, I only get the text of the last item. Here is my code ...

Why is the image auto-swapping script failing to display images frequently?

I have a script that is currently running to rotate between two different logos on my webpage. What I am attempting to achieve is for the page to load and then seamlessly transition from one image to the other without any blank space. Below is the code I ...

Show a dynamic highchart graph displaying linear data retrieved from the database

I am attempting to present data retrieved from a database in a linear highchart format. Here is the JSON response from my database: [{"protocol":"tcp","date":"01/02/20","time":"00:10:20","total":281}, {"protocol":"udp","date":"01/02/20","time":"00:10:30", ...

Guarantee the correct sequence of following HTTP ajax requests within AngularJS

Imagine a basic search form with autocomplete that triggers a $http.get() request on keyup/keypress: <input type="text" ng-model="keyword" ng-change="makeRequest()"> and $scope.makeRequest = function() { $http.get(url).then(function(res) { ...

Tips for applying styles with an on-click event in a loop

I have an array of objects (items) that can be incremented with other items, which are displayed by looping through the array. Take a look at the image here: https://i.sstatic.net/AXRGQ.png When I click on an item, I want to highlight it (for example: c ...

The variable 'originalPrompt' has already been declared within the React TypeScript code

For the project I am working on, I do not have a variable named "originalPrompt," yet I keep seeing this error message. This problem seems to only occur for users who are using the "Selenium IDE" chrome extension. Is there a way to prevent this extension f ...

leveraging UI-Router for navigating based on app state and data

Is there a way to dynamically adjust Angular's ui-routing based on certain data conditions? For instance, let's say we need to create a subscription process where the user is informed of whether their subscription was successful or not. As the f ...

XMLHttpRequest changes the contents of UTF-8 encoded text

Encountered a challenging issue while processing a large XML file on the client side. Some unicode characters are being replaced with unreadable sequences, causing the server to be unable to parse the XML properly. Here is how I approached testing and hand ...

Click to slide the div down and up when needed

Currently, I am utilizing the code below to implement a slide up/down effect on a div using JavaScript. The slide down action is triggered by a button, while the slide up action is associated with a close text. My goal is to have the button toggle betwee ...

Consistently gathering stock price data tables

Issue at Hand: I am aiming to automate the scraping of a table containing currency prices from this stock price website. As the stock broker does not offer an API, I need to find alternative methods. I have extensively researched existing applications fo ...

Capturing screenshots with Selenium in Node.js is proving to be quite sluggish

My current project involves using Selenium with Mocha in Node.js for UI testing on a website. I want to capture screenshots after each test to review and share the results visually. The challenge arises when there are AJAX calls and JavaScript animations ...

Exploring the distinction and connection between the $scope provided in a controller and the $scope provided in a directive

Can you explain the distinction and connection between the $scope utilized in a controller versus the $scope used in a directive? How is the setup process for each of these scopes different? Please elaborate. ...

Cut off all information beyond null characters (0x00) in Internet Explorer AJAX responses

When using Internet Explorer (IE6, IE7, and IE8), null characters ("0x00") and any subsequent characters get removed from ajax responses. Here's the code snippet that showcases a loop of AJAX requests: var pages = 10; var nextnoteid = 0; for (isub ...

Only the initial element within the specified class is targeted by JQuery

Currently, I am utilizing Kendo UI to refresh multiple charts by class without having to access each one individually. Here is the code snippet I am using: $(".k-chart").data("kendoChart").refresh(); The issue I am encountering is that only the first cha ...

EJS failing to render HTML within script tags

Here is some code that I'm working with: <% // accessing content from a cdn api cloudinary.api.resources( { type: 'upload', prefix: '' }, (error, result) => { const assets = result.r ...