Creating an array of Form Groups involves first initializing an empty array and then

Here is a JSON object that I need to create a reactive form based on. What steps should I take for the array portion specifically?

{
    "examName" : "java",
    "password" : "1234.com",
    "examCategory" : {
        "id" : 78
    },
    "examDetailSet" : 
        [ 
            {
                "questionCategory" : {"id" : 40},
                "section" : {"id" : 7},
                "numberOfQuestions" : 3
            },
            {
                "questionCategory" : {"id" : 41},
                "section" : {"id" : 8},
                "numberOfQuestions" : 6
            }
        ],
    "expiryHours" : 6
}

abc.component.ts

// The formGroup I have created
formdata = this.fb.group({
    examName: ['', Validators.required], password: ['', [Validators.required, Validators.minLength(3)]],
    examCategory: this.fb.group({
      id: [0, Validators.required]
    }),
    examDetailSet: new FormArray([
      new FormGroup({
        questionCategory: this.fb.group({
          id: [0, Validators.required]
        }),
        section: this.fb.group({
          id: [0, Validators.required]
        }),
        numberOfQuestions: new FormControl(['', Validators.required])
      })
    ]),
    expiryHours: [0, Validators.required]
});

abc.component.html

<form [formGroup]="formdata" (submit)="onSubmit()">
  <mat-dialog-content>
    <div class="row">
      <div class="col-md-6">
...
// Truncated for brevity

-pasted image link not available-
<p>I followed the instructions provided in the answer below but now I am encountering an issue stating that it can't locate the control within the <code>examDetailSet and its controls. Any assistance would be appreciated.

Answer №1

when working with a FormArray, it is important to not only use formArrayName but also iterate over controls using the *ngFor directive as shown below:

<span formArrayName="examDetailSet">
  <div class="row" *ngFor="let group of formdata.get('examDetailSet').controls;let i=index"
     [formGroupName]="i">
    <div class="col-md-6" formGroupName="questionCategory">
    ....
</span>

To avoid "type errors", it is recommended to create getters for the formArray like this:

get examDetailArray()
{
    return this.formdata.get('examDetailSet') as FormArray
}

Then you can use it in the *ngFor loop:

  <div class="row" *ngFor="let group of examDetailArray.controls;let i=index"
     [formGroupName]="i">

You can also use [formGroup]="group" instead of [formGroupName]="i" if you prefer.

Update on how to create a FormGroup and FormArray when dealing with an object:

It's best practice to have two separate functions, one for creating the form and another for creating the formArray.

createForm(data:any)
{
    data=data || {examName:null,
                  password:null,
                  examCategory : {
                    id:0
                 },
                 examDetailSet:null 
                 expiryHours:0
             } 
    return this.fb.group({
    // form fields here
});
 }

createGroup(data)
{
   data=data || {
                questionCategory:
                  {id : 0},
                section : {id : 0},
                numberOfQuestions" : 0
            }
  return this.fb.group({
        // form fields here
      })
}

By using the "map" function, we can easily convert each element of the array into a formGroup when creating the formArray.

formData=this.createForm(null)
//or if you has data
formData=this.createForm(myObject)

If you need to add an element to the array, you can do so like this:

(formData.get('examDetailSet') as FormArray.push(this.createGroup(null))

Answer №2

Utilizing FormArray in Angular is a great way to group AbstractControl objects in an array, similar to how a FormGroup groups them in an object.

For a detailed example, you can check out the following link -

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

Guide to iterating through different endpoints in a predetermined sequence

I am facing a challenge with testing various endpoints using different login credentials. When looping through the endpoints, the results are not appearing in the sequential order due to asynchronous nature. My goal is to iterate through each endpoint wit ...

challenges with template inheritance: when one template takes precedence over another

I have encountered an issue with my two HTML templates, login.html and signup.html. Both of these files inherit from the base.html file, but there seems to be a problem where one file is overriding the title and content of the other. So when I visit /login ...

Angular - Transform calendar dates to a lively green upon initial popup activation

I'm looking to customize my calendar so that all the dates in my list have a green background when the calendar is opened. ngOnInit(): void { this.roomService.getReservableDatesFromRoom(room.roomName).subscribe(data => { for (let i = 0; i ...

"An error occurred stating that _co.JSON is not defined in

During my attempt to convert an object into a string using the JSON method, I encountered an error upon loading my page: Error: _co.JSON is undefined The stacktrace for this error message is extensive and seems unnecessary to include at this point. Th ...

How to manipulate dates using Angular 2's date pipe to add or subtract hours

I am encountering an issue with the new Angular 2 Date Pipe. My date value is as follows: let myDate = '2017-01-31T17:53:36' When I use the Date Pipe to format it in the view like this; {{myDate | date: 'dd/MM/yyyy HH:mm' }} It dis ...

Which superclass does ReadonlyArray extend from?

Looking at this TypeScript code snippet: const arr: ReadonlyArray<string> = [ "123", "234" ]; arr.push("345"); An error is thrown by the TS compiler: Property 'push' does not exist on type 'ReadonlyArray<string>&apo ...

Guide to resolving the issue of DELETE error 404 not found in express.js

I enrolled in a MEAN Stack course and have been making progress. I can easily add new data and fetch existing data, but running into trouble when attempting to DELETE data. The error message reads as follows: "DELETE http://localhost:3200/posts/5e831685bf7 ...

Issue with Angular trackBy not functioning properly within a nested *ngFor loop

My component is similar to the following <div class="users-list" *ngIf="datasetPermission !== undefined"> <div *ngFor="let userpermission of datasetPermission; trackBy : trackByFn"> <span *ngFor="let user of userpermission.users"& ...

Exploring the directories: bundles, lib, lib-esm, and iife

As some libraries/frameworks prepare the application for publishing, they create a specific folder structure within the 'dist' directory including folders such as 'bundles', 'lib', 'lib-esm', and 'iife'. T ...

Issue with Angular2 wysiwyg component failing to submitThe Angular2

I'm currently in the process of familiarizing myself with angular2 by developing a sleek wysiwyg component. However, I seem to have reached an obstacle at this point. Below is the code I've been working on: The form that I am utilizing for testi ...

JavaScript - Modifying several object properties within an array of objects

I am attempting to update the values of multiple objects within an array of objects. // Using a for..of loop with variable i to access the second array and retrieve values const AntraegeListe = new Array(); for (let i = 0; i < MESRForm.MitarbeiterL ...

Using TypeScript to efficiently filter an Array by converting all values to lowercase

I have a custom array in TypeScript that needs to be filtered based on the city and job, with case-insensitivity as a requirement. array = [{ name: "Hardik", city: null, job: null }, { name: "John", city: "Ahmedabad", job: "IT" }, { name: "Margie", c ...

Issue encountered while attempting to package Azure project in Visual Studio 2015 Update1 due to difficulty copying Typescript files

Since upgrading to VS 2015 Update 1 (that includes Typescript 1.7) and Azure SDK 2.8, packaging my Azure application for deployment has become a challenge due to an error in the file path where the packager is attempting to copy the js output file: Erro ...

How to Update Angular 10 ESRI Map Layers Without Reloading the Entire Map

Recently, I successfully developed an Esri Map using Angular 10 where users can toggle different map layers by selecting from a group button. The input for selecting layers is an array, for example: ['0', '1', '2'], with each ...

Please ensure that the Angular Input field only allows for numbers to be entered, with the exception that the

My input should only allow numbers, with the exception of the first digit being zero. I have attempted to use regex in this directive, but it is not functioning as expected. import { Directive ,ElementRef, HostListener} from '@angular/core'; @Di ...

Extending Enums in Typescript: A Comprehensive Guide

How can you work with a list of constants or Enum? Here is an example: enum MyList { A, B } enum MyList2 { C } function process<T>(input:MyList | T):void { } process<MyList2>(123) // The compiler does not recognize that 123 ...

Angular 6 allows for the use of radio buttons to dynamically enable or disable corresponding fields

Here is the HTML code for a row containing radio button selections: <div class="form-row"> <div class="col-md-3 mb-3"> <div class = "form-group form-inline col-md-12 mb-3"> <div class="form-check form-check-inl ...

Getting the data from the final day of every month in a Typescript time-series object array

I am dealing with timeseries data retrieved from an API that consists of random dates like the following: [ { "id": 1, "score": 23, "date": "2023-08-30" }, { "id": 2, "score&qu ...

Showing Arrays in Angular on HTML Page

I have created an array that stores multiple arrays with 3 indexes each. An example of the structure looks like this: (3) [Array(3), Array(3), Array(3)] 0: (3) [199.4, 10.5, 19] 1: (3) [47.2, 2.1, 23] 2: (3) [133.6, 5.3, 25] In my HTML, I want to display ...

Preparing a component for evaluation

When I execute the app and load views using @useview('resources/panels/data-table-panel.html'), everything works fine. However, running a component test results in failure due to a 404 error caused by the html file not being found. After changin ...