Encountered an error while trying to access the 'touched' property of undefined within Angular6 reactive forms

When attempting to validate my page, I encountered an error stating 'Cannot read property 'touched' of undefined'. Can someone please assist me with this code? Also, feel free to correct any mistakes you may find.

Here is the HTML code:

<div class="container pt-4">
    <form [formGroup]="goalForm" (submit)="submit()">
        <div class="card">
            <div class="card-header">Sub Goals</div>
            <div class="card-body" formArrayName="subgoals">
                <div *ngFor="let goal of goalForm.controls.subgoals.controls; let i=index">
                    <div [formGroupName]="i" class="row">
                        <div class="form-group col-sm-3">
                            <label for="name">Criteria Name *</label>
                            <input class="form-control" formControlName="criteria_name" type="text" 
                                    id="criteria_name" name="criteria_name" 
                                    placeholder="Criteria Name">
                            <span class="text-danger" *ngIf="goalForm.controls['criteria_name'].touched 
                                    && goalForm.controls['criteria_name'].hasError('required')">
                                    Criteria Name is required! </span>
                        </div>                            
                        <div class="form-group col-sm-3">
                            <label for="weightage">Criteria Weightage *</label>
                            <input class="form-control" formControlName="criteria_weightage" type="number" 
                                    id="criteria_weightage" name="criteria_weightage" 
                                    placeholder="Criteria Weightage">
                            <span class="text-danger" *ngIf="goalForm.controls['criteria_weightage'].touched 
                                    && goalForm.controls['criteria_weightage'].hasError('required')">
                                    Criteria Weightage is required! </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>     
    </form>
</div>

kpa-goal.component.ts:

 ngOnInit(){
        this.goalForm = this.fb.group({
            subgoals :this.fb.array([
              this.initgoal(),
            ])
          });
    }
    initgoal(){
        return this.fb.group({
          criteria_name: [null,Validators.compose([Validators.required])],
          criteria_weightage: [null,Validators.compose([Validators.required])]
          });
    }

Answer №1

Within your FormGroup, there was actually a FormArray named subgoals where the two fields, criteria_name and criteria_weightage, were nested inside. To access these fields, you needed to traverse through the subgoals before reaching them.

Here is the relevant HTML code snippet:

<div class="container pt-4">
        <form [formGroup]="goalForm" (submit)="submit()">
            <div class="card">
                <div class="card-header">Sub Goals</div>
                <div class="card-body" formArrayName="subgoals">
                    <div *ngFor="let goal of goalForm.controls.subgoals.controls; let i=index">
                        <div [formGroupName]="i" class="row">
                            <div class="form-group col-sm-3">
                                <label for="name">Criteria Name *</label>
                  <input class="form-control" formControlName="criteria_name" type="text" 
                          id="criteria_name" name="criteria_name" 
                          placeholder="Criteria Name">
                          <span class="text-danger" *ngIf="goalForm.controls.subgoals.controls[0].controls.criteria_name.touched && goalForm.controls.subgoals.controls[0].controls.criteria_name.errors?.required" >
                          Criteria Name is required! 
                          </span>
              </div>                            
              <div class="form-group col-sm-3">
                  <label for="weightage">Criteria Weightage *</label>
                  <input class="form-control" formControlName="criteria_weightage" type="number" 
                          id="criteria_weightage" name="criteria_weightage" 
                          placeholder="Criteria Weightage">
                          <span class="text-danger" *ngIf="goalForm.controls.subgoals.controls[0].controls.criteria_weightage.touched && goalForm.controls.subgoals.controls[0].controls.criteria_weightage.errors?.required" >
                          Criteria Weightage is required!
                          </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>     
    </form>
</div>

You can view a complete working demo on stackblitz here.

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

Assuming control value accessor - redirecting attention

import { Component, Input, forwardRef, OnChanges } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'formatted-currency-input', templateUrl: '../v ...

I noticed that while my shareService is effectively sending values in Angular 2, I encounter an issue where my other components are displaying default values instead

I'm in the process of developing an application using angular 2. I have a UserService that sends a value to other components indicating whether a user is logged in or not, and it's working correctly in terms of data transmission. The issue I&apos ...

Ways to extract a specific value from a geojson object using the key name

After making a call to the back-end, I retrieved the below geojson data in the 'data' object. However, when trying to access the values of the 'type' and 'features' keys within the geojson, I encountered difficulties. data["g ...

Display an icon within an HTML element when the content inside it exceeds its boundaries

Looking to display a copy to clipboard icon when the content inside a div overflows I am using ngFor to iterate through four divs, and if any of those divs is overflowing, I want to show an icon specific to that respective div. <div *ngFor div of Four ...

There are occasional instances in Angular 6 when gapi is not defined

I am currently developing an app with Angular 6 that allows users to log in using the Google API. Although everything is working smoothly, I encounter a problem at times when the 'client' library fails to load and displays an error stating gapi i ...

Angular 8 seems to be disregarding SetTimeout

When executing the following code snippet: this.logger.warn('start'); setTimeout(() => {},3000); delay(3000); this.logger.warn('start2'); The output displays enter image description here Blockquote: ngx-logger.js:596 2020-11-19T13 ...

"Using Spyon with the returnValue() method will run the original function, but without the expected

Hello fellow developers, I've been immersing myself in unit testing tutorials lately. However, I've encountered a problem while trying to perform unit tests on an HTTP call example. When I test the function inside my component, it returns the ori ...

What is the best approach when one property of a typescript class relies on the values of two others?

Currently, I have a TypeScript class within an Angular application that consists of three properties. The first two properties can be changed independently using [(ngModel)]. However, I am looking for a way to set the third property as the sum of the first ...

"Create a React Bootstrap Alert component with a dismissible button feature that is

I'm trying to add an "X" button to dismiss an alert on my website, but the bootstrap style isn't working properly. I've attempted setting the closeLabel to empty string, but it hasn't resolved the issue The desired outcome is: Below i ...

Display additional json elements as you scroll down

The total number of JSON objects is 100. Initially display the first set of 20 objects. As you scroll down, the next 20 objects will be shown. This process continues until all 100 objects have been displayed. ...

What is the best method for retrieving the complete path of a FormControl in Angular versions 4 and above

Is there a way to obtain the complete path of a FormControl in Angular 4+? Below is my reactive form structure: { name: '', address: { city: '', country: '' } } I urgently require the full path o ...

There was an unhandled exception that occurred due to a missing file or directory with the lstat error on 'D:a1s ode_modulesquill'

ngx-quill is causing issues in production, any suggestions? I am currently using "ngx-quill": "^13.4.0", but it is unable to find Quill on my server even though it works locally. The problem persists in the pipeline... An unhandled exception has occurred ...

Having trouble displaying ng-bootstrap toast using an interceptor or constructor in any Angular component. However, it functions properly when triggered by a button click

Is there a way to display toast notifications using an interceptor in Angular? I have a function in my toastService that works perfectly fine when called in a component, and even within the interceptor, the toasts array gets filled. However, the toast noti ...

Is there a method for executing ng-serve alongside expressjs?

I am currently following an Angular6/Express tutorial. In the tutorial, they utilize the following scripts: "scripts": { "ng": "ng", "start": "ng build && node ./bin/www", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e ...

Utilizing Vue and Typescript for efficient dependency injection

After attempting to use vue-injector, I encountered an issue as it was not compatible with my version of Vue (2.6.10) and Typescript (3.4.5). Exploring other alternatives, there seem to be limited options available. Within the realm of pure typescript, t ...

Encountering issues with managing CometD channels within Angular 2

After dabbling in Angular2 and Typescript, I decided to challenge myself by creating an application using plain javascript with the CometD library. The goal of this app was to retrieve data from a CometD channel and present it to the user in some way. So, ...

What is the best way to send {...rest} properties to a text field in react material?

When using a material textfield inside a wrapper component and passing the remaining props as {...otherprops} in a JavaScript file, everything works fine. However, when attempting to do the same in TypeScript, an error occurs. const TextFieldWrapper = (pro ...

When utilizing a generic type with a class, type T fails to meet the specified constraint

export type ExtractType<T extends Array<{ name: Array<string>, type: keyof TypeMapping }>> = { [K in T[number]['name'][0]]: TypeMapping[Extract<T[number], { name: K }>['type']] } export class CommandLineParse ...

Experiencing difficulty when trying to link control with form in Angular Reactive forms

I am currently working on Angular Reactive forms and facing an issue with binding form controls dynamically. Initially, I have a form array in form group, and then I push form groups into the form array to add form controls dynamically. However, I encounte ...

Angular: Utilize a Pipe in Template to Format and Display Time With a Mask

Within my code, there's a function called secondsToHms that serves to convert seconds into hours, minutes, and seconds: transform(seconds: number): string { const minutes = Math.floor(seconds / 60); //minutes const secs = seconds % 60; //seconds ...