What is the best way to access this nested array in order to display my <input> field?

I am currently working on displaying an input field for 'levels'. The ultimate goal is to have an add button that will allow users to create multiple levels. Each learningGoal should have its respective levels created before the learning goals are finalized. Here is an example of how the json should be structured:

{
  "name": "name rubric",
  "learningGoals": [
    {
      "description": "learning goal description",
      "levels": [
        {
          "name": "level name",
          "criteras": []
        },
        {
          "name": "level name",
          "criteras": []
        }
      ]
    }
  ]

Currently, the 'levels' section is empty.

<form [formGroup]="rubricForm">
  <ng-template matStepLabel>Naam & Niveaus</ng-template>

  <mat-form-field>
    <input matInput placeholder="Naam" formControlName="name">
  </mat-form-field>

  <div formArrayName="learningGoals">
    <div *ngFor="let learningGoal of learningGoals().controls; let i = index" [formGroupName]="i">
      <div formArrayName="levels">
        <div *ngFor="let level of levels?.controls; let j = index" [formGroupName]="j">
          <mat-form-field>
            <input matInput placeholder="Naam" formControlName="name">
          </mat-form-field>
        </div>
      </div>
    </div>
  </div>


</form>

This is my TypeScript code:

rubricForm: FormGroup
constructor(private fb: FormBuilder) {
  this.rubricForm = this.fb.group({
    name: ["", Validators.required],
    learningGoals: this.fb.array([
      this.initLearningGoal()
    ])
  });
}

initLevel() {
  return this.fb.group({
    name: "",
  });
}

initLearningGoal() {
  return this.fb.group({
    description: "",
    levels: this.fb.array([
      this.initLevel()
    ])
  });
}

rubric(): FormArray {
  return this.rubricForm.get("rubric") as FormArray;
}
learningGoals(): FormArray {
  return this.rubricForm.get("learningGoals") as FormArray;
}

get levels(): FormArray {
  return this.learningGoals()
    .get('levels') as FormArray;
}

I attempted to remove the for loops but encountered the following error:

ERROR Error: Cannot find control with path: 'learningGoals -> levels'.

Therefore, it seems I have to include the form group within the loop. Any assistance would be greatly appreciated!

Answer №1

This issue was resolved by implementing the following solution:

levels(i: number): FormArray {
    const learningGoal = this.learningGoals.at(i) as FormGroup;
    return learningGoal.get('levels') as FormArray;
  }

Additionally, I utilized the code snippet below:

<div formArrayName="learningGoals">
    <div *ngFor="let learningGoal of learningGoals.controls; let i = index" [formGroupName]="i">
      <div formArrayName="levels">
        <div *ngFor="let level of levels(i).controls; let j = index" [formGroupName]="j">
          <mat-form-field>
            <input matInput placeholder="Naam" formControlName="name">
          </mat-form-field>
          <button mat-icon-button (click)="deleteLevel(i, j)">
            <mat-icon>delete</mat-icon>
          </button>
        </div>
        <button mat-icon-button (click)="addLevel(i)">
          <mat-icon>add</mat-icon>
        </button>
      </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

Every time I attempt to use interpolation in Angular 11, the result ends up being displayed as plain text on

I'm a beginner in Angular and I recently attempted my first code following a tutorial. When running this code on a live server using port 5500, I encountered an issue with interpolation. <h1>{{title}}</h1> The result on the webpage displa ...

Ways to increase the number of responses in an Express app after the initial response

In order to comply with the Facebook messenger API requirements, a 200 response must be sent immediately upon receiving the webhook request on my server, within 20 seconds. However, this process may take longer than the execution time of other middleware f ...

Modifying values in a reactive form does not function as expected for dropdown selections

I'm currently working on a project in Angular2 and I am facing an issue with setting the (change) event in a select element inside a reactive form. Unfortunately, it does not seem to be working. What steps should I take to resolve this? Below is the ...

Asyncronous calls in Angular involve executing tasks without

The issue seems to be related to the timing of updates for the controlSelected and isAssessmentDataLoading variables. The updateQuestions() method is invoked within the ngOnInit() method, which is triggered when the component is initialized. However, the ...

It seems that there is an issue with Ionic v4 and Angular when trying to retrieve the inner text of ion-slide elements in loop

I have a set of statuses displayed in <ion-slide> using the *ngFor directive to loop through a specified array: status: string[] = [ 'Active', 'Inactive', 'Ended' ]; @ViewChild('slideWithNav') slides: Io ...

What steps can I take to enhance the quality of my PDF files? Currently, I am utilizing Jspdf in conjunction with html

My current challenge involves generating a PDF file from my application. Although I am able to create a PDF, the quality is not up to par. When I download the PDF, I notice some discrepancies in text quality. While it's not terrible, it's also n ...

The powerful combination of Angular 6, NodeJS, and MongoDB creates a

Hi there. I've been searching around but couldn't find a solution to my problem. There are two similar unanswered questions. I'm new here, so any help with my final project would be greatly appreciated. After running ngForm, I encountered a ...

It takes two clicks for the text to change on the button in Angular

As a newcomer to angular, I am working on a quiz application where I've encountered an issue. When I click a button, it requires two clicks to function properly. The first click works fine, but subsequent clicks on the next and back buttons need to be ...

The correct method for recording a personalized directive with added functionality using the then function

Here's a full Typescript Cypress project. Encountering an error while trying to use the custom command below: Usage: cy.restGetUserId(userEmail).then(userId => { //do something with userId }); Custom command: Cypress.Commands.add ...

What is the best way to include type within a nested object?

How should I properly define types for a nested object structured like the example below? const theme: DefaultTheme = { color: { primary: '#5039E7', secondary: '#372E4B', heading: '#4D5062', }, ...

Managing the activation and deactivation of a form based on value modifications

I have a formgroup with interconnected formcontrols where each control is enabled only if the previous one is filled. Additionally, if a control is cleared, all subsequent controls should also be cleared and disabled. To illustrate this use case, I create ...

The functionality to close a Mat dialog is not functioning properly on Angular 11 with Material 11

I am trying to close the dialog by calling the close function of MatDialogRef instance, but unfortunately it is not working as expected. Within my ShareModule, there are components like HeaderCompose and LoginComponent. The HeaderComponent utilizes the Lo ...

Troubleshooting a cross-component property problem involving a fetch request within a subscription

My current objective is to utilize ActivatedRoute parameters to make a fetch request and update a class property with the fetched data. Progress has been made on making the request, but I am facing difficulties in getting the fetched data to the specific c ...

Utilize AngularJS directives within an Angular component for enhanced functionality

I'm currently in the process of enhancing an angularjs directive to integrate it into my angular component. I have successfully set up the hybrid (ng1 + ng2) environment and have also managed to inject angularjs services into Angular and utilize them ...

Popover disappears when scrolling the page, but its position remains constant in Angular 4+

After clicking on an icon, a popover appears. I've noticed that the popover has a delay set, but when I scroll, the popover also moves along with it. Is there a way to keep the popover in place and not have it affected by scrolling? <md-badge cla ...

Retrieving the attribute key from a dynamically typed object

Having this specific interface structure: interface test { [key: string]: string } along with an object defined as follows: const obj: test ={ name: 'mda', telephone: '1234' } Attempting to utilize this object in a variab ...

Revamping an npm package on GitHub

Currently, I am managing a project that has gained popularity among users and has received contributions from multiple individuals. The next step I want to take is to convert the entire library into TypeScript, but I am unsure of the best approach to ach ...

Encountering a timeout issue with the Sinch API within an Angular 2 project during the onCallProgressing

We successfully integrated Sinch into our angular 2 web application. Most functionalities are working perfectly, except for the user calling feature using the sinch phone demo. When the application is in the foreground, the call rings and connects withou ...

Learn how to trigger an event or API call in Angular 8 when the browser is closed with the help of HostListener

I am facing the challenge of calling a simple websocket closure API when the browser is closed in my project. I attempted to utilize HostListener, but unfortunately it did not work as expected. You can find the code snippet below: https://stackblitz.com/ ...

Creating dummy objects from a specific data type in Typescript for the purpose of testing

I'm exploring ways to streamline the creation of mock data for unit testing within an Angular solution. Currently, I am defining interfaces such as: export interface ReferenceDataItemCommon { codeDescription?: string; code: string; deleted?: boo ...