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

Tips for receiving @ mentions in PrimeNg Editor using Quill and quill-mention with Angular

Currently, I have been given the task of adding a mentions feature to our text editors. The editor I am working with is the PrimeNg Editor, built on Quill. After some research, I came across the package quill-mention, which appears to be a potential soluti ...

The ng build command encounters a failure (module cannot be found) when running in a docker environment on Ubuntu, while it successfully runs

I'm facing an issue that I can't quite pinpoint whether it's related to docker, Ubuntu, or node/npm. Here are all the details I have: Although there are known causes for this module error, none of them explain why it works on various Window ...

What is the correct way to define the onClick event in a React component?

I have been encountering an issue while trying to implement an onClick event in React using tsx. The flexbox and button are being correctly displayed, but I am facing a problem with the onClick event in vscode. I have tried several ideas from the stack com ...

Is it possible to generate a user profile using Firebase Cloud Functions and assign the user id as the document id?

I'm having trouble generating a user profile document in Firebase cloud functions using the user.uid as the doc id. Below is the script I am working with, but it keeps failing. I suspect there might be a syntax issue, so any suggestions would be great ...

Ways to eliminate the white background gap between pages on ionic

While developing an app using Ionic, I encountered a strange issue. Everything runs smoothly on a browser, but when testing the app on an Android 5 device, I noticed a white background appearing between pages. The app loads correctly with the custom splas ...

Exploring the @HostBinding argument in Angular directives

Need help grasping the concept behind the @Hostbinding argument: Snippet of the code: import { Directive, HostBinding } from "@angular/core"; @Directive({ selector: '[appDropdown]' }) export class DropdownDirective { @HostBinding(&apos ...

How to handle a property that is not found in a combined type in TypeScript?

In this scenario using TypeScript: interface EmotionsOkay { emotion: string; okay: "yap"; } interface EmotionsNotOkay { emotion: string; } type UndetereminedEmotion = EmotionsOkay | EmotionsNotOkay; const areYouOkay = (test: UndetereminedEmotion) =& ...

Incorporate a 'Select All' functionality into ion-select by adding a dedicated button

Looking for a way to set custom buttons on ion-select through interfaceOptions in ionic 4? HTML <ion-item> <ion-label>Lines</ion-label> <ion-select multiple="true" [(ngModel)]="SelectedLines" [interfaceOptions]="customAlertOption ...

When is the right time to develop a new component?

Exploring the strategy behind determining when to create a new component in a web application using angularjs / angular has been on my mind lately. It seems like this concept could apply to all component-based front end frameworks as well. I understand th ...

Add a new item to an array in Angular 2 when a click event occurs

I'm trying to add a new list item (which comes from an API) when a button is pressed, but I'm not sure how to do it. Can anyone provide some guidance? Here's the code: <ul> <li *ngFor="let joke of jokes">{{joke.value}}</li> ...

Unable to bring in an exported class from a TypeScript file

I have a TypeScript file named foo.ts that contains an exported class called "Foo" export default class Foo{ } I am attempting to import this class into another file within the same directory import {Foo} from './foo'; However, I am encounter ...

What improvements can I implement in this React Component to enhance its efficiency?

Seeking advice on improving the efficiency of this React Component. I suspect there is code repetition in the onIncrement function that could be refactored for better optimization. Note that the maxValue prop is optional. ButtonStepper.tsx: // Definition ...

Exploring methods to access specific values from an array containing multiple values using Lodash in Angular 4

Hey, I have an array that looks like this: [ 0: "Migration, MD" 1: "Lution, MD" 2: "Mover, MD" 3: "Dee" 4: "Prov10A" ] I would like to extract the values that contain the word "MD" in them. In other words, I want a result like this: [ 0: "Migratio ...

How to identify alterations in user input within Angular?

I need assistance with my search input functionality. I want to ensure that the this.searchProperties.emit is only triggered when the user interacts with the input field by touching it or making an input. The current issue is that the emit function gets ca ...

Declaration files for Typescript ESLint configurations

I've been researching this issue online, but I haven't been able to find any solutions. It could be because I'm not entirely sure what's causing the problem. What I'm trying to do is set a global value on the Node.js global object ...

What is the best way to pass the answerId in the action that I am dispatching, when the answerId is nested within an array object within another array object in

Reflect on the following: private listenToAnswerDeleted() { this.uiService.onGlobalEvent('ANSWER_DELETED').subscribe((response) => { this.store.dispatch(deleteAnswerAction({'answerId': })); }); } Upon receiving a respon ...

Angular2 - Issue with calling toPromise() method on this.http.get() function, as it is not recognized

I was following a tutorial on angular.io called Tour the Heroes, but instead of sticking to the tutorial I decided to make a real GET request for some JSON data. Here is a snippet of my code: private userUrl = 'https://jsonplaceholder.typicode.com ...

Error Message: "Module not found - Module TS2307 cannot be located

When I try to open a Typescript project in VSCode, I encounter the error message "ts2307 Cannot find module 'react' or its corresponding type declarations". However, everything works fine when I use WebStorm. The project was created using Create ...

When no values are passed to props in Vue.js, set them to empty

So I have a discount interface set up like this: export interface Discount { id: number name: string type: string } In my Vue.js app, I am using it on my prop in the following way: export default class DiscountsEdit extends Vue { @Prop({ d ...

What could be the reason for TypeScript throwing an error that 'product' does not exist in type '{...}' even though 'product' is present?

Structure of Prisma Models: model Product { id String @id @default(auto()) @map("_id") @db.ObjectId name String description String price Float image String createdAt DateTime @default(now()) updatedAt Da ...