Angular Material 9 Modal Popup Example

In this post, we’ll learn how to open a Modal Popup Dialog in Angular 9/8 application using the Material UI library.

Angular Material is a UI library which provides a number of components. It works great with the Angular framework and helps in developing awesome applications. This UI library is based on Material design principals which add on user experience a lot!

Here we will discuss How to add and use Modals as we have seen in Bootstrap projects. But in an Angular project, we’ll use the Material library to implement Modals. Like any other library, Material Modals can communicate with data which we can pass from parent and in return, the Modals can return back the data on close events.

Let’s get started!

 

# Setup Angular CLI

We’ll create Angula project in the latest version. Make sure you have updated the Angular CLI tool by running below npm command in the terminal

$ npm install -g @angular/cli</pre>
 
<h3># Create an Angular Project</h3>
Execute below <code>ng command to create an Angular project in latest version 9.1.3. But this tutorial is compatible with previous version 7,6,5 and 4
$ ng new angular-material-modals
$ cd angular-material-modals</pre>
<h3></h3>
<h3># Install Angular Material in project</h3>
After version 8, Angular Material package can be installed by executing the following <code>ng command. For configuration, it will ask a few questions related to the theme, browser animations etc
$ ng add @angular/material</pre>
Answer questions
<pre class="wp-block-prismatic-blocks"><code class="language-javascript">? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? Yes</pre>
Now our Angular project is ready to use Material components.

 
<h3># Import Material Modules</h3>
The Material UI library provides a wide variety of components, so we need to import the API module of the component we are going to use in the App module.

Here as we'll be using the Modal Dialog so we need to import <code>MatDialogModule. Also, we'll have a form with Inputs and Buttons, so also import the FormsModule, MatFormFieldModule, MatInputModule, and MatButtonModule in the app.module.ts file as shown below
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { MyModalComponent } from './modals/my-modal/my-modal.component';

import { FormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent,
    MyModalComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,

    FormsModule,
    MatDialogModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

# Create Modal Component

The Modal can have its own component which will act a modal container. Run the following ng generate command to create a my-modal component in the modals folder.

$ ng generate component modals/my-modal</pre>
<img class="alignnone wp-image-4052 size-full" src="https://www.freakyjolly.com/wp-content/uploads/2020/04/Pasted-into-Angular-Material-98-Modal-Popup-Dialog-like-Bootstrap-Example.png" />

Now open the <strong>app>modals>my-modal.component.ts</strong> file and place following code in it
<pre class="wp-block-prismatic-blocks"><code class="language-javascript">// my-modal.component.ts
import { Component, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';

@Component({
selector: 'app-my-modal',
templateUrl: './my-modal.component.html',
styleUrls: ['./my-modal.component.css']
})

export class MyModalComponent {

food: string;

constructor(
public dialogRef: MatDialogRef<MyModalComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) { }

onNoClick(): void {
this.dialogRef.close({
food: this.food
});
}

}</pre>
<h3></h3>
<h3>How to Get Data passed from a parent component in Modal?</h3>
Data object passed from parent component will be available in the <code>data

property. We can also define a type to this data but to keep this tutorial simple we have not created any model or interface.

 

Update the my-modal.component.html file with below template:

<h1 mat-dialog-title>You are from {{data.name}}</h1>

<div mat-dialog-content>

<p>What's your favorite city?</p>
<mat-form-field>
<mat-label>Favorite City</mat-label>
<input matInput [(ngModel)]="data.city">
</mat-form-field>

<p>Your favorite food?</p>
<mat-form-field>
<mat-label>Favorite Food</mat-label>
<input matInput [(ngModel)]="food">
</mat-form-field>

</div>

<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Get Food</button>
<button mat-button [mat-dialog-close]="data.city" cdkFocusInitial>Get City</button>
</div></pre>
<h3></h3>
<h3>How to send back data from Modal to parent component?</h3>
There are two methods to send-back data from Modal component to parent component:
<h3>1) Use <code>[mat-dialog-close]

property

This property can have an Object to pass the data to the parent. On clicking on a button with this property will also close the modal.

2) Use close() method

The MatDialogRef class provides the close() method which we called in the onNoClick() method in the my-modal.component.ts file above. The close() method will pass data object and also close the modal.

 

 

# Open Modal from App Component

To open the modal we will update the app.componet.html file to have the following template

<ol>
<li>
<mat-form-field>
<mat-label>Where do you stay?</mat-label>
<input matInput [(ngModel)]="name">
</mat-form-field>
</li>
<li>
<button mat-raised-button (click)="openDialog()">Pick city or food</button>
</li>
<li *ngIf="city">
You chose: <i>{{city}}</i>
</li>
<li *ngIf="food_from_modal">
I love {{food_from_modal}}
</li>
</ol></pre>
Update the <strong>app.component.ts</strong> component class with below code
<pre class="wp-block-prismatic-blocks"><code class="language-javascript">// app.component.ts
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MyModalComponent } from './modals/my-modal/my-modal.component';

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

city: string;
name: string;
food_from_modal: string;

constructor(public dialog: MatDialog) { }

openDialog(): void {
const dialogRef = this.dialog.open(MyModalComponent, {
width: '250px',
data: { name: this.name, animal: this.city }
});

dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed', result);
this.city = result;
this.food_from_modal = result.food;
});
}

}
</pre>
<h3>How to Pass data from parent component to Modal?</h3>
The Modal can be opened by calling the <code>open()

method available in the MatDialog class. This method takes first argument as the Modal component and second takes configuration with data property.

We can pass data using the data property.

 

How to get data in the parent component passed by Modal?

We need to subscribe to the afterClosed() method available in the MatDialog class, which return the object passed by modal after it closes.

 

Now you can run your Angular project by hitting $ ng serve --open to see it working.

 

Conclusion: Modals in an application plays an important role to simplify the user experiences. We have used many time the Modals available in the Bootstrap framework, but Angular application can also use Material based Dialogs in form of Modals.

Leave a Comment

Your email address will not be published. Required fields are marked *