Error encountered in Angular 18 Reactive Form: No FormControl instance is connected to the form control element named 'q1124'

In my Angular component, I have implemented a feature where a form is dynamically created and rendered using ReactiveFormsModule. Upon clicking the submit button, the data is posted and new questions are fetched to replace the old ones in the component.

The initial rendering works well when you first visit the page. However, after submitting the first question, the parent component sends new questions to be displayed in this component.

An error occurs stating: "

There is no FormControl instance attached to form control element with name: 'q1124'
". However, logging form.controls confirms that it does contain 'q1124'.

Here is the content of form.component.ts:


import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges }       from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { Question } from '../../../../shared/models/views-models/question-view';
import { getQuestionAnswers } from '../../../../shared/utils/helpers.util';
import { MatButtonModule } from '@angular/material/button';
import { MatCard } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

@Component({
  selector: 'app-survey-form',
  standalone: true,
  imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatCard, MatButtonModule,],
  templateUrl: './survey-form.component.html',
  styleUrl: './survey-form.component.scss'
})
export class SurveyFormComponent implements OnChanges {
  form: FormGroup = new FormGroup({});
  @Input() questions: Question[] = []
  @Input() currentState: string | undefined;
  @Input() previousState: string | undefined;
  @Output() dataEmitter: EventEmitter<any[]> = new EventEmitter<any[]>();

  constructor(private fb: FormBuilder, private cdr: ChangeDetectorRef) { }


  ngOnChanges(changes: SimpleChanges): void {
    if (changes['questions'] && changes['questions'].currentValue !== changes['questions'].previousValue) {
      this.form = this.createForm(this.fb, this.questions)
      this.cdr.detectChanges();
    }
  }

  submit() {
    if (this.form.valid) {
      const answers = getQuestionAnswers(this.form, this.questions)
      this.dataEmitter.emit(answers)
    }
  }

  createForm = (
    formBuilder: FormBuilder,
    questions: any[]
  ): FormGroup => {
    const group: { [key: string]: AbstractControl<any, any> } = {};

    questions.forEach(question => {
      group[question.id] = question.mandatory
        ? formBuilder.control('', [Validators.required])
        : formBuilder.control('');
    });
    return new FormGroup(group)
  }
}

This is the content of form.component.html:

<div class="form-container">
    <form [formGroup]="form" (ngSubmit)="submit()" class="input-form">
        @for (question of questions; track $index) {
        <input type="text" matInput [formControlName]="question.id" [required]="question.mandatory"
            placeholder="Type your answer here..." [id]="question.id">
        }
        @if (currentState) {
        <button type="submit" [disabled]="form.invalid" mat-flat-button>Next</button>
        }
    </form>
</div>

I have tried using different lifecycle hooks like ngOnAfterInit to address timing issues, and also included the ChangeDetectorRef for debugging purposes.

For further reference, here is a link to a Stackblitz mockup: https://stackblitz.com/edit/stackblitz-starters-4ewzry?file=src%2Fapp%2Fform-test%2Fform-test.component.ts

Answer №1

One issue arises when questions are assigned values prior to the creation of the form

To solve this, loop through form.controls using the keyvalue pipe

@for (control of form.controls|keyvalue; track $index) {
    <!--Make sure to use questions[$index].id instead of question-->
        <input type="text" matInput [formControlName]="questions[$index].id">
}

Remember to wait for the questions to be retrieved before proceeding

  ngOnChanges(changes: SimpleChanges): void {
    if (
      changes['questions'] &&
      changes['questions'].currentValue !== changes['questions'].previousValue
    ) {
      //Wrap in a setTimeout without any delay
      setTimeout(()=>{
        this.form = this.createForm(this.fb, this.questions);
      })
      this.cdr.detectChanges();
    }
  }

Check out stackblitz for more details

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

What is the process for creating a new Object based on an interface in Typescript?

I am dealing with an interface that looks like this: interface Response { items: { productId: string; productName: string; price: number; }[] } interface APIResponse { items: { productId: string; produc ...

Issue with ngx-bootstrap custom typeahead feature malfunctioning

I'm facing an issue while trying to develop a customized typeahead feature that is supposed to search my API every time the user inputs something, but it's not functioning as expected. The autocomplete() function isn't even getting accessed. ...

What is the process for integrating uploaded files from a .NET Core API into my Angular application?

I'm having a problem displaying an image in my Angular application. This issue is encountered in both my profile.ts and profile.html files. public createImgPath = (serverPath: string) => { return `http://localhost:63040/${serverPath}`; } & ...

Unable to access property 'http' of undefined during testing in Angular 2+

Struggling to obtain a fresh token for testing purposes and unable to identify the root cause... Uncertain if this approach is optimal or if mocking would be more appropriate, but sticking with this method for now... The specific error message being enco ...

Connect the Result of a Button Click to a Fresh Span

Just starting out with Angular2 so I'm keeping things simple for now. I understand the importance of separating feature components, but my main focus at the moment is getting everything to function properly. My objective here is to bind the value of ...

Looking to retrieve the AssetLoadedFunc properties in the LoadAssets function? Wondering if you should use TypeScript or JavaScript

When I invoke this.AssetLoadedFunc within the function LoadAssets(callback, user_data) LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL("assets/Js/scrollbar_h.g", null, this.AssetLoaded, { name: "scrollb ...

Error message "Cannot access property 'template' of undefined" is thrown when using Material Design Mat-footer-row component

Whenever I include the following code snippet: I encounter the error message: Cannot read property 'template' of undefined ..... <ng-container matColumnDef="Price"> <mat-header-cell *matHeaderCellDef >Price</mat-head ...

Promise disregards the window being open

I'm facing an issue with redirecting users to Twitter using window.open in a specific function. It seems like the instruction is being ignored, even though it works perfectly on other pages. Any ideas on how to fix this? answerQuestion() { if ...

require the ability to dynamically adjust the header based on the content

I am using ag-grid-polymer and I need to adjust the header content so that user-entered text fits within the column size without being cut off by ellipses. .ag-theme-material .ag-header-cell-label .ag-header-cell-text { overflow: hidden; text-ov ...

Utilizing an external HTTP API on an HTTPS Django and Angular server hosted on AWS

Can this be achieved? I am in the process of creating an ecommerce platform that necessitates interacting with an external API service built on HTTP. My website is hosted on AWS EBS, utilizing django for the backend and angular2 for the frontend. Whenever ...

Dealing with a multi-part Response body in Angular

When working with Angular, I encountered an issue where the application was not handling multipart response bodies correctly. It seems that the HttpClient in Angular is unable to parse multipart response bodies accurately, as discussed in this GitHub issue ...

Encountering difficulties importing the Kendo TimePicker component for Angular versions 2 and above

On Wednesday (9/13/2017), I received the KendoUI newsletter via email announcing the release of the New TimePicker component. Intrigued, I attempted to import the TimePicker into my project, but encountered difficulties in doing so. The API indicated that ...

Utilizing a single Angular 2 app to incorporate various components on a single page

Can you guide me on how to dynamically render a section of HTML from a child component to a parent component in Angular 2? The concept is to create a main layout where different sections can be replaced or customized by child components based on specific r ...

Navigating with firebase authentication and angular routing

Currently, I am in the process of developing an ionic app using version 4. For this project, I have decided to utilize firestore as my database and implement firebase-authentication for user login and registration functionalities. However, I have encounter ...

Steps to filter types by a singular property assessment

export type HalfSpin = { halfspin: string } export type FullSpin = { fullspin: string } export type SpinType = | HalfSpin | FullSpin export function isHalfSpin(_: SpinType) ...

Update: Git is not currently keeping track of the Angular project

After creating an Angular 5 project in a local branch, I encountered an issue when trying to add/commit/push that branch to origin. Despite Bitbucket confirming the commit, the angular project did not appear in my branch in the remote repository. Strangel ...

Tips for creating nested child routes in AngularJS 2 with ID:

Here is a Demo of what I'm working on. Just getting started with angularjs 2 and trying to figure things out. I want to display Twitter names that correspond to certain names using routes on the same page, specifically utilizing a second <router- ...

The child component is receiving null input data from the Angular async pipe, despite the fact that the data is not null in the

I encountered a strange scenario that I'm unable to navigate through and understand how it occurred. So, I created a parent component called SiteComponent. Below is the TypeScript logic: ngOnInit(): void { this.subs.push( this.route.data.subscribe( ...

Linking to a file within an npm package

Is it possible to reference local files within an npm package? Will these references still work correctly when the package is installed by a different consumer? For example, let's say I have developed an npm package for Angular which includes some HTM ...

What is the best way to selectively retrieve a combination of keys from multiple objects within an array?

Consider the following scenario: const common = { "test": "Test", "test2": "Test2" } const greetings = { "hello": "Hello" } export const locales = (["en", "nl"] as const); export type I18nMap = Record<typeof loc ...