Incorporate interactive elements into the form

I'm facing an issue with adding 2 dynamic input fields to my form.

<div formArrayName="details">
  <div *ngFor="let detail of _detailRowNumber; index as i">
    <mat-form-field appearance="fill">
      <mat-label>Label of a detail</mat-label>
      <input id="detail-label" matInput type="text" [formControlName]="i">
    </mat-form-field>

    <mat-form-field appearance="fill">
      <mat-label>Description of a detail</mat-label>
      <input id="detail-description" matInput type="text" [formControlName]="i">
    </mat-form-field>

    <button type="button" *ngIf="_detailRowNumber.length > 1" (click)="decreaseDetailRow(detail)" mat-fab color="primary" aria-label="Remove a new row from the detail list">
      <mat-icon>remove</mat-icon>
    </button>

    <button type="button" (click)="increaseDetailRow(i)" mat-fab color="primary" aria-label="Add a new row to the detail list">
      <mat-icon>add</mat-icon>
    </button>
  </div>
</div>
_detailRowNumber: Array<number> = [0];

details: FormGroup = new FormGroup({
  details: new FormArray([
    new FormControl('label'),
    new FormControl('description')
  ])
})

fields: string[] = [];
formMain = this.fb.group({
  details: this.details
});

increaseDetailRow(index: number): void {
  this._detailRowNumber.splice(++index, 0, Date.now());
}

decreaseDetailRow(index: number): void {
  this._detailRowNumber = this._detailRowNumber.filter((item) => item != index);
}

However, I encounter the following error:

ERROR Error: Cannot find control with path: 'details -> 0'

This is the result I expect:

{
  details: [
    { label: "My label 1", description: "My description 1" },
    { label: "My label 2", description: "My description 2" }
  ]
}

How can I achieve my desired outcome?

Answer №1

To achieve the desired outcome, ensure that your details form control is a FormArray containing FormGroups rather than a FormArray with FormControls.

<div [formGroup]="formMain">
  <div formArrayName="details">
    <div *ngFor="let detail of _detailRowNumber; index as i">
      <ng-container [formGroupName]="i">
        <mat-form-field appearance="fill">
          <mat-label>Label of a detail</mat-label>
          <input
            id="detail-label"
            matInput
            type="text"
            formControlName="label"
          />
        </mat-form-field>

        <mat-form-field appearance="fill">
          <mat-label>Description of a detail</mat-label>
          <input
            id="detail-description"
            matInput
            type="text"
            formControlName="description"
          />
        </mat-form-field>

        <button
          type="button"
          *ngIf="_detailRowNumber.length > 1"
          (click)="decreaseDetailRow(detail)"
          mat-fab
          color="primary"
          aria-label="Remove a new row from the detail list"
        >
          <mat-icon>remove</mat-icon>
        </button>

        <button
          type="button"
          (click)="increaseDetailRow(i)"
          mat-fab
          color="primary"
          aria-label="Add a new row to the detail list"
        >
          <mat-icon>add</mat-icon>
        </button>
      </ng-container>
    </div>
  </div>
</div>
ngOnInit() {
  this.formMain = this.fb.group({ details: this.fb.array([]) });
  this.addDetailsFormGroup();
}

addDetailsFormGroup() {
  (this.formMain.controls.details as FormArray).push(
    new FormGroup({
      label: new FormControl('label'),
      description: new FormControl('description'),
    })
  );
}

increaseDetailRow(index: number): void {
  this._detailRowNumber.splice(++index, 0, Date.now());
  this.addDetailsFormGroup();
}

decreaseDetailRow(index: number): void {
  this._detailRowNumber = this._detailRowNumber.filter(
    (item) => item != index
  );

  (this.formMain.controls.details as FormArray).removeAt(index);
}

View Demo on StackBlitz

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

The API endpoint code functions perfectly in Express, but encounters an error when integrated into Next.js

Express Code: app.get('/', async (req, res) => { const devices = await gsmarena.catalog.getBrand("apple-phones-48"); const name = devices.map((device) => device.name); res.json(name); }) Nextjs Code: import {gsmarena} ...

Having trouble transferring captured images to Firebase storage

I am currently working on creating a small Ionic 2 application that is capable of capturing images using the camera and then uploading those images to Firebase storage. Additionally, I aim to store the URLs of the captured images in the Firebase database. ...

Attempting to ensure that Angular 2 delays rendering until the necessary data has finished loading

Looking to efficiently load multiple XML files before the initial rendering? Here's a configuration snippet from app.module.ts: import { DataProvider } from './xml-provider' export function dataProviderFactory(provider: DataProvider) { r ...

I'm receiving an error message stating "mongoose.connect is not a function" while attempting to establish a connection with mongoose. Can you help me troub

I'm a beginner in Node.js and I'm currently working on creating a node/express/mongoose server app using TypeScript. Below is my app.ts file: // lib/app.ts import express from 'express'; import * as bodyParser from 'body-parser&a ...

I will not be accessing the function inside the .on("click") event handler

Can someone help me troubleshoot why my code is not entering the on click function as expected? What am I missing here? let allDivsOnTheRightPane = rightPane.contents().find(".x-panel-body-noheader > div"); //adjust height of expanded divs after addi ...

Issue with webpack dev server not correctly generating output files to be included in index.html

Struggling to configure webpack and react with typescript without the complexity of CRA. The dev server isn't outputting files to index.html for viewing in the browser. I want to maintain a clean and simple structure, avoiding the multiple js scripts ...

Angular client encounters error "Access Control Check Fails for Preflight Request" when integrating with ASP.net Core SignalR

In my ASP.Net core server startup.cs file, I have the following code within the ConfigureServices method: services.AddCors(o => o.AddPolicy("CorsPolicy", builder => { builder .AllowAnyMethod() .AllowAnyHeader() ...

The message "In Angular, there is no such property as 'data' in the type '{ user: User; session: Session; error: ApiError; }'."

Here is my complete supabase.service.ts code: import { Injectable } from "@angular/core"; import { createClient, SupabaseClient, User } from "@supabase/supabase-js"; import { BehaviorSubject } from "rxjs"; import { envi ...

Adjust the selected value in real-time using TypeScript

Hey there, I've got a piece of code that needs some tweaking: <div> <div *ngIf="!showInfo"> <div> <br> <table style="border: 0px; display: table; margin-right: auto; margin-left: auto; width: 155%;"& ...

What is your approach to organizing the HTTP requests in your Angular 2+ application?

I'm looking for suggestions on how to better organize my API calls within my services. How have you structured your API calls? Do you centralize all API calls for the entire application in one dedicated service? Do you create an HTTP folder and sepa ...

There are a few steps to take in order to sort an array of objects by a

I want to organize and display data in a sortable table format javascript let dataList = [ { idx: number, name: string, btn: number, index: number }, { idx: number, name: string, btn: number, index: number }, { idx: number, name: string, btn: number ...

Is it possible for an uninitialized field of a non-null literal string type to remain undefined even with strict null checks in

It seems that there might be a bug in Typescript regarding the behavior described below. I have submitted an issue on GitHub to address this problem, and you can find it at this link. The code example provided in that issue explains the situation more clea ...

Creating a gradient background with the makeStyles function

Why is it that the background: 'linear-gradient(to right, blue.200, blue.700)' doesn't work within makeStyles? I just want to add a gradient background to the entire area. Do you think <Container className={classes.root}> should be rep ...

In TypeScript, how can we specify that a key is mandatory for an object but it can be referred to by two different names?

Essentially, I'm faced with a situation where I need to handle a style object that must contain either the maxHeight or height properties. If one of these properties is included, the other becomes unnecessary. Despite my efforts, I have been unable to ...

Unable to instantiate FormData with the constructor

Within my Angular application, I have a basic form setup like this: <form [formGroup]="loginForm" (submit)="login()"> <div id="container-credentials"> <input type="text" name="username" formControlName="username"> <input typ ...

Ensuring the accuracy of forms using third-party verification services

While working on an Angular form validation using an external service, I encountered a cannot read property of undefined error. The component contains a simple form setup: this.myForm = this.fb.group({ username: ['', [this.validator.username] ...

Hover over to reveal the button after a delay

I'm struggling with implementing a feature in my Angular code that displays a delete button when hovering over a time segment for 2 seconds. Despite trying different approaches, I can't seem to make it work. .delete-button { display: none; ...

Is there a way to turn off tsc pretty printing using the configuration file?

My typescript program is intentionally broken but I want to fix it. 12:17:23:~/hello $ cat hello.ts console.log("Hello World" 12:17:29:~/hello $ cat package.json { "dependencies": { "typescript": "^5.2.2" ...

Enhancing Selectpicker options in Angular using data fetched from a web service

Having trouble with updating a selectpicker element within a subscribe method. I've included the code snippets below: Here is my HTML code: <div class="form-group col-md-2 pull-right"> <label for="city">City</label> <select ...

Remove the package from the @types folder within the node_modules directory

I currently have the 'mime' library in my node_modules directory and I am looking to completely remove it from my project, along with its @types files. The reason for this is that the old mime package is not functioning correctly for me, so I wan ...