change in the value of a nested formArray within a parent formArray

I am working with a form that includes a formArray called FinYearArray, which in turn contains another formArray called RecipientArray. Both of these arrays have formControls for the amount, and whenever there is a change in these fields, the totals need to be calculated for each financial year and each recipient country per financial year. To calculate the total for recipients, I added a formControl in the FinYearArray called 'RecipientTotal'.

// Form structure
{
    "FinYearArray": [
        {
            "FinYear": 2022,
            "FinYearAmount": 0,
            "RecipientTotal": 0,
            "RecipientArray": [
                {
                    "CtryDesc": "",
                    "Amount": 0,
                },
                {
                    "CtryDesc": "",
                    "Amount": 0,
                }
            ],
        },
        {
            "FinYear": 2023,
            "FinYearAmount": 0,
            "RecipientTotal": 0,
            "RecipientArray": [
                {
                    "CtryDesc": "",
                    "Amount": 0,
                }
            ],
        }
     ],
    "ProjectCode": "",
}

In my ngOnInit(), I have the following code to monitor changes in the FinYearArray formArray and automatically update the RecipientArray formArray since it is nested inside the other formArray.

// Function to calculate totals for each financial year and recipients per financial year

    this.formDetailReport.get('FinYearArray').valueChanges.subscribe(values => {
        this.myFinYearTotal = 0;
        const ctrl = <FormArray>this.formDetailReport.controls['FinYearArray'];

    // Loop through financial years
        ctrl.controls.forEach(x => {
            let parsed = Number(x.get('FinYearAmount').value);
            this.myFinYearTotal += parsed;
        });

// Loop through recipient countries for each financial year
            for (let i = 0; i < ctrl.controls.length; i++) {
                this.myRecipientTotal = 0;
                const recipientFormArray = <FormArray>ctrl.controls[i].get('RecipientArray');

                recipientFormArray.controls.forEach(x => {
                    let parsed = Number(x.get('Amount').value);
                    this.myRecipientTotal += parsed;
                });
                console.log('total : ' + i + ' amount : ' + this.myRecipientTotal );
// The error occurs when trying to assign the calculated value to the formControl
                this.formDetailReport.controls['cFinYearGroup']['controls'][i].controls.cRecipientTotal.setValue(this.myRecipientTotal);
                // ctrl[i].controls.cRecipientTotal.setValue(this.myRecipientTotal);
            }
            this.ref.detectChanges();
        });

However, I am encountering an error:

// Error related to assigning the calculated value to the formControl
core.js:4442 ERROR RangeError: Maximum call stack size exceeded
    at EuiInputNumberComponent.ngDoCheck (eui-components-next.js:11713:1)
    at callHook (core.js:3285:1)
    at callHooks (core.js:3251:1)
    at executeInitAndCheckHooks (core.js:3203:1)
    at refreshView (core.js:7395:1)
    at refreshEmbeddedViews (core.js:8481:1)
    at refreshView (core.js:7404:1)
    at refreshComponent (core.js:8527:1)
    at refreshChildComponents (core.js:7186:1)
    at refreshView (core.js:7430:1)

It seems that the error is caused by the valueChange tracking every field in the formArray. Is there a way to modify it so that it only watches changes in the FinYearAmount formControl and then in the Amount formControl in the RecipientArray?

Answer №1

If you need to update an AbstractControl that has a listener for valueChanges and you want to avoid it being triggered again (which can lead to the infinite loop you are experiencing), you can include a configuration object in your setValue/patchValue method:

myFormControl.setValue(value, { emitEvent: false });

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 positioning a mat-form-field beside an h1 tag

I've been attempting to place an h1 next to a mat-form-field from Angular Material, but I'm encountering some difficulties. Here's what I've attempted so far: <div class="mat-elevation-z8"> <mat-form-field> <mat-l ...

Having trouble retrieving data from a JSON file within an Angular application when utilizing Angular services

This JSON file contains information about various moods and music playlists. {mood: [ { "id":"1", "text": "Annoyed", "cols": 1, "rows": 2, "color": "lightgree ...

Transition your PHP application to Angular gradually

Our current setup consists of a Multi Page PHP Application that we are looking to migrate to Angular 4 in stages. This will allow us to gradually transition our modules over the span of a few months. While we have Node.js installed on our localhost testin ...

Troubleshooting a GetStaticProps problem in Next.js

I'm currently facing an issue with retrieving posts from my WordPress site. After running tests on the URL endpoint, it seems to be functioning properly with client-side rendering. However, when I attempt to utilize the getStaticProps function, the re ...

Having trouble decoding a cookie received from a React.js front-end on an Express server

When using React js for my front end, I decided to set a cookie using the react-cookie package. After confirming that the request cookie is successfully being set, I moved on to configure the Express server with the cookie parser middleware. app.use(cookie ...

When attempting to deploy my app, I encountered a CORS error with Nest.js

Currently, I am in the process of building a Nest.js - React.js application. However, I am encountering a cors error despite having cors enabled in my main.ts file of Nest.js. While my application functions smoothly on localhost and an IP address in produ ...

What is causing the error to appear in my Jasmine unit test?

Embarking on my journey to implement an Angular Unit Test using Jasmine for the first time, I encountered a few challenges after referring to some examples. The crux of my issue lies in the implementation of the PeopleListComponent class which encapsulate ...

Exporting a Component from a Lazy Loaded Module in Angular 2: A Step-by-Step Guide

In Module M1, I have a component 'A' that is added and exported for lazy loading. Now in another module M2, there is component 'B' which uses A as its selector. However, since M1 is lazily loaded, I encounter the following error: "Com ...

Guide to Triggering a Page View Event in Google Tag Manager with Angular

Previously, I manually fired the Page View Event using JavaScript from app.component.ts while directly accessing Google Analytics: declare var gtag: Function; ... constructor(private router: Router) { const navEndEvents = this.router.events.pipe( fil ...

TypeScript integration for express-validator

Recently, I made an attempt to switch my NodeJS project with ExpressJS to TypeScript for better organization and type safety. However, I encountered an issue with the 'express-validator' middleware during this conversion process. To resolve thi ...

There was an error encountered during the npm install process

C:\Users\Mayur Saner\pmrm>npm install npm ERR! code ENOTFOUND npm ERR! errno ENOTFOUND npm ERR! network request to http://registry.npmjs.org/@fortawesome%2ffontawesome-free failed, reason: getaddrinfo ENOTFOUND proxy.company.com npm ERR! ...

Ways to stop dialog from disappearing in Reactjs

This code snippet demonstrates the implementation of a popup with buttons, where clicking the cancel button triggers a confirmation dialog. To make the popup disappear when clicked outside of it, the following event handling is employed: const popupRef = ...

A step-by-step guide on configuring data for aria's autocomplete feature

Currently, I am implementing aria autocomplete and facing an issue while trying to populate data from the server into the selection of aria autocomplete. I have tried setting the selected property of the aria autocomplete object, but it doesn't seem t ...

Using ngFor to Filter Tables in Angular 5

Are you in the midst of implementing multiple data filters in an Angular Application that displays data using a Table and ngFor? You may have explored different methods such as using Pipe in Type Script, but discovered that it is not recommended accordin ...

Assistance required for setting a value in a mat-select using Angular

Could really use some assistance resolving the issue with mat-select I'm aiming to establish the initial values by utilizing the following code snippet: orders: Order[] = [{"dish":"steak-0"},{"dish":"tacos-2" ...

Is the user's permission to access the Clipboard being granted?

Is there a way to verify if the user has allowed clipboard read permission using JavaScript? I want to retrieve a boolean value that reflects the current status of clipboard permissions. ...

Autodesk Forge serves as a hub for hosting dependencies on a nearby server

Our company has implemented an Angular/TypeScript version of the Forge Viewer, currently loading dependencies from Autodesk's server. To ensure these files are always accessible to our customers, we want to host them on our own servers. However, attem ...

Exploring the TypeScript compiler API to read and make updates to objects is an interesting

I'm delving into the world of the typescript compiler API and it seems like there's something I am overlooking. I am trying to find a way to update a specific object in a .ts file using the compiler API. Current file - some-constant.ts export co ...

TypeScript: defining a custom type with a collection of properties following a consistent pattern

I am looking for a way to create a type that can accommodate any number of properties following a predefined pattern, like so: type Values = { id: number; id1?: number; id2?: number; id3?: number; // ... somethingElse: string; anotherOne: num ...

Deleting a parent item along with its child elements in the ngrx state management library

I am currently exploring ngrx store and grappling with where to place my logic, specifically whether looping through an array should be handled in the reducer or the component. I have an array of objects called Item that need to be manipulated - particular ...