What could be the reason behind the infinite digestion loop triggered by my custom filter?

I devised a personalized filter that segregates an array of key-value pairs into an object based on grouping values by the first letter of a specific property. For instance

Input:

[{foo: 'bar'}, {faz: 'baz'}, {boo: 'foo'}]

Output:

{f: [{foo: bar}, {faz: baz}], b: [{boo, foo}]}

However, this custom filter appears to be resulting in an infinite digestion error within Angular.

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

app.controller('ctrl', ['$scope', function($scope){
  $scope.arr = [{name: 'foo', def: 'bar'}, {name: 'faz', def: 'baz'}, {name: 'boo', def: 'foo'}]
}]);

app.filter('firstLetterChunks', function() {
    return function(input){
        var chunks={};
        for(var i = 0; i < input.length; i++){
            var firstLetter = input[i].name[0].toUpperCase();
            if(!(chunks.hasOwnProperty(firstLetter))) {
                chunks[firstLetter]=[];
            }
            chunks[firstLetter].push(input[i]);
        }

        return chunks;
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">
  <div ng-controller="ctrl">
    This caused a infdig error. Check your console.
    <div ng-repeat="(firstletter, values) in arr | firstLetterChunks">
      {{firstletter}}
      <hr>
      <div ng-repeat="value in values">
        {{value}}
      </div>
    </div>
  </div>
</div>

I am struggling to pinpoint the reason behind this issue. From my research, it seems to typically arise from modifying the model in the filter, consequently triggering a re-rendering of the ng-repeat directive, but I do not believe I am engaging in such actions.

Answer №1

The reason behind this occurrence is that each filter call generates a new object with a different identity, causing Angular to detect a change and initiate a new digest cycle until the limit of 10 digests is reached.

While caching can potentially resolve this issue by storing the computed object and retaining the filter, I opted for a modification in your code that provides the same functionality. However, it does require recalculating the chunks if the array undergoes any changes:

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

app.controller('ctrl', ['$scope', function($scope){

  $scope.arr = [{name: 'foo', def: 'bar'}, {name: 'faz', def: 'baz'}, {name: 'boo', def: 'foo'}];

    function getChunks() {
        var input = $scope.arr;
        var chunks = {};
        for(var i = 0; i < input.length; i++){
            var firstLetter = input[i].name[0].toUpperCase();
            if(!(chunks.hasOwnProperty(firstLetter))) {
                chunks[firstLetter]=[];
            }
            chunks[firstLetter].push(input[i]);
        }

        return chunks;
    }

    $scope.chunks = getChunks();
}]);

Make sure to update the HTML call as follows:

<div ng-repeat="(firstletter, values) in chunks">

Check out the Fiddle here

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

What is the best method to activate a JavaScript function after 1 minute of user inactivity?

I need to set up a web page where a JavaScript function is activated after 1 minute of user inactivity. The page primarily features the <form> component. What's the best way to implement this type of function? ...

Display a progress bar on the index page of the grid view

Seeking assistance in displaying a progress bar on the grid view page index. Currently, I have successfully implemented a progress bar on button click and would like to replicate this functionality when the user switches from 1 to 2. Here is the modal pop- ...

What methods can be used to generate a comprehensive coverage report using karma?

I am working with karma-coverage, browserify, and angular. The issue I am facing is that the coverage report shows 100% coverage for all files under test, which is incorrect. Any suggestions on how to resolve this? Here is a snippet from my karma.conf.js ...

Utilize a map image as a texture on a plane within a personalized shader in THREE.js

I'm currently facing an issue where I need to load two images as textures, blend between them in the fragment shader, and apply the resulting color to a plane. However, I am struggling to even display a single texture properly. My process for creatin ...

Reaching the maximum request threshold

Currently, I am facing an issue where users are able to upload files from the client side (using Angular 4) to the server (implemented with Spring Boot). The problem arises when a user attempts to upload more than 6 files at once. In such cases, Chrome uti ...

The functionality of ng-click and ng-submit seems to be malfunctioning

I am currently facing an issue with my Angular application and PhoneGap. I have a login form along with a login controller set up, but for some reason, the ng-submit function is not working as expected. When the submit button calls the formConnexion() func ...

Ways to retrieve text from an input field using Protractor

Looking through the protractor documentation, I came across an interesting example: describe('by model', function() { it('should find an element by text input model', function() { var username = element(by.model('username&ap ...

Tips for sending JSON data to .js files

I am experiencing an issue here. In locations.php, I have the following code to generate JSON data: <?php $locations = array( array('2479 Murphy Court', "Minneapolis, MN 55402", "$36,000", 48.87, 2.29, "property-detail.html", ...

Optimizing Test Data Management for Protractor in Angular E2E Testing: How to Choose the Most Effective Strategy

As a beginner in the world of Angular and Protractor, I have successfully created several protractor test cases for automating tasks such as registration, login, and other pages. However, I am facing an issue when it comes to passing data into my test case ...

Is sending a stream to a variable the best option, or could there be another solution

Is there a way to pipe stream data to a variable? The writable stream examples mentioned in this documentation include: HTTP requests on the client side HTTP responses on the server side Zlib streams Crypto streams TCP sockets Child process stdin Process ...

Enhancing Image Quality with jspdf and Html2Canvas

We are currently utilizing jsPDF and HTML2canvas to create PDFs, however, we have noticed that the image resolution is quite high. Is there a method available to obtain low-resolution images using jquery, javascript, jsPDF, and html2canvas? function addE ...

When a promise is executed, it runs the code synchronously regardless of the promise

Essentially, I have a web application that fetches data from Firebase. Due to the time it takes to retrieve this data, I've implemented promises in JavaScript to ensure my code executes at the appropriate times. Within the function getDataFirebase, in ...

Dynamic options can now be accessed and modified using newly computed getters and setters

When using Vuex with Vue components, handling static fields that are editable is easily done through computed properties: computed: { text: { get() { return ... }, set(value) { this.$store.commit... }, }, }, <input type ...

Techniques for eliminating single quotes from string arrays and then creating a new array by separating them with commas

I have an array of elements containing IP addresses with single quotes. I need to remove the single quotes and separate each IP address into new values, storing them as strings in another array using JavaScript. let myArray = [ '10.202.10.800,10.202 ...

Using JavaScript to convert the text within a div into negative HTML code

I am working with this specific div: <div class="signs" id="signs" onclick="toggle()">&#43;</div> It currently displays the positive sign. I have set up a JavaScript function that is triggered when the div is ...

Guide on verifying internet connection status using Ajax request

Ensuring authentication by checking the availability of network connection on mobile devices. To do this, we must have both a username and password. The authentication process will be conducted online, requiring an active internet connection on the device. ...

When using JSON.stringify(value, replacer), the output may vary between Chrome and Firefox

I'm encountering an issue when attempting to utilize JSON.stringify with the "replacer" function. var scriptTag = document.createElement('script'); scriptTag.type = 'text/javascript'; scriptTag.src = 'https:// ...

Is NodeJS Asynchronous: Has the callback been called twice?

I'm currently working with the Async module in Node.JS to manage my asynchronous calls. However, I've encountered an issue stating "Callback already called." Could someone assist me with resolving this problem? async.each(data['results&apos ...

Techniques for Shortening Dates in JavaScript

How can I abbreviate a full date in JavaScript? For example, converting 15 September 2020 to 15 SEP 20. I have arrays of dates that need this formatting. ...

How to extract just the year from Material-UI's date picker in React

const displayYearOnly = (date) => { const year = date.getFullYear(); console.log(year); }; return ( <div style={{ marginRight: "20px" }}> <LocalizationProvider dateAdapter={AdapterDayjs}> <DemoContainer componen ...