Twitter LogoFacebook Logo
Dialog
Hello, in this tutorial, I will be talking about the dialog component from Angular Material.
By: King
Image from Codeible.com

The dialog component is a pop up container that appears above all your contents when triggered.  

You will need 2 things:

(1) a trigger to activate the dialog 
(2) a component for the dialog. 

Implementation

To begin, add the MatDialogModule to your project. Go to the app module file, add the import statement, and add it to the app.

import { MatDialogModule } from '@angular/material/dialog';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    ...
    MatDialogModule

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Using the Dialog Component

Go into a html page and add a button for the trigger. Attach a click event to it so we can click on the button to activate the dialog.

<button (click)="onOpenDialogClick()">Open</button>

Go into the TypeScript file and define the method for the click event.

onOpenDialogClick(){

}

Import MatDialog from @angular/material/dialog and inject it in the constructor.

...
import { MatDialog } from '@angular/material/dialog';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private dialogTrigger: MatDialog){
  }

  onOpenDialogClick(){

  }

}

Lastly, call the open method inside the trigger function to active a dialog.

let dialogTriggerRef = this.dialogTrigger.open();

Since we do not have a component for the dialog, we cannot pass anything yet.

Creating the Component for the Dialog

Open the terminal in Visual Studio Code and run the ng generate component command.

ng generate component Greetings

Once the component files are generated, pass in the name of the component in the open method. 

onOpenDialogClick(){

   this.dialogTrigger.open(GreetingsComponent);

}

Angular 8 and Below

If you are using Angular 8 and below, make sure to add the component in the entryComponents array in the app module file. 

...
import { GreetingsComponent } from './greetings/greetings.component';

@NgModule({
  declarations: [
    ...
  ],

  entryComponents: [
    GreetingsComponent
  ],

  imports: [
    ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

You need to do this for Angular versions below 9 because of how the project is compiled. For efficiency, the compiler will only compile the components that are declared in the code. 

For example, to successfully declare that the GreetingsComponent is used, we need to take the value of selector and add it inside of an HTML page. 

@Component({
  selector: 'app-greetings',
  templateUrl: './greetings.component.html',
  styleUrls: ['./greetings.component.css']
})
export class GreetingsComponent implements OnInit {

   ...

}

<app-greetings></app-greetings>

Since this was not necessary for the material dialog, the component needed to be added to the entryComponents array.

Transferring Data

To transfer data into the dialog, add a new JSON object argument in the open method, add a property call data, and pass in the data that you want to transfer. 

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: 10
   }
);

Then go into the TypeScript file for the component and import MAT_DIALOG_DATA from @angular/material/dialog

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

Lastly, inject the data inside the constructor by using the inject() decorator. For the type, use the type of the data that was passed in. 

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

@Component({
  selector: 'app-greetings',
  templateUrl: './greetings.component.html',
  styleUrls: ['./greetings.component.css']
})
export class GreetingsComponent implements OnInit {

   constructor(@Inject(MAT_DIALOG_DATA) public data: number){

   }

}

If we take a look at our code, we are passing in a number, so the type of our data will be a number.

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: 10
   }
);

Now our data is successfully transferred and it can be used within the dialog. For example, we can call it in the TypeScript file or in the HTML file.


TypeScript

ngOnInit(): void {
    alert(this.data);
}

HTML

<p>Hello, I am {{data}} years old.</p>

Image from Codeible.com

Complex Data

For more complex data, we can pass in an JSON object instead. 

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: {
           age: 1000,
           name: "King"
       }
   }
);

Greetings Component TypeScript

constructor(
   @Inject(MAT_DIALOG_DATApublic data: { age: number, name: string}){

}

Greetings Component HTML

<p>


Hello, I am {{data.name}} and I am {{data.age}} years old.

</p>

Image from Codeible.com

Transferring Data Out

To transfer data out from the dialog. Go to the dialog's component TypeScript file and add MatDialogRef to the imports. Then inject it inside the constructor. Inside the angel brackets, pass in the component's name.

import

   MatDialogRef
   MAT_DIALOG_DATA 
} from '@angular/material/dialog';

Override the ngOnDestroy() method, call the close() method from the DialogRef object, and then pass in the data that you want to transfer.

ngOnDestroy(){
    this.dialogRef.close(this.data);
}

Lastly, go back to the function that triggers the dialog.

Declare a reference to the trigger and then call the afterClosed() method and subscribe to it. 

onOpenDialogClick(){

    let dialogTriggerRef = this.dialogTrigger.open(
       GreetingsComponent,
       {
          data: {
              age: 1000,
              name: "King"
          }
       });

    dialogTriggerRef.afterClosed().subscribe(
      (result) => {
        alert(result.name);
      }
    );
}

The results argument represents the data that we passed in the closed method. Every time the dialog closes, it we will get the data.

Instead of closing the dialog by clicking on the dark area around it, we can add a button to close the dialog. 


Go into the HTML page of the dialog component, add a button, and attach the click event.

<p>

Hello, I am {{data.name}} and I am {{data.age}} years old.

</p>
<button (click)="onCloseClick()">Close</button>

Go into the TypeScript file and define the function and call the close() method.

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

Image from Codeible.com

Useful properties

We can also override the default settings for the dialog. 


For example, we can change the width and height. Locate the code where you called the open method.

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: {
           age: 1000,
           name: "King"
       }
   }
);

Inside the JSON object where you passed in the data, add the width and height properties and give them a string value of the dimensions you want.

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: {
           age: 1000,
           name: "King"
       },
       width: "30em",
       height: "300px"
   }
);

Image from Codeible.com

Positioning

We can position the dialog by using the position property and setting the top, right, bottom, and left values.

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: {
           age: 1000,
           name: "King"
       },
       width: "30em",
       height: "300px",
       position: {
          top: "0",
          left: "0"
       }
   }
);

Image from Codeible.com

Preventing Closures

To prevent the user from closing the dialog when they click in the dark area, set the disableClosed property to true. Alternatively, we can remove the dark area by setting the hasBackdrop property to false

this.dialogTrigger.open(
   GreetingsComponent,
   {
       data: {
           age: 1000,
           name: "King"
       },
       width: "30em",
       ...,
       disableClose: true,
       hasBackdrop: false
   }
);

For the full list and details, visit the Angular Material website posted in the description.

https://material.angular.io/components/dialog/overview


Sign In