Angular Material 9|8|7 Add Dialog Modal and Pass Data between Parent Component Tutorial by Example

In this Angular Material 9 tutorial, we’ll discuss how to implement Material Modal popup using Dialog API and pass data between parent and Modal dialog component.

The Dialog component is used to show dynamic HTML content which component in a container floating over the content box, this can be closed down by user action like clicking on the close icon. The dialog models are used to create a focused area on-screen generally used for data actions like Create, Update data or show alerts and confirmation.

The Angular Material UI library provides a number of components which can be used by importing the required APIs in the project modules. Material Dialog is provided by the MatDialogModule to creat dynamic Modals with custom components. The Dialog component provides number of configurations options which we’ll discuss in this post.

Here we will create a new Angular application then install Material UI library package to demonstrate how to add Angular Material Dialog in Application with options available also discuss on how we can pass data between the parent page and Dialog component.

Let’s start the implementation…

 

# 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-checkboxlist
$ cd angular-material-checkboxlist</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>
We are done with Angular material installation and configurations. 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.

After adding Angular material in our project, we need to import the required modules in the Angular module. we'll use Dialog, Input Field, Form and Button modules.

Now open the app.module.ts file them import Material UI modules <code>MatFormFieldModule, MatDialogModule, MatInputModule & MatButtonModule then add in the imports array. In the Dialog example, we'll also use Forms so also import the FormsModule 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 { FormsModule } from '@angular/forms';

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


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

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

# Create a Component for Dialog

For dynamic content in a Dialog, we'll create a new component which will act like a Dialog Modal having its own template and component class.

Run following npm generate command in the terminal window to create MyDialogModalComponent component in the modals folder.

$ ng generate component modals/my-dialog-modal</pre>
Above command will add the <code>MyDialogModalComponent in the App Module's declarations array automatically.

Note: For Angular CLI versions before 8, we will need to add the MyDialogModalComponent in the entryComponents Array in the app's module as Dialog is loaded dynamically after app load.

# Open Dialog from Parent Component

To open the dialog modal from the App component, we will add an input field and a button with a (click) event calling the openDialog() method. This will pass Input value to opened Dialog and show value in it. Update app template and component class with the following code:
<!-- app.component.html -->
<mat-form-field>
  <input matInput [(ngModel)]="sendValue" placeholder="Enter value for Dialog">
</mat-form-field>
<div *ngIf="dialogValue">
  <b>Value From Dialog</b>: {{dialogValue}}
</div>
<div>
  <button mat-raised-button (click)="openDialog()">Open Dialog</button>
</div></pre>
<h6></h6>
<h6>Update App Component Class</h6>
In the class file, import the <code>MatDialog class from @angular/material package to provide the open() method. This method takes the component we want to open as a first argument. In the second argument we pass option object which is also having the data property using which we can pass data to the Modal.

Update the app.component.ts file  as shown below:
// app.component.ts
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MyDialogModalComponent } from './modals/my-dialog-modal/my-dialog-modal.component';

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

  dialogValue: string;
  sendValue: string;

  constructor(
    public dialog: MatDialog
  ) { }


  openDialog(): void {
    const dialogRef = this.dialog.open(MyDialogModalComponent, {
      width: '250px',
      backdropClass: 'custom-dialog-backdrop-class',
      panelClass: 'custom-dialog-panel-class',
      data: { pageValue: this.sendValue }
    });

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

}

There are some options we used in the open() method above:

width: defines the width of the modal.

backdropClass: To customize the background style visible when the modal is open.

panelClass: Add a custom class to the modal panel.

data: This property is used to pass the data object inside the modal.

 

# Disable Dialog close when User clicks outside

Sometimes we want a user to click the cross icon to close the modal instead on clicking outside of the modal. In that case, we can set the option property disableClose:true. By setting this to true a user will not be able to close the modal on hitting ESC or clicking outside. Modal can only be closed by calling the close() method available in the MatDialogRef class.

 

# Dialog Close Callback Handler

In the dialogRef we are saving the Modal instance to subscribe its callback method afterClosed() which will return data back to parent component when modal is closed.

 

 

# Update DialogExample Component

Now we will update the Dialog Modal template and class to accept data from Parent, show it in the modal. Also, we will handle the close() method to send back data from Modal to the parent component.

Update Modal Component Template

In the my-dialog-modal.component.html file, add the following template that will have an input field to get a new value which will be passed to <strong>afterClose()</strong> subscription method in the parent component.

There is a button to call closeDialog() method.

<!-- my-dialog-modal.component.html -->
<h2>Dialog Modal</h2>
<b>Value From Page</b>:{{fromPage}}
<div>
<mat-form-field>
<input matInput [(ngModel)]="fromDialog" placeholder="Enter value to send back">
</mat-form-field>
</div>
<div>
<button mat-raised-button (click)="closeDialog()">Close</button>
</div></pre>
 
<h6>Update Modal Class</h6>
Next, update the <strong>my-dialog-modal.component.ts</strong> file, with the following code:
<pre class="wp-block-prismatic-blocks"><code class="language-javascript">// my-dialog-component.ts
import { Component, OnInit, Optional, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';

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

fromPage: string;
fromDialog: string;

constructor(
public dialogRef: MatDialogRef<MyDialogModalComponent>,
@Optional() @Inject(MAT_DIALOG_DATA) public data: any
) {
this.fromPage = data.pageValue;
}

ngOnInit() {
}

closeDialog() {
this.dialogRef.close({ event: 'close', data: this.fromDialog });
}

}
</pre>
In the above code, we are getting data passed from parent using <code><strong>MAT_DIALOG_DATA</strong>

and passing back new value form Dialog to parent using <strong>close()</strong> method's <strong>data</strong> property.

Conclusion: In the above article, we discussed how to implement Angular Material Dialog component in Angular app using a dialog component and also discussed how to pass data from parent to dialog and send back data from dialog to parent component using MatDialog class methods.

 

 

 

Leave a Comment

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