85 votes

Angular 5 : "No provider for ControlContainer" (pas de fournisseur pour ControlContainer)

J'ai une petite application web avec Angular 5 et tout à coup, je reçois ce message d'erreur étrange dans la console de mon navigateur :

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

Ce n'était pas le cas auparavant et je n'ai pas connaissance de modifications apportées. Et je n'ai aucune idée de ce que ce message essaie de me dire.

Il s'agit du modèle de composant de form-group qui semble être invalide d'une manière ou d'une autre :

<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>

Et c'est le modèle où je consomme 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>

Je l'ai regardé pendant des heures, mais je n'ai pas trouvé d'erreur.

Je dois préciser que je n'utilise pas le FormGroup d'Angular mais ma propre solution (parce que je pensais que le leur était trop élaboré et ne répondait pas à mes besoins spécifiques). Pourrait-il y avoir une sorte de collision de noms ? Bien sûr, dans le module d'application, j'ai importé le module FormsModule pour que la liaison bidirectionnelle fonctionne et pour intercepter le submit du formulaire. Au moins, le composant de notification fonctionne sans problème.

Je vous serais très reconnaissant de toute aide.

Edit : On m'a demandé de partager mon code TS.

Composant défaillant :

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
}

Le type Groupe de formulaires est juste un tableau et le composant est juste destiné à être une enveloppe visuelle. Il n'y a aucun service supplémentaire impliqué ou DI et sans ce composant Angular compile très bien. ( formGroup est marqué comme optionnel parce que TS continuerait à se plaindre qu'il n'est pas initialisé, bien qu'il le soit toujours à l'exécution).

Composante qui transmet les biens :

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 : Pour répondre à la question de @Andrei : Je n'ai aucun service ou fournisseur appelé ControlContainer. Je n'ai que trois petits services, dont aucun ne pose de problème. D'après ce que je sais, ControlContainer a quelque chose à voir avec DI, mais la documentation d'Angular sur ce sujet est plutôt mystifiante.

0 votes

Pouvez-vous partager votre code ts ?

0 votes

J'ai bien peur qu'il n'y ait pas assez d'éléments pour que la question ait un sens. Angular se plaint que quelqu'un demande un fournisseur (service) avec le type ControlContainer qui ne peut être trouvé dans aucun injecteur. Est-ce un service que vous avez défini ? Où est-il injecté ? De quel module fait-il partie ? Est-il déclaré comme fournisseur à cet endroit ?

0 votes

Je pense que nommer votre entrée de la même chose qu'une directive angular forms est une mauvaise idée en général, même si cela ne cause pas de conflit.

170voto

cyr-x Points 7948

Le site ControlContainer est une classe abstraite qui est étendue par le AbstractFormGroupDirective à l'intérieur de la ReactiveFormsModule .

L'erreur est signalée si vous utilisez l'option ReactiveFormsModule et un <form> -sans élément FormGroup qui lui sont liés par [formGroup]="myForm" .

Pour corriger cette erreur, vous devez créer un FormGroup et le lier à votre formulaire :

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

Assurez-vous également que vous avez les deux FormsModule et le ReactiveFormsModule ajouté aux importations de votre module.

0 votes

Changer monForm par basicInformation et additionalInformation dans le composant '<filename>.ts' avec : basicInformation = new FormGroup = basicInformation ;

0 votes

Si je fais ça, l'erreur persiste. J'ai donc ajouté ReactiveFormsModule et FormsModule à l'importation du module du composant, et ça marche.

110voto

Manav Kothari Points 1

Pour moi, il s'avère que j'ai importé seulement ReactiveFormsModule mais pas FormsModule. Vous devez importer les deux.

7 votes

J'ai eu le même problème. Même si vous voulez utiliser un élément de formulaire uniquement à des fins d'affichage, vous devez importer FormsModule si vous avez importé ReactiveFormsModule.

0 votes

Même solution pour moi ici avec Ionic 4 Angular 8 ;)

1 votes

Année 2020 ici, j'ai dû importer les deux modules de formulaires et remettre l'application en service pour que cette erreur disparaisse.

10voto

Marvin H. Points 488

Il s'avère que l'erreur n'a rien à voir avec form n'étant pas lié à un formGroup mais je dois aussi nommer la variable réceptrice formGroup . Cela rend Angular très confus.

Il suffit de renommer cette variable pour résoudre le problème. C'est bon maintenant :

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

0 votes

Cela m'a aidé, merci. J'avais une situation similaire avec une variable ngb-bootstrap NgbDialog qui était nommée (trop simplement) 'dialog'. Apparemment, cela dérangeait Angular 11.0.4 (cela fonctionnait au moins avec certaines des versions précédentes). Donner un meilleur nom à la variable a permis de résoudre le problème. Le style compte !

3voto

Dictech Inc Points 11

Si vous n'avez pas enregistré votre composant dans le module de votre application, cela signifie que vous devez importer le ReactiveFormsModule dans le module de ce composant.

0voto

emirhosseini Points 125

Dans mon cas, c'est parce que j'avais placé "ReactiveFormsModule" dans la section des exportations d'un de mes modules de premier niveau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X