"No provider for MdDialogRef!"

16,876

Solution 1

You may have tried to use your dialog component in a template like this:

<pizza-dialog ...></pizza-dialog>

Delete that from your template and open the dialog using MdDialog.open() as is done here:

@Component({
  selector: 'pizza-component',
  template: `
  <button type="button" (click)="openDialog()">Open dialog</button>
  `
})
export class PizzaComponent {

  dialogRef: MdDialogRef<PizzaDialog>;

  constructor(public dialog: MdDialog) { }

  openDialog() {
    this.dialogRef = this.dialog.open(PizzaDialog, {
      disableClose: false
    });

    this.dialogRef.afterClosed().subscribe(result => {
      console.log('result: ' + result);
      this.dialogRef = null;
    });
  }
}

This code was copied from: https://github.com/angular/material2/blob/master/src/lib/dialog/README.md

Solution 2

You must not change your implementation. You can provide a Mock for the MdDialogRef. In the following example I fake the MdDialogRef with the MdDialogRefMock class and register it in the providers section:

import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { MessageBoxYesNoComponent } from "./message-box-yes-no.component";
import { MdDialogRef } from "@angular/material";

class MdDialogRefMock {
}

describe("MessageBoxYesNoComponent", () => {
  let component: MessageBoxYesNoComponent;
  let fixture: ComponentFixture<MessageBoxYesNoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MessageBoxYesNoComponent ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      imports: [
      ],
      providers: [
        { provide: MdDialogRef, useClass: MdDialogRefMock }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MessageBoxYesNoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it("should create", () => {
    expect(component).toBeTruthy();
  });
});

If you are using Jasmine, you can also create a Spy instead of creating the Fake-Class:

let mdDialogSpy = jasmine.createSpy('MdDialogRef');
Share:
16,876
Alexander Taylor
Author by

Alexander Taylor

Updated on June 09, 2022

Comments

  • Alexander Taylor
    Alexander Taylor about 2 years

    Suppose I have this component:

    @Component({
      selector: 'pizza-dialog',
      template: `
      <h1 md-dialog-title>Would you like to order pizza?</h1>
    
      <md-dialog-actions>
        <button (click)="dialogRef.close('yes')">Yes</button>
        <button md-dialog-close>No</button>
      </md-dialog-actions>
      `
    })
    export class PizzaDialog {
      constructor(public dialogRef: MdDialogRef<PizzaDialog>) { }
    }
    

    I've already imported MdDialog into my app module:

    @NgModule({
      imports: [
        BrowserModule,
        MaterialModule.forRoot(),
        MdDialogModule.forRoot(),
      ],
      ...
    })
    

    Why would I get this error?

    No provider for MdDialogRef!

  • bschmitty
    bschmitty about 7 years
    how does this get placed in the html then so that the button can be clicked? you must need <pizza-component> in the html right?
  • Alexander Taylor
    Alexander Taylor about 7 years
    dialogRef.open() does it for you at runtime :)
  • Leo
    Leo almost 7 years
    This works! We do really need more documentation about this behavior and how exactly it works under the hood. But, this works!