Before marking this question as "duplicate", kindly hear me out since I'm stuck for hours with this problem. I've gone through the existing questions but could not find any solution.
I'm learning Angular and have started with Angular 9+ and Angular Material. I'm trying to implement a simple dialog of Angular Material by reading the documentation from the official page.
My code closely follows the example code but I'm at a loss on why I'm still getting this error messages:
'mat-dialog-content' is not a known element.
'mat-dialog-actions' is not a known element.
The dialog does show up but it looks as if no Angular Material components / directives are being rendered at all in the dialog template html. Even if I use <button mat-button>Button</button>
, it would be rendered as a normal button and not an Angular Material button. Everything else which is not in the dialog template works perfectly fine. I have no idea what I'm doing wrong here, but if anyone could point me out my mistake, that'd be great!
app.module.ts
: (I'm importing the MatDialogModule
)
...
import { MatDialogModule } from '@angular/material/dialog';
@NgModule({
declarations: [
...
],
imports: [
...
MatDialogModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
mycomponent.ts
:
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import { MatDialog, MatDialogModule, MAT_DIALOG_DATA, MatDialogConfig } from '@angular/material/dialog';
...
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
constructor(public dataDialogHandler: MatDialog) {}
ngOnInit(): void {}
public openDataDialog(): void {
const dialogConfig = new MatDialogConfig();
dialogConfig.data = {};
this.dataDialogHandler.open(DataDialogComponent, dialogConfig);
}
}
@Component({
selector: 'data-dialog',
templateUrl: './data-dialog.html'
})
export class DataDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
}
export interface DialogData {}
data-dialog.html
:
<h2 mat-dialog-title>some title</h2>
<mat-dialog-content>
<p>dialog works</p>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close>Close</button>
</mat-dialog-actions>
and finally, in my.component.html
:
<button mat-button (click)="openDataDialog()">View Dialog</button>
What am I doing wrong here? Thanks in advance!
@angular/core 9.0.7
@angular/cdk 9.1.3
@angular/material 9.1.3
typescript 3.7.5
Change the mat-dialog-content
and mat-dialog-actions
to attributes.
i.e:
<div mat-dialog-content>
<p>dialog works</p>
</div>
<div mat-dialog-actions align="end">
<button mat-button mat-dialog-close>Close</button>
</div>
Please add DataDialogComponent in the declarations array, and in entryComponents array of app.module.ts
import { MatDialogModule } from '@angular/material/dialog';
@NgModule({
declarations: [
DataDialogComponent //I think you have missed this declaration
],
imports: [
...
MatDialogModule
],
providers: [],
entryComponents: [DataDialogComponent]
bootstrap: [AppComponent]
})
export class AppModule { }
I had the same problem and solved it by moving the dialog component and the container components into different files. At the moment you've got this setup where both the dialog and the container component are declared in the same file:
# my.component.ts
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
constructor(public dataDialogHandler: MatDialog) {}
ngOnInit(): void {}
public openDataDialog(): void {
const dialogConfig = new MatDialogConfig();
dialogConfig.data = {};
this.dataDialogHandler.open(DataDialogComponent, dialogConfig);
}
}
@Component({
selector: 'data-dialog',
templateUrl: './data-dialog.html'
})
export class DataDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
}
export interface DialogData {}
I would suggest creating an entirely new dialog component that handles its own dependencies so that you end up with this:
# my.component.ts
import { Component} from '@angular/core';
import{ MatDialog } from '@angular/material/dialog';
# Make sure you import your newly created component
import{ MyDataDialog } from 'src/app/wherever-youve-put-it/my-data-dialog.component';
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
constructor(public dataDialogHandler: MatDialog) {}
ngOnInit(): void {}
public openDataDialog(): void {
const dialogConfig = new MatDialogConfig();
dialogConfig.data = {};
this.dataDialogHandler.open(MyDataDialogComponent, dialogConfig);
}
}
Then use ng generate component my-data-dialog
to create a new component to be your dialog. You can then copy across dependencies and code into (you'll be less likely to get references etc. wrong if you use the CLI to generate it and copy rather than just copy into a new handcrafted component)
# my-data-dialog.component.ts
import { Component, OnInit, Inject} from '@angular/core';
import{ MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'data-dialog',
templateUrl: './data-dialog.html'
})
export class DataDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {}
}
export interface DialogData {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With