Why am I getting the "Cannot locate control by name" error in my Angular 9 application?

Currently, I am developing a "Tasks" application using Angular 9 and PHP. I encountered a

Error: Cannot find control with name: <control name>
issue while attempting to pre-fill the update form with existing data.

Here is how the form is structured:

<form [formGroup]="updateTask" name="edit_task_form">
  <mat-form-field appearance="standard">
    <mat-label>Title</mat-label>
    <input matInput placeholder="Title" formControlName="title" placeholder="Title">
  </mat-form-field>
  <mat-form-field appearance="standard">
    <mat-label>Short Description</mat-label>
    <input matInput placeholder="Short description" formControlName="short-description" placeholder="Short Description">
  </mat-form-field>
  <mat-form-field>
    <mat-label>Category</mat-label>
    <mat-select formControlName="tags">
      <mat-option *ngFor="let category of categories" [value]="category.id">{{category.name | titlecase}}</mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field appearance="standard">
    <mat-label>Full Description</mat-label>
    <textarea matInput formControlName="full-description" placeholder="Full Description"></textarea>
  </mat-form-field>
  <div class="text-center">
    <button mat-flat-button type="submit" color="accent" [disabled]="updateTask.pristine || updateTask.invalid">Update</button>
  </div>
</form>

In my component file, I have included:

I am importing the following modules at the beginning:

import { Component, OnInit } from '@angular/core';
import * as _ from "lodash";
import {FormGroup, FormBuilder, Validators} from "@angular/forms";
import {SharedService} from "../../../core/services/shared-service.service";
import {ApiService} from "../../../core/http/api.service";

taskId: string;
updateTask: FormGroup;
currentTest:any = {};

 constructor(private _apiService: ApiService, private _formBuilder: FormBuilder, private _formControl: FormControl, private _sharedService: SharedService) {}

ngOnInit(): void {
this.categories = [
  {
    id: 1, name: "Category 1"
  },
  {
    id: 2, name: "Category 2"
  },
  {
    id: 3, name: "Category 3"
  }
];

 this.updateTask = this._formBuilder.group(this.formFields);

 this._apiService.getTaskInfo().subscribe(res => {
   this.Task = res;
   let formInfo = this.Task.info; 

   formInfo.forEach(function(task, index){
    console.log(task.key + ": " + task.data);
    this.updateTask .get(task.key).setValue(task.data);
   }, this)
 });

}

The array formInfo that contains task information looks like this:

[{
   "taskId":"5eb45c2738ae2549000ddb0a",
   "key":"title",
   "data":"Lorem ipsum dolor"
},
{
   "taskId":"5eb45c2738ae2549000ddb0a",
   "key":"short-description",
   "data":"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
},
{
   "taskId":"5eb45c2738ae2549000ddb0a",
   "key":"full-description",
   "data":"Reprehenderit aperiam unde distinctio, fuga magnam asperiores laboriosam expedita fugiat numquam rerum debitis temporibus dolores."
}] 

Although the line

console.log(task.key + ": " + task.data)
outputs the correct values:

title: Lorem ipsum dolor
short-description: Lorem ipsum dolor sit amet, consectetur adipisicing elit
full-description: Reprehenderit aperiam unde distinctio, fuga magnam asperiores laboriosam expedita fugiat numquam rerum debitis temporibus dolores.

However, the form fields remain empty, leading to console errors such as:

Cannot find control with name: 'title'

This error persists for each object in the formInfo array.

What am I overlooking?


UPDATE:

I have made changes to the code responsible for populating the form:

currentTask: any = {};

constructor(private _apiService: ApiService, private _formBuilder: FormBuilder, private _formControl: FormControl, private _sharedService: SharedService) {}

updateTask = this._formBuilder.group({});

ngOnInit(): void {

    this._apiService.getTaskInfo().subscribe(res => {
        this.currentTask = res;
        let formInfo = this.currentTask.info;

        formInfo.forEach(function(item) {
            console.log(item.key + ": " + item.data);
            this.updateTest.addControl(item.key, this._formBuilder.control(item.data, Validators.required));
        }, this);
    });

}

A browser error

NullInjectorError: R3InjectorError(AppModule)[FormControl -> FormControl -> FormControl]: NullInjectorError: No provider for FormControl!
occurs.

Answer №1

When using formControlName attributes in your template, make sure you have FormControls inside your updateTask FormGroup.

If you encounter an issue with the get method trying to retrieve a non-existent FormControl :

this.updateTask.get(task.key).setValue(task.data);

A recommended approach is to instantiate a FormBuilder instance in your constructor to reduce boilerplate code:

constructor(private fb: FormBuilder){}

Create your FormGroup like this:

updateTask = this.fb.group({});

Note that typing the updateTask variable as a FormGroup does not create an instance of the FormGroup class:

updateTask: FormGroup;

Next, use a foreach loop to add all necessary FormControls:

formInfo.forEach((task) => {
  this.updateTask.addControl(task.key, this.fb.control(task.data))
})

By following these steps, you should be able to resolve any console errors. Additionally, here is a simplified and functional StackBlitz example to help guide you through the process : https://stackblitz.com/edit/stack-fromcontrols

Answer №2

Insert the code snippet below into your ngOnInit lifecycle hook:

this.taskForm = new FormGroup({
      title: new FormControl(),
      descriptionShort: new FormControl(),
      descriptionFull: new FormControl()
    });

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

Having trouble navigating the Request and Response handling in Expressjs/Nodejs?

As I continue to delve deeper into this code, confusion seems to cloud my understanding. Here is the provided source: var express = require('express') , http = require('http') , server = express() ; var home = require('./ro ...

What steps can I take to ensure my dashboard table is dynamic, updates in real-time, and automatically reflects changes made in my MySQL database

FrontEnd Code import React, { Component, useState, useEffect } from "react"; import Navbar from "../Navbar/Navbar.js"; import BarChart from "../BarChart/BarChart"; import { Chart, Tooltip, CategoryScale, LinearScale, ...

Update the Material V4 Style ts file to the latest version, Material V5

I am currently in the process of upgrading from material v4 to v5. The problem I am encountering is related to a styles.ts file that I used to import into my component. Initially, the beginning of the class looked like this: import { defaultFont, prima ...

The callback function used for the database query did not provide any results

So here's a code snippet: module.exports.checkEmailInUse = (email) => { connection.query('SELECT `id` FROM `users` WHERE email = ?', [ email ], function(err, rows, fields) { console. ...

Are there specific mathematical algorithms that lend themselves well to creating responsive HTML designs?

Tired of constantly guessing the percentage values to use with a specific number of divs and other elements in my design. I am looking to understand the mathematical calculations that determine the scaling required for different elements in order to main ...

Filter ng-repeat according to the user's choice

Currently, I am developing a music catalog and working on implementing a feature that allows users to filter the catalog based on a list of artists and genres The list: <ul class="artists"> <li class="title"> <h5> ...

Unable to get CSS transition to function properly after adding a class using jQuery

I am trying to create a hover effect that shows an image when the mouse is over a specific div, but for some reason, the transition is not working as expected. I understand that using visibility: hidden cannot be animated. Here is the code snippet: $(d ...

Repairing a syntax error in a jQuery selector variable

$(".className").click(function(){ var link = $(this).find("a").attr('href'); //output is '#myID' var findItems = $(link '.mydiv').length; //WRONG var findItems = $(link + '.mydiv').length; ...

Can asynchronous programming lead to memory leakage?

I'm wondering about the potential for memory leaks in asynchronous operations, specifically within Javascript used on both frontend and backend (node.js). When the execute operation is initiated, a delegate named IResponder is instantiated. This dele ...

In Vue js, where is the best place to incorporate something similar to a 'base.html' template?

My transition from a Flask backend without a front end framework to Vue.js (with no chosen backend yet) has me considering how to structure my project. Previously, I would create a 'base.html' file that contained all the necessary HTML code, depe ...

Getting data from an HTML file with AJAX

I have a JavaScript application where I am trying to retrieve an HTML file in order to template it. Currently, I am using the following method: var _$e = null; $.ajax({ type: "GET", url: "/static ...

"The latest version of Angular, version 15, experiencing issues with javascript loading

Currently, I am diving into the world of Angular and encountering a puzzling dilemma. Surprisingly, my application performs flawlessly on various browsers such as Chrome, Firefox, Brave, Opera, and even on mobile versions except for Safari. Both the deskto ...

Playing with Data in AG-Grid using Javascript

I am working on implementing data display using AG Grid with an AJAX call, but I am facing an issue where no data is being shown in the grid. Even though my AJAX call seems to be functioning correctly and returning the desired object List, the grid itsel ...

"Exploring Angular's versatile table component for dynamically displaying object values in a loop

I am facing an issue with my generic table component in the software I am currently developing. The problem arises when trying to loop through and display all the values in the table. My employeeList contains data fetched from the backend successfully, bu ...

Having trouble setting $scope after redirecting to a partial template via routing

Looking to create a website that loads all necessary templates upon the initial visit. Currently, I only have one partial template but plan to add more in the future. Despite having just this one template, I'm struggling with binding the data from my ...

I encountered an issue while constructing a React application. An error message popped up indicating: "Warning: Can't execute a React state update on a component that is not mounted"

Having difficulty pinpointing the source of the error message displayed below. Should I focus my investigation on the specific lines mentioned in the console, such as Toolbar.js:15? Is the console indicating that the error lies there? Additionally, what i ...

Formcontrol is not functioning properly with invalid input

I am attempting to style an input field with a FormControl using the :invalid pseudo-class. Here is my code snippet: scss input:invalid { background-color: red; } html <input type="text" [formControl]="NameCtrl"> Unfortunate ...

Acquiring radio button input in PHP

I have 2 radio buttons within a form, <label><input type="radio" onclick="this.form.submit()" name="shfaq<?php echo $i; ?>" value="1" id="radiobuttonsondazh_0" <?php if($result['live']==1) echo 'checked'; ?> /> ...

Is there a way to retrieve JSON data using Vue and Axios?

I'm facing an issue trying to retrieve product data from a JSON file. Despite attempting different methods and searching for solutions online, I have not been able to find one that fits my specific scenario. As I am new to both Vue and axios, I apprec ...

Utilizing a functional component to incorporate a "load more" button in ReactJS

Hey everyone, I've come across this ReactJS code that I need some help with: function DisplaySolutions({solutions}) { const topSolutions = solutions.slice(0, 4); const remainingSolutions = solutions.slice(4); const [isD ...