Getting started with Angular Material - Creating a custom Dialog Component

Paul Isaris - Apr 30 '19 - - Dev Community

Introduction

This article was originally published at paulisaris.com

Angular is a popular framework for building single-page, interactive applications.

With Angular gaining more popularity, we have the opportunity to use libraries that provide us with built-in UI components that allow us to focus on the code that will make our app stand out. ;)

In this tutorial, we will examine how to use Angular Material in order to build a clean and reusable dialog component.

We will focus on reusability, meaning that we will build a single custom dialog component that we will call when needed via a service class.
This will help us avoid duplication of HTML templates and CSS classes, as well as improve Separation of concerns throughout our app.

You can find the sample project in my Github repository

GitHub logo PavlosIsaris / Angular-playground

A simple angular app demonstrating Angular Material components

AngularPlayground

This project was generated with Angular CLI version 7.3.8.

Development server

Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Code scaffolding

Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module.

Build

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

Running unit tests

Run ng test to execute the unit tests via Karma.

Running end-to-end tests

Run ng e2e to execute the end-to-end tests via Protractor.

Further help

To get more help on the Angular CLI use ng help or go check out the Angular CLI README.




Getting started

Before writing any code, we need to set up our project. Angular uses a command line interface (CLI in short) in order to use its various commands. This tool can be installed as an npm dependency.

We assume that you have npm installed as a global dependency on your system.
You can verify a correct npm installation by running:



paul@spiderman:~$ npm -v
6.4.1


Enter fullscreen mode Exit fullscreen mode

(Yes I name all my computers with Superhero names, isn't that totally awesome?) :D

Great, since we have npm installed, we can go ahead and install the Angular CLI tool:



npm -g i @angular/cli


Enter fullscreen mode Exit fullscreen mode

(-g states that the dependency will be installed globally)

If the installation process finishes successfully, we can use npm to print all global dependencies:



paul@spiderman:~$ npm -g ls --depth=0

/home/paul/.nvm/versions/node/v10.15.3/lib
├── @angular/cli@7.3.8
└── npm@6.4.1


Enter fullscreen mode Exit fullscreen mode

Great! Let's create a playground project to start coding!



ng new angular-playground


Enter fullscreen mode Exit fullscreen mode

After we have selected the desired set up configuration options, we can go to the project's location and start the project:



cd angular-playground

ng serve


Enter fullscreen mode Exit fullscreen mode

If everything goes according to plan, we should be able to navigate to http://localhost:4200/ and see the default Angular starting page.

Adding Angular material to our project

Now, it's time to install Angular material and make use of it's built-in components.

As stated in the installation guide, we use the following npm command to install Angular Material:



npm install --save @angular/material @angular/cdk @angular/animations


Enter fullscreen mode Exit fullscreen mode

Next, we need to enable animations. Go to src/app/app.module.ts and add the following:



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

@NgModule({
  ...
  imports: [BrowserAnimationsModule],
  ...
})


Enter fullscreen mode Exit fullscreen mode

Also, we need to specify a CSS theme that our application will be using when showing Angular Material components.

We will use the default indigo-pink theme, by adding the following import statement into src/styles.scss:



@import "~@angular/material/prebuilt-themes/indigo-pink.css";


Enter fullscreen mode Exit fullscreen mode

Great! Angular Material is set up and ready to be used.

Creating the custom dialog component

Next, we need to create a new Angular component that will serve as a wrapper to MatDialog component, which in turn is the native dialog component in Angular Material.
The point here is to create a universal Angular component for our app in order to style it as we wish and include any required business logic code there.

We can use Angular CLI and execute the following:



ng g c dialog


Enter fullscreen mode Exit fullscreen mode

A new component was created in src/app/dialog/.
Navigate to src/app/dialog/dialog.component.html and delete the boilerplate HTML.

We also need to add the DialogComponent to the entryComponents array in src/app/app.module.ts class:

Creating the dialog service

We will use Angular Services in order to create a class that will serve as a Singleton.
The purpose of this class is

  1. Define a way to pass customization data for the dialog component
  2. Provide an easy way for every other component to use a dialog component

Again, we can use Angular CLI to create the service:



ng g s services/dialog


Enter fullscreen mode Exit fullscreen mode

Cool, Angular has created our service located at src/app/services/dialog.service.ts.

We also need to add this service to the providers array in src/app/app.module.ts class, since we would like to have it available app-wide.

The first step is to define an interface with the data that we will be passing each time we need to create a new dialog.
Create a src/app/shared/dialog-data.ts to include the following:



export class DialogData {
  title: string;
  message: string;
  showOKBtn = false;
  showCancelBtn = false;
}


Enter fullscreen mode Exit fullscreen mode

As it is stated in the interface, we can give a custom title and message for the dialog, as well as whether we would like to also show "OK" and/or "Cancel" buttons.

Structuring the custom dialog component

It's time to set up the dialog component we created before.
Head to src/app/dialog.dialog.component.ts and add the following:



import {Component, Inject, OnInit} from '@angular/core';
import {DialogData} from '../shared/dialog-data';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';

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

  constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData, private dialogRef: MatDialogRef<DialogComponent>) {}

  close() {
    this.dialogRef.close(true);
  }
}


Enter fullscreen mode Exit fullscreen mode

Next, head over to src/app/dialog.dialog.component.html to add the required HTML template:

Defining the openDialog method

Next up, we need a method in our service that will create and handle the dialog component. Let's add this method in src/app/services/dialog.service.ts:

The additionalDialogConfigData object passed, is Angular Material optional configuration for our dialog component.

Before creating the dialog component, we check to see whether there is another dialog open, and we close it first.

Cleaning up app component

Let's add a button (Material style of course) into our app root component, to test our custom dialog.

Head over to src/app/app.component.html and delete the boilerplate code.

Setting up app component

In order to add the button, we need to import MatButtonModule into our app.module.ts file first:



@NgModule({
  declarations: [
    AppComponent,
    DialogComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})


Enter fullscreen mode Exit fullscreen mode

Add the following to src/app/app.component.html:



<div class="wrapper">
  <button mat-raised-button color="primary" (click)="openDialog()">Show dialog</button>
</div>


Enter fullscreen mode Exit fullscreen mode

And the following style to src/app/app.component.scss:



.wrapper {
  margin-top: 5rem;
  text-align: center;
}


Enter fullscreen mode Exit fullscreen mode

We are using an openDialog method in our html template. Head over to src/app/app.component.ts to define the method:



import { Component } from '@angular/core';

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

  openDialog() {

  }
}


Enter fullscreen mode Exit fullscreen mode

Using the dialog service

In our openDialog method, we would like to call the openDialog method defined in src/app/services/dialog.service.ts file.
In order to do that, we need to use Angular's dependency injection to get an instance of Dialog service in our app component.

Go ahead and add the dependency in src/app/app.component.ts constructor:


 javascript
import {DialogService} from './services/dialog.service';
.
.
.
constructor(private dialogService: DialogService) {}


Enter fullscreen mode Exit fullscreen mode

Calling dialog service

And now for the fun part!
First, we need to create an object as described in app/shared/dialog-data.ts interface.

modify src/app/app.component.ts to reflect the following:

... and that's it! If we head over to http://localhost:4200/ , we can click on the button and see a clean, natively styled dialog:

App Screenshot

Also, if we open the console, we can see the appropriate logs when we click either the "OK" or the "Cancel" buttons.

You can find the sample project in my Github repository

GitHub logo PavlosIsaris / Angular-playground

A simple angular app demonstrating Angular Material components

AngularPlayground

This project was generated with Angular CLI version 7.3.8.

Development server

Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Code scaffolding

Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module.

Build

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

Running unit tests

Run ng test to execute the unit tests via Karma.

Running end-to-end tests

Run ng e2e to execute the end-to-end tests via Protractor.

Further help

To get more help on the Angular CLI use ng help or go check out the Angular CLI README.




Awesome, right?

Conclusion

Angular is a powerful ecosystem for building single page, interactive applications.

Angular Material is a collection of beautifully designed and clean components that you can easily integrate into your app and can save you countless hours of templating and theming.

When using an Angular Material component, think about how you can abstract it and isolate it even more by using a service, so that you can easily re-use it throughout your app!

. . . . . . . . . . . . . . . . . . .