Updating nested forms in Angular 4

The nested form structure I am working with is a 'triple level' setup: FormGroup->ArrayOfFormGroups->FormGroup

At the top level (myForm):

this.fb.group({
            name: '',
            description: '',
            questions: this.fb.array([])
        });

For the nested form array element 'questions':

this.fb.group({
            priority: ['1'],
            params: this.fb.group({parameter: ['']})
        });

The 'params' nested form group element contains key:value pairs of varying lengths.

When iterating through elements, I use the following ngFor loop:

<tr *ngFor="let questionConfigForm of myForm.controls.questions.controls; let i=index" [formGroupName]="i">
...
    <div *ngFor="let param of objectKeys(questionConfigForm.controls.params.controls)" formGroupName="params">
        <input type="text" [formControlName]="param">

However, I've encountered an issue: Changes made to fields in the first two levels of the form are immediately reflected in the corresponding form control values when {{myForm.value | json}} is checked. But changes to the 'params' controls do not update the overall myForm values unless a change is made in the related 'questions' form.

It seems like the 'param' form control captures input data but fails to trigger an update event. I'm unsure how to resolve this issue other than creating a custom function to handle the updates when there is a (change) event and patchValue in the form..

So, my question remains: How can I ensure that changes in 'params' controls update myForm without experiencing this unexpected behavior?

Update:

initQuestionConfig() {
    return this.fb.group({
        priority: ['1'],
        params: this.fb.group({parameter: ['']}),
    });
}

addQuestionConfig() {
    const control = <FormArray>this.myForm.controls['questions'];
    const newQuestionCfg = this.initQuestionConfig();
    control.push(newQuestionCfg);
}

Answer №1

Hooray, the issue has been resolved!

The root cause of the problem stemmed from my approach to cleaning up existing 'params'.

In order to remove all parameters from 'questions', I used the following code snippet:

const control = <FormArray>this.myForm.controls['questions'];
control.controls[index]['controls'].params = this.fb.group([]);

The culprit behind the glitches was the introduction of this new 'fb.group' instance.

Now, I am removing params individually while keeping the original formGroup instance intact, and it is functioning as expected:

const control = <FormArray>this.myForm.controls['questions'];
        const paramNames = Object.keys(control.controls[index]['controls'].params.controls);
        for (let i = 0; i < paramNames.length; i++) {
            control.controls[index]['controls'].params.removeControl(paramNames[i]);
        }

@MilanRaval, thank you once again for your assistance!

Answer №2

Consider using formArrayName and formGroupName in the following manner:

 <div formArrayName="exampleGroup">
            <div *ngFor="let member of exampleGroup.controls; let index=index">
                <div [formGroupName]="index">
                    <div class="container container-lg">
                        &nbsp;&nbsp;<label>
                            <input type="radio" formControlName="memberName" />                                
                    </div>
                </div>
            </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

"Exploring ways to reattempt a route request upon encountering the $stateNotFound event within AngularUI Router

Managing a large AngularJS application can be quite challenging when it comes to splitting it into functional modules. Currently, all the modules are loaded on the initial page load as they are bundled into a single JavaScript file. However, I am looking t ...

pick out particular values from an array

I have a question that may seem basic to some, but I'm curious about how to select specific elements from an array. In this case, I have an array with 100 elements: var cubes = [element1, element2, element3 ...] and I want to select elements 25-35. ...

Having trouble getting async and await to function properly

Why is my code not waiting for validation and running the else part immediately? Can you help me find the mistake? async validateBeforeSubmit(event) { await this.$validator.validateAll().then(result => { if (result) { ...

The data submitted from the form did not successfully get inserted into the database row

Currently, I am working on integrating a new product into my products database using ajax with php and mysql PDO. The form is located in a separate HTML file and gets loaded into a Bootstrap modal when the "add product" button is clicked. Below you can fi ...

Three.js experiences a memory leak issue

We are currently working on a single page app where users can switch between multiple Three.js apps. However, we have observed a continuous increase in memory usage by the tab. There is no memory leakage in our app and it appears that Three.js variables ar ...

ReactJS integration issue with Material Design Lite (import/require problem)

I am currently integrating Google's Material Design Lite with ReactJS. Specifically, I am utilizing the Spinner Loading and Text Field components from the MDL library. However, I am encountering an issue when switching routes using React Router. The ...

Enhance your application with realtime listeners that provide updates without the need to retrieve the entire database each time changes

Can you clarify the meaning of this Firestore concept? In order to keep your app's data up-to-date without having to retrieve the entire database every time there is an update, you can add realtime listeners. By adding these listeners to your app, ...

Scope problem in the next() function within an Observer's callback

Recently delving into Angular 9 and incorporating Angular Material for my project. Utilizing the MatSidenavContent component which includes a method named elementScrolled that returns an Observable. I managed to successfully implement the observable witho ...

Incomplete DOM elements in jQuery are like puzzles that need to be solved

My issue revolves around jQuery and manipulating DOM elements. I need a specific template setup, as shown below: var threadreply = " <li class='replyItem'>" + " <div class='clearfix'>" + ...

Updating interval time based on an external variable with jQuery

I have developed a JavaScript script where pressing a button triggers the continuous playback of an audio file. The audio, which is a 'beep' sound, serves as an alarm. The frequency at which the beep plays is determined by a setting located on a ...

Strategies for avoiding the issue of multiple clicks on a like button while also displaying an accurate likes

My latest project involves creating a Like button component that features a button and a likes counter text field. The challenge I am facing is that each time I click on the button, it toggles between like and dislike states. However, if I rapidly press ...

What could be causing my jQuery switch not to function on the second page of a table in my Laravel project?

Having an issue with a button that is supposed to change the status value of a db column. It seems to only work for the first 10 rows in the table and stops functioning on the 2nd page. I'm new and could really use some help with this. Here's the ...

Could you provide the parameters for the next() function in Express?

Working with Express.js to build an API has been a game-changer for me. I've learned how to utilize middlewares, handle requests and responses, navigate through different middleware functions... But there's one thing that keeps boggling my mind, ...

Looking to customize session data for my online game within the same interface

I have successfully coded a game called Ninja Gold using PHP with CodeIgniter. The game works by setting session variables (Gold and Activities) when the index page loads if they are not set already. Each location clicked adds a certain amount of gold to t ...

Having trouble downloading the compression webpack plugin using npm, as it keeps throwing an error

Hey there, this message pops up when attempting to execute the following command: npm install compression-webpack-plugin Here is the accompanying error: `PS D:\phaser games\game-slot-machine> npm install compression-webpack-plugin npm ERR! ...

Is there a way to automatically refresh a page as soon as it is accessed?

My goal is to create a page refresh effect (similar to pressing Command+R on Mac OS) when navigating to a certain page. For instance: Currently, when I navigate from "abc.com/login" to "abc.com/dashboard" after successfully logging in, the transition occ ...

Managing JavaScript with Scrapy

Spider for reference: import scrapy from scrapy.spiders import Spider from scrapy.selector import Selector from script.items import ScriptItem class RunSpider(scrapy.Spider): name = "run" allowed_domains = ["stopitrightnow.com"] start_urls = ...

What is the solution for fixing the '$ not defined error' in a .js file with $ajax code?

var example = document.createElement("SCRIPT"); example.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"; var nodeScript= document.createTextNode("function test() {console.log('test message');$.ajax({ type: \"POST&bs ...

extract the ng-model data and send it to an angular directive

In my current project, I have a specific situation where there are multiple text-boxes and when any of them is clicked, the corresponding ng-model should be displayed in the browser console. To achieve this functionality, I came up with the following Angul ...

The "if" statement carries out the identical action each time it is executed

Despite my efforts to toggle the value of the turn variable every time the if statement runs, I keep encountering the same outcome. It appears that turn consistently evaluates as 2. Below is the code snippet in question: $(function() { var turn = 2; ...