web-dev-qa-db-fra.com

NullInjectorError: aucun fournisseur pour MatDialogRef

Je ne peux pas injecter MatDialogRef tel qu'il est décrit dans la documentation: https://material.angular.io/components/dialog/overview

Quand j'essaie de le faire, j'ai une erreur:

ERREUR Erreur: StaticInjectorError [MatDialogRef]: StaticInjectorError [MatDialogRef]: NullInjectorError: Aucun fournisseur pour MatDialogRef!

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';

import {
        MatInputModule,
        MatDialogModule,
        MatProgressSpinnerModule,
        MatButtonModule,
        MatDialog,
        MatDialogRef
} from '@angular/material';

import { ApiModule } from '../api/api.module';
import { RoutingModule } from '../routing/routing.module';

import { RegistrationComponent } from './components/registration.component';
import { LoginComponent } from './components/login.component';

import { AccountService } from './services/account.service';

@NgModule({
        imports: [
                BrowserModule,
                MatInputModule,
                MatDialogModule,
                MatProgressSpinnerModule,
                MatButtonModule,
                FormsModule,
                RoutingModule,
                ApiModule
        ],
        declarations: [
                RegistrationComponent,
                LoginComponent
        ],
        entryComponents: [
                LoginComponent,
                RegistrationComponent
        ],
        providers: [
                AccountService,
                MatDialog,
                MatDialogRef
        ]
})
export class AccountModule {}

home.component.ts

import { Component } from '@angular/core';

import { MatDialog } from '@angular/material';
import { RegistrationComponent } from '../account/components/registration.component';

@Component({
    moduleId: module.id.replace('compiled', 'app'),
    templateUrl: 'home.component.html'
})
export class HomeComponent
{
    constructor(private modalService: MatDialog) {}

    public openModal() : void
    {
        let dialog = this.modalService.open(RegistrationComponent, {});
    }
}

registration.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { MatDialogRef } from '@angular/material/dialog';

import { User } from '../../../models/domain/User';
import { ApiUserService } from '../../api/entity-services/user.service';
import { AuthService } from '../../auth/auth.service';
import { AccountService } from '../services/account.service'

@Component({
        selector: 'registration-component',
        templateUrl: 'app/modules/account/templates/registration.component.html'
})
export class RegistrationComponent
{
        public user :User = new User();

        public errorMessage :string;

        public isLoading :boolean;

        constructor
        (
                private userService :ApiUserService,
                private authService :AuthService,
                private accountService :AccountService,
                private router :Router,
                public dialogRef :MatDialogRef<RegistrationComponent>
        )
        {
                this.isLoading = false;
        }

        public onSubmit(e) :void
        {
                e.preventDefault();
                this.isLoading = true;

                this.userService
                        .Create(this.user)
                        .subscribe(
                                user =>
                                {
                                        this.user.id = user.id;
                                        this.user.login = user.login;


                                        this.authService
                                                .Login(this.user)
                                                .subscribe(
                                                        token =>
                                                        {
                                                                this.accountService.Load()
                                                                        .subscribe(
                                                                                account =>
                                                                                {
                                                                                        this.user = account;
                                                                                        this.isLoading = false;
                                                                                        this.dialogRef.close();

                                                                                        let redirectRoute = account.activeScopeId
                                                                                                ? `/scope/${account.activeScopeId}`
                                                                                                : '/scope-list/';

                                                                                        this.router.navigate([redirectRoute]);
                                                                                },
                                                                                error => this.errorMessage = <any>error
                                                                        );
                                                        },
                                                        error => this.errorMessage = <any>error
                                                );
                                },
                                error => this.errorMessage = <any>error
                        );
        }
}
19
rc21

Grâce à @Edric, iv a résolu le problème en important MatDialogModule, MatDialog et MatDialogRef de @angular/material/dialog au lieu de @angular/material

15
rc21

J'ai eu cette erreur lors de l'ajout de boîtes de dialogue à un service à partager dans de nombreux composants. Juste pour clarifier, l'erreur n'était pas présente dans l'application avant de déplacer les boîtes de dialogue vers le service. La solution consistait à inclure un fournisseur personnalisé MatDialogRef dans le module principal

  import {DialogService} from './services/dialog.service';
  import {MatDialogModule, MatDialogRef} from '@angular/material/dialog';
  ...
  imports: [
    ...
    MatDialogModule
  ],
  providers: [
     DialogService, {provide: MatDialogRef, useValue: {}},
  ],
  ...

Avec ce fournisseur, le service fonctionnait comme un singleton avec mes dialogues à partager et l’erreur du fournisseur avait disparu.

23
FRECIA

Cela peut être dû au fait que vous n’avez pas inclus un polyfill d’API Web Animations requis pour les animations Angular), car il repose sur l’API.

Voici un caniuse pour les navigateurs qui le supportent de manière native. Actuellement, seuls Chrome, Firefox et Opera prennent en charge l’API Web Animations.

Quoi qu'il en soit, vous devez suivre ces étapes pour obtenir un polyfill:

  1. Dans le terminal, tapez ce qui suit dans votre console:

    npm install web-animations-js
    
  2. Une fois l'installation terminée, décommentez la ligne pour Angular Animations in polyfills.ts _ (ou l'ajouter si ce n'est pas là):

    import 'web-animations-js'; // Uncomment this line
    

Vous pouvez également essayer d'importer les modules à partir de points de terminaison distincts, comme suit:

De:

import { MatButtonModule, MatDialogModule } from '@angular/material';

À:

import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
2
Edric
  • Dans votre module: importer uniquement MatDialogModule d'angle/matériau suffit. Non requis pour importer et fournir: MatDialogRef
  • Dans votre code où DialogComponent import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
  • Ce qui précède sont les étapes que j'ai suivies. Vous ne savez pas pourquoi vous devez l'importer à partir du dialogue
  • Mais, pourriez-vous préciser quel sélecteur vous avez utilisé dans votre HTML/template? Si vous avez utilisé le "composant d'enregistrement" dans votre modèle, c'est peut-être pour cette raison que vous obtiendrez cette erreur. J'ai essayé exactement le même exemple dans le guide Matériau. J'ai accidentellement utilisé le 'dialogue-overview-example-dialog' au lieu du 'dialogue-overview-example'. = J'ai la même erreur que vous avez.
1
Charith

Le composant transmis à la méthode ouverte MatDialog devrait avoir MatDialogRef injecté dans son constructeur, comme indiqué dans l'exemple .

@Component({
  selector: 'dialog-overview-example-dialog',
  templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewExampleDialog {

  constructor(
    public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData) {}

  onNoClick(): void {
    this.dialogRef.close();
  }

}

Je l'injectais dans le composant qui appelait MatDialog :: open plutôt que dans le composant transmis à la méthode open à l'origine de cette erreur.

0
Stack Underflow

Pour moi, le problème était que j'avais ajouté mon composant Dialog à un autre modèle HTML simplement pour le tester. Une fois que je l'ai enlevé, l'erreur dans OP est partie et cela a juste fonctionné.

0
VIBrunazo