Reputation: 1279
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
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
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
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.
@Input()
formGroup: FormGroup;
<!-- Angular now thinks this is a form which causes the error -->
<my-own-component [formGroup]="formGroup"></my-own-component>
@Input()
form: FormGroup;
<!-- This works -->
<my-own-component [form]="formGroup"></my-own-component>
@Input("form")
formGroup: FormGroup;
<!-- This works too -->
<my-own-component [form]="formGroup"></my-own-component>
Upvotes: 1
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
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 theReactiveFormsModule
added to your module imports.
Upvotes: 174
Reputation: 779
Somehow bootstrap class was conflicting with angular.
I had to remove the top level div with bootstrap class.
Upvotes: 0
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
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
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
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
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
Reputation: 1149
For Me its turns out that i imported just ReactiveFormsModule but not FormsModule. you need to import both.
Upvotes: 110
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
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