97

I have a component which is meant to be used in an Angular Material MdDialog :

@Component({
  ...
})
export class MyComponent {

  constructor(@Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: 
MdDialogRef<MyComponent>) {
...
  }


}

I am trying to Unit Test it with Jasmine :

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        SharedTestingModule,
      ],
      declarations: [
        MyComponent,
      ],
    })
    .compileComponents();
  }));

  ...
  
});

Unfortunately, I am getting the following error :

Error: No provider for InjectionToken MdDialogData!

SharedTestingModule imports and exports my custom Angular Material module, which itself imports and exports MdDialogModule.

How can I get rid of this error?

Thank you very much!

Angular 4.2.4
Angular Material 2.0.0-beta.7
Jasmine 2.5.3
Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
Wenneguen
  • 3,196
  • 3
  • 13
  • 23
  • You always is going to get a error of this type if the injectable, in this case MdDialogData, is null or not defined (JS) or one of the components of MatDialog is null and then it can not be created. Example: `let dialogRef = this.dialog.open(DeleteDialogComponent, { data: row.name //<-if here you put i.e 4 value you get Error: No provider for InjectionToken MatDialogData, in this case DeleteDialogComponent inherits from MatDialogRef and MatDialogRef has MAT_DIALOG_DATA as injectable! });` – Aly González Dec 08 '22 at 01:53

8 Answers8

168

I added this :

providers: [
    { provide: MAT_DIALOG_DATA, useValue: {} },
    // { provide: MdDialogRef, useValue: {} }, --> deprecated
    { provide: MatDialogRef, useValue: {} } ---> now
]

And it works :)

Thanks for your help @methgaard!

Sefat Anam
  • 142
  • 4
  • 14
Wenneguen
  • 3,196
  • 3
  • 13
  • 23
101

For Angular 5 with latest Material Component

 import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

and

 providers: [
     { provide: MAT_DIALOG_DATA, useValue: {} },
     { provide: MatDialogRef, useValue: {} }
 ]
Yuri
  • 4,254
  • 1
  • 29
  • 46
Kamruzzaman
  • 1,423
  • 1
  • 12
  • 14
  • Worked perfectly for me.. couldn't figure out how to import `MAT_DIALOG_DATA` from `@angular/Material` – Rinktacular May 16 '18 at 18:23
  • This works perfectly to. I'm using `@Inject(MAT_DIALOG_DATA) public data: any` in my DialogRef component. I forgot to declare this in my spec. Thanks! – XenoX Dec 27 '18 at 09:13
15

try this

beforeEach(async(() => {
 TestBed.configureTestingModule({
   imports: [
     SharedTestingModule,
   ],
   declarations: [
     MyComponent,
   ],
   providers: [ <-- here
    {
     provide: MdDialogData,
     useValue: {},
    }
   ] <-- to here 
 })
 .compileComponents();
}));

let me know how it goes

kodeaben
  • 1,829
  • 3
  • 24
  • 33
13

as an update, this is also replicated for those who use the tags with the prefix "Mat"

providers: [{provide: MAT_DIALOG_DATA, useValue: {}}, 
{provide: MatDialogRef, useValue: {}}]
mehs2690
  • 131
  • 1
  • 4
6

You can use Angular Optional decorator, I faced this problem before so

if the component is not used as a popup try this snippet

constructor(
  @Optional() public dialogRef: MatDialogRef<PopupComponent>,
  @Optional() @Inject(MAT_DIALOG_DATA) public data: any
) {}
Mustafa Omran
  • 354
  • 5
  • 7
  • Worked for me!!! Had a component that I was loading in normal way and also loading the same as a dialog sometimes. So the *@Inject(MAT_DIALOG_DATA) public data: any * was null in normal loading and it would not work. – Luke Matafi Dec 02 '22 at 15:24
4

you can inject MAT_DIALOG_DATA / MAT_BOTTOM_SHEET_DATA in jasmine tests without specifying a provider. you must simply ensure that the value being injected is non-null. if it is null, the compiler mistakes the null value for a non-existing provider and you get the provider not found error.

Bob
  • 41
  • 1
1

try add in your <x>.component.spec.ts under providers:

{ provide: MatDialog, useValue: {} }

in some cases you need also:

{ provide: MatDialogRef, useValue: {} }

(this way working in my angular 11 project)

ofir_aghai
  • 3,017
  • 1
  • 37
  • 43
0

No provider for InjectionToken MatDialogData!, This error will occur when we run test cases, When we use matdialog reference with @Inject(MAT_DIALOG_DATA) public value: string, in the respected component.

Add below code in spec.ts file

providers: [MatDialogModule, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: MatDialogRef, useValue: {} }]

Sreehari Ballampalli
  • 3,404
  • 3
  • 12
  • 19