Groups of FormControls can be created using Formgroups and Form

After receiving data from an API, I aim to build a reactive form with a parent form and multiple child forms. The data that needs to be displayed in the form has the following structure:

    data{
    "extraInformation": false
    "cars": [
    {
     "Id": 48,  
    "Period": { 
    "Start": null, 
    "End": null }, 
    "Rentalstats": null, 
    "Reason": null 
    } 
    ]
    }

How can I achieve this? This is what I have attempted so far:

this.form = this.formBuilder.group({

    extraInformation: [this.data.ExtraInformation, [Validators.required]],
    cars: this.fb.array([this.addDetailFormGroup()]),
});

addDetailFormGroup() {
  this.form = new FormGroup({
    Reason: new FormControl(this.data?.cars?.Reason, Validators.required),
    Rentalstats: new FormControl(this.data?.cars?.Rentalstats, Validators.required),
    Period: new FormGroup([this.initListFormGroup()]),
  });
  initListFormGroup() {
    return new FormGroup({
      Start: new FormControl(this.data?.cars?.Period?.Start, Validators.required),
      End: new FormControl(this.data?.cars?.Period?.End, Validators.required),
    });
  }

However, I am encountering an issue where I get a "Cannot read properties of undefined (reading 'Start')" error.

Any assistance on this matter would be greatly appreciated.

Answer №1

It appears that your code is not ready for compilation due to several errors:

  1. Attempting to reassign the FormGroup instance with form controls like Reason, Rentalstats, and Period will overwrite the original FormGroup containing extraInformation and the cars array.

  2. Based on the provided data, accessing this.data?.cars as an array means you cannot directly reference fields like

    Reason</code. To properly handle this, you need to iterate through each element in the <code>cars
    array, creating a new FormGroup for each element and adding it to the cars FormArray.

  3. The way you are assigning the FormGroup instance to Period is incorrect. Your current code is attempting to assign a FormGroup to a FormGroup control under Period.

  4. Declaring the initListFormGroup method inside the addDetailFormGroup method is not the proper approach. It should be declared outside of that method.

The method names used to create the FormGroup are not clear or meaningful. Consider using names like initCarFormArray and initPeriodFormGroup for improved readability.

Below is an example of the component code to create the form, its nested FormArray, and

FormGroup(s):</p>
<pre><code>ngOnInit() {
  this.form = this.formBuilder.group({
    extraInformation: [this.data.extraInformation, [Validators.required]],
    cars: this.formBuilder.array([]),
  });

  this.initCarFormArray();
}

initCarFormArray() {
  for (let car of this.data.cars) {
    let carFormGroup = this.formBuilder.group({
      Reason: new FormControl(car?.Reason, Validators.required),
      Rentalstats: new FormControl(car?.Rentalstats, Validators.required),
      Period: this.initPeriodFormGroup(car.Period),
    });

    this.cars.push(carFormGroup);
  }
}

initPeriodFormGroup(period: any) {
  return new FormGroup({
    Start: new FormControl(period?.Start, Validators.required),
    End: new FormControl(period?.End, Validators.required),
  });
}

get cars(): FormArray {
  return this.form.controls.cars as FormArray;
}

To generate the form in HTML:

<div [formGroup]="form">
  <div>
    <span>ExtraInformation:</span>
    <input formControlName="extraInformation" />
  </div>

  <div formArrayName="cars">
    <ng-container *ngFor="let controls of cars.controls; let i = index;">
      <div [formGroupName]="i">
        <div formGroupName="Period">
          <div>
            <span>Start:</span>
            <input formControlName="Start" />
          </div>

          <div>
            <span>End:</span>
            <input formControlName="End" />
          </div>
        </div>

        <div>
          <span>Rentalstats:</span>
          <input formControlName="Rentalstats" />
        </div>

        <div>
          <span>Reason:</span>
          <input formControlName="Reason" />
        </div>
      </div>
    </ng-container>
  </div>
</div>

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

Is there a way to programmatically reselect a checkbox in Angular if it has been previously unselected?

I need to ensure that a checkbox remains checked, even if a user tries to uncheck it. I am using Angular 7 for this task. Here is a snippet of the template code: type="checkbox" [(ngModel)]="CheckBoxValue" (ngModelChange)="onChangeCheckBox(Check ...

Issue with arrow function not being invoked in a React TypeScript component's prop inside a function

My parent component holds a useState hook to determine if the mobile Nav is open or closed: const [showMobileMenu,setShowMobileMenu] = useState<boolean>(false);. To close the mobile menu, I created an arrow function and passed it down to a child comp ...

Angular application's HTML Canvas unexpectedly changes to a black color when I begin drawing

Currently, I am developing an Angular application in which users can draw text fields on PDF pages. To achieve this functionality, I have integrated the ng2-pdf-viewer library and created a PDF page component that incorporates an HTML canvas element. Howe ...

Issue with secondary router outlet nested within primary router outlet not functioning properly

I've set up my router outlets like this, with the secondary router outlet nested inside the primary one. However, when I attempt to use routerLink to display the roster.component.html, I keep encountering the same error message no matter what configur ...

The table on the page shifts position when viewed on different devices, sometimes not remaining between the header and footer

Here is a link to see how my page looks with the header, table, and footer: https://i.sstatic.net/U6tdO.png If you want to see how it looks when responsive (with smaller width), check out this link: https://i.sstatic.net/zsGkc.png I have encountered 2 ma ...

Troubleshooting problem with Webpack and TypeScript (ts-loader)

Seeking help to configure SolidJS with Webpack and ts-loader. Encountering an issue with return functions. What specific settings are needed in the loader to resolve this problem? import { render } from "solid-js/web"; const App = () => { ...

Is it possible for Azure static web apps to utilize Azure App Service as their backend?

Is it possible to have a Azure static web app communicate with an existing Azure app service in order for users to download a file generated by the app service? ...

Tips on providing validation for either " _ " or " . " (select one) in an Angular application

I need to verify the username based on the following criteria: Only accept alphanumeric characters Allow either "_" or "." (but not both) This is the code snippet I am currently using: <input type="text" class="form-control" [ ...

Why is the Angular6 HttpClient Post method failing when Postman shows success?

Here is the code for my postmethod: postMetadata(titleParam, rankParam) { let headers = new HttpHeaders(); headers = headers.append( "Authorization", "Bearer " + this.adalService.userInfo.token ); headers = headers.append( ...

Changing the environment variable in an Angular application with user input

I'm currently in the process of developing an angular application that interacts with a REST API on the backend server. The URL for this server is currently set as an environment variable like so: export const environment = { production: false, lo ...

Initializing the ngOnInit function with 'this' keyword

I've encountered a scope issue where the lines "this.catVotes = catData" are within another function, preventing me from directly assigning it to "catVotes: Number;" Any suggestions on how I can overcome this challenge? catVotes: Number; dogVotes: N ...

Validating nested objects in YUP with the potential for zero or multiple properties present

I am currently working on setting up yup validation for this object: placements: { 3: {}, 5: {}, 6: {0: 'D17'}, 7: {}, 8: {}, 9: {}, 10: {}, 11: {}, } The challenge I am facing is that an entry like 3: {} can be empty, and that's totally fi ...

What is the best way to hide the back arrow in Cordova UWP for Ionic 4?

I am currently developing a Windows 10 (UWP) application using Ionic 4 (Angular). I want to remove the back arrow from the interface: Example of back arrow I have attempted various solutions, such as implementing in the app.component constructor with in ...

Exploring the Global Reach of Angular 9

I have been working on updating our current app to implement internationalization using the new approach in Angular 9. Below is how I set it up in the angular.json file: { ... "projects": { "viewer": { ... "i18n": { "sourceLocale": ...

Enhance user interaction in Angular 13 by animating a selected element using just one animation block

I am currently working on a one-page website project to enhance my Angular skills, and I'm facing a challenge with animating multiple DOM elements using a single animation. Defining the animation for each element individually seems like a cumbersome a ...

Is the component experiencing issues with its style functionality?

I am attempting to add CSS styles to app.component.ts using the :host property, but I am not seeing the desired results. The CSS is being applied, but not correctly. .ts export class AppComponent { title = "Default Title" data = 'This is defaul ...

"Optimize the appearance of group headers and items in Angular select style

I have integrated the ng-select library into my Angular project to create a dropdown menu. Here is an example of how I am using it: <ng-select [items]="flattenedSelectList" bindLabel="displayName" placeholder="Select speci ...

Mastering the Art of Concise Writing: Tips to

Is there a way to write more concisely, maybe even in a single line? this.xxx = smt.filter(item => item.Id === this.smtStatus.ONE); this.yyy = smt.filter(item => item.Id === this.smtStatus.TWO); this.zzz = smt.filter(item => item.Id == ...

Discovering the origins of the node.js native modules and delving into the intricacies of typed modules

I am using a Windows machine and trying to locate where node fetches the source code for native modules. On my system, I can only find the @types file which contains "Typed Only" modules. For example, the module "assert" is available in the master/lib fold ...

Encountering an unexpected token error while trying to compile a Typescript file to Javascript, even though it had previously worked

In my Typescript project, I usually run it using "ts-node". $ ts-node .\src\index.ts it works =) However, I wanted to compile it to Javascript, so I tried the following: $ tsc $ node .\src\index.js Unfortunately, I encountered the f ...