Angular Material Dialog

In this article we're gonna take a look at dialogs in angular material a dialog is a type of modal window that appears in front of the app content to provide information or ask for information, the usage of a dialog is very similar to that of the snackbar component we looked at in the last lecture, so this lecture should be pretty straightforward if you've understood how a snackbar works, let's get started.

First step import MatDialogModule in the material.module.ts and add it to the MaterialComponents[] array.

import { MatDialogModule } from "@angular/material";

const MaterialComponents = [
  MatDialogModule,
]

Next in the HTML create a button that can open the dialog using a click handler which is a method openDialog().

<button mat-raised-button (click)="openDialog()">
  Open Dialog
</button>

Now let's define the openDialog() method in our component class in app.component.ts, to be able to actually open the dialog we need the MatDialog service so import it from @angular/material, after importing we need inject it in the constructor, here is the code.

import { MatSnackBar, MatDialog } from "@angular/material";

export class AppComponent {
  constructor(private snackBar: MatSnackBar, private dialog: MatDialog) {}  
}

Now we need to define our openDialog() but the open method on dialog accept 2 parameters the first one is a component and the second is optional configuration to pass in a component parameter let's first create it. So in the terminal we use angular CLI and run the command ng g c dialog-example --skipTests.

The command creates a folder for the component and adds it to the app module, but a component that is used for a dialog also has to be included in the entryComponents array in app.module.ts

entryComponents: [DialogExampleComponent],

Now we can pass this component as the first parameter for the open() method in the app.component.ts file and of course you should import it first.

  openDialog(){
    this.dialog.open(DialogExampleComponent)
  }

all right if I save the files and take a look at the browser and click on the button. angular material dialog a dialog pops up with the content corresponding to our dialog example component which is just a paragraph tag but there are several directives meant specifically to structure the dialog content let's use them instead.

Let's open the file dialog-example.component.html and first we specify a dialog title using the mat-dialog-title directive and also let's specify the content using mat-dialog-content next we have the mat-dialog-actions let's create two buttons within this component, now on both those buttons if you want the click event to close the dialog we need to add the mat-dialog-close directive.

<h2 mat-dialog-title>Session timeout</h2>
<mat-dialog-content>You'll be logged out due to inactivity</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button mat-dialog-close>Keep me logged in</button>
  <button mat-button mat-dialog-close>Log out</button>
</mat-dialog-actions>

Alright let's test this out go back to browser and click on the button. angular material dialog component We have the modal with the title, content and actions when I click the button it closes the dialog as well, now we have two buttons intended for different purposes how would we know to log the user out or keep him signed in when the dialog closes on the button click, we can do that using the afterClosed observable which conveniently returns a result.

So back in vscode in the component class, first create a reference to the dialog and you can subscribe to the observable and let's simply log that to the console

  openDialog() {
    let dialogRef = this.dialog.open(DialogExampleComponent);
    dialogRef.afterClosed().subscribe(result => {
      console.log(`Dialog Result : ${result}`);
    });
  }

Finally we assign a value to the mat-dialog-close directive which is accessed as the result so in the HTML on Keep me logged in button the directive is going to be true and false Log out button.

<h2 mat-dialog-title>Session timeout</h2>
<mat-dialog-content>You'll be logged out due to inactivity</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button mat-dialog-close mat-dialog-close="true">
    Keep me logged in
  </button>
  <button mat-button mat-dialog-close mat-dialog-close="false">Log out</button>
</mat-dialog-actions>

Let's go back to the browser after saving the files and test this out I'm going to open the console when you open the dialog and click on the first button you can see that it says Dialog Result : true and click on the Log out button it says Dialog Result : false. angular material dialog passing data

So as you can see in the subscription method you can have the code that checks for the result if result is equal to true keep the user signed in and if result is equal to false log him out.

The final point to discuss with dialogs is passing in the data to the dialog component, there are a couple of steps so let's go over each of them.

The first step is to specify the data as the second parameter to the dialog open() method which is going to be an object the key is going to be data which in turn is going to be an object I'm going to pass a name.

  openDialog() {
    let dialogRef = this.dialog.open(DialogExampleComponent, {
      data: { name: "Rb Hosh" }
    });
    dialogRef.afterClosed().subscribe(result => {
      console.log(`Dialog Result : ${result}`);
    });
  }

next the component class for the dialog-example.component.ts, to access the data in the dialog component we have to use the MatDialogData injection token so first import Inject from @angular/core next import MAT_DIALOG_DATA from @angular/material and then we inject it in the constructor.

import { Component, OnInit, Inject } from "@angular/core";
import { MAT_DIALOG_DATA } from "@angular/material";

@Component({
  selector: "app-dialog-example",
  templateUrl: "./dialog-example.component.html",
  styleUrls: ["./dialog-example.component.scss"]
})
export class DialogExampleComponent implements OnInit {
  constructor(@Inject(MAT_DIALOG_DATA) public data: any) {}

  ngOnInit() {}
}

So basically we are now making the dialog component capable of receiving any type of data, next in the dialog-example.component.html we can simply interpolate the data object.

<h2 mat-dialog-title>Session timeout</h2>
<mat-dialog-content>Hi {{ data.name }} You'll be logged out due to inactivity</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button mat-dialog-close mat-dialog-close="true">
    Keep me logged in
  </button>
  <button mat-button mat-dialog-close mat-dialog-close="false">Log out</button>
</mat-dialog-actions>

Go back to the browser you can see that we have the name in the content so we are able to pass data to dialog component. passing data angular dialog

If you want to specify height and width for the dialog it can be passed into the configuration object, there are a bunch of properties you can use based on your requirements so I leave that for you to explore browse the API tab in the documentation and you will find everything you need.