Marvin H.
Marvin H.

Reputation: 1279

Angular 5: "No provider for ControlContainer"

I have a little web app with Angular 5 and out of a sudden I am getting this strange error message in my browser console:

ncaught Error: Template parse errors:
No provider for ControlContainer ("
</p>
<form class="container" (ngSubmit)="update()">
  [ERROR ->]<app-form-group-component 
[formGroup]="additionalInformation"></app-form-group-component>
      <button "): ng:///AppModule/KickoffComponent.html@4:2

That did not happen before and I am not aware of any made changes. And I have no idea what that message tries to tell me.

This is the component template of form-group which seems to be invalid somehow:

<div *ngFor='let e of formGroup' class="form-group">
<label for="{{e.key}}">{{e.label}}</label>
<input type="{{e.type}}" name="{{e.key}}" 
[(ngModel)]="e.value" class="form-control" 
[ngClass]='{"is-valid": e.valid === true && e.required === true}'
        />
    </div>

And this is the template where I consume form-group:

<form class="container" (ngSubmit)="update()">
 <app-form-group-component [formGroup]="additionalInformation"></app-form-group-component>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>
<app-notification [notification]="notification"></app-notification>

I stared at it for hours, but I can't find any mistake.

I should mention that I don't use Angular's FormGroup but my own solution (because I thought theirs to be overengineered and it didn't fit my specific needs). Could there be some kind of name collision? Of course, in the app.module I have imported the FormsModule for two-way binding to work and to intercept the form's submit. The notification-component at least works without complaints.

I would be very grateful for any help.

Edit: I was asked to share my TS code.

Failing component:

import { Component, Input } from '@angular/core';
import { FormGroup } from '../../models/form-group';

@Component({
  selector: 'app-form-group-component',
  templateUrl: './form-group.component.html',
})
export class FormGroupComponent {
  @Input() formGroup?: FormGroup
}

The type FormGroup is just an Array and the component is just meant to be a visual wrapper. There are no additional services involved or DI and without that component Angular compiles just fine. (formGroup is marked as optional because TS would keep complaining about it not being initialized, although at runtime it will always be initialized)

Component which hands over property:

import { Component, OnInit } from "@angular/core";
import { additionalInformation } from "./additional-information";
import { basicInformation } from "./basic-information";
...

@Component({
  selector: "app-kickoff",
  templateUrl: "./kickoff.component.html",
})
export class KickoffComponent implements OnInit {
  basicInformation: FormGroup = basicInformation;
  additionalInformation: FormGroup = additionalInformation;
  methods...
}

Edit: To answer @Andrei's question: I have no service or provider called ControlContainer. I just have three small services, none of them causes any trouble. As far as I can tell, ControlContainer has something to do with DI, but Angular's documentation on that topic is rather mystifying.

Upvotes: 90

Views: 125030

Answers (14)

Balazs F.
Balazs F.

Reputation: 410

I didn't find the solution here, but at the end I had to add

viewProviders: [{provide: ControlContainer, useExisting: NgForm}]

to the @Component annotation, so my Typescript class looks like this:

@Component({
  selector: 'my-app',
  templateUrl: './my-app.html',
  styleUrls: ['./my-app.component.scss'],
  viewProviders: [{provide: ControlContainer, useExisting: NgForm}]
})
export class MyAppComponent {

Upvotes: 1

CharithJ
CharithJ

Reputation: 47490

I came across the same issue with Angular 9. Only solution that helped is removing @Host () from the dependency declaration in the constructor. Angular new Rendering engine Ivy doesn't like @Host() decorator.

Upvotes: 1

tobias47n9e
tobias47n9e

Reputation: 2231

Every time I encounter this error I make the mistake of using reactive forms and using an input named @Input formGroup in one of my own components.

Error: Using reserved word for @Input

Component

@Input()
formGroup: FormGroup;

Using it

<!-- Angular now thinks this is a form which causes the error -->
<my-own-component [formGroup]="formGroup"></my-own-component>

Solution 1: Use other word for @Input

Component

@Input()
form: FormGroup;

Using it

<!-- This works -->
<my-own-component [form]="formGroup"></my-own-component>

Solution 2: Alias the input

Component

@Input("form")
formGroup: FormGroup;

Using it

<!-- This works too -->
<my-own-component [form]="formGroup"></my-own-component>

Upvotes: 1

Armando Monjane
Armando Monjane

Reputation: 39

In case someone is still having this error while using the Angular CLI, i was only importing the ReactiveFormsModule, then i imported and registered the FormsModule to fix the error. I was serving the app with ng serve when i made changes to the module class and i was still having the error even after importing and registered the FormsModule. To fix the error i had to stop serving and start again in order to recompile the module class.

Upvotes: 4

cyr_x
cyr_x

Reputation: 14257

The ControlContainer is a abstract class which is extended by the AbstractFormGroupDirective inside the ReactiveFormsModule.

The error is thrown if you're using the ReactiveFormsModule and a <form>-element without a FormGroup bound to it via [formGroup]="myForm".

To fix this error you have to create a FormGroup and bind it to your form:

<form class="container" [formGroup]="myForm" (ngSubmit)="update()">

Also make sure you have both the FormsModule and the ReactiveFormsModule added to your module imports.

Upvotes: 174

Siddhesh Bondre
Siddhesh Bondre

Reputation: 779

Somehow bootstrap class was conflicting with angular.

I had to remove the top level div with bootstrap class.

Upvotes: 0

Robert Smith
Robert Smith

Reputation: 634

For me (and for those creating a TAB application), it turns out I had to add the imports for FormsModule and ReactiveFormsModule in the tab1.module.ts. I have found no other answer for this type of senario so I thought I would share it.

Upvotes: 1

kmjb
kmjb

Reputation: 170

Just in case someone is still having issues with this. I ran into the same error. However, it was not related importing ReactiveFormsModule or FormsModule .

In my case, I had copied a component directory from a different directory, and my SCSS imports in the ~.component.scss were relative to the initial directory that I copied from.

The error did not suggest this was the case and it took a little too long to finally consider checking other component files. Dur!

Upvotes: 1

Hoang Subin
Hoang Subin

Reputation: 7400

This issue happen when you import ReactiveFormsModule and missing FormsModule in the module. So we need to import it to the module that your component belong to

import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    ReactiveFormsModule,
    FormsModule
  ]
})
export class XXXModule { }

Upvotes: 7

Andy Essien
Andy Essien

Reputation: 131

if did not registering your component in your app module, then it means you have to import the ReactiveFormsModule in that component's module.

Upvotes: 3

Forrest
Forrest

Reputation: 3490

I was able to resolve this with two changes.

1) I had my component in its own module. I had to import THAT specific module into the app.module. That got me half way to the solution.

2) I also had some fields whose values were generated in the component and being displayed in the form group. Once I took those out of the form group and put them in a separate div, then I was set to go.

Upvotes: 2

Manav Kothari
Manav Kothari

Reputation: 1149

For Me its turns out that i imported just ReactiveFormsModule but not FormsModule. you need to import both.

Upvotes: 110

emirhosseini
emirhosseini

Reputation: 565

So for me it ended up being because I had put 'ReactiveFormsModule' in the exports section in one of my top level modules.

Upvotes: 0

Marvin H.
Marvin H.

Reputation: 1279

Turns out that the error had nothing to do with form not being bound to a formGroup, but me naming the receiving variable also formGroup. That confuses the heck out of Angular.

Just renaming this variable solves the issue. That is okay now:

<form class="container" (ngSubmit)="update()">
 <app-form-group [fg]="additionalInformation"></app-form-group>
 <button type="submit" class="btn btn-primary">Submit</button>
</form>

Upvotes: 10

Related Questions