I'm streaming

Angular 2 reusable modal service

I was recently working on an Angular 2 project that required a modal to be displayed to the end user. I decided to build a reusable component / service that can be injected into any other component and can manage the state of the modal.

To do so, I created a service that will control both the showing and hiding of the modal, as well as the current state.


import {Injectable} from '@angular/core';
import { Subject } from 'rxjs';

export class ModalService {
    isShowing = false;
    modal = new Subject();

    getModal() {
        return this.modal;
    open() {
        this.isShowing = true;
    close() {
        this.isShowing = false;
    closeModal() {

We can now associate our modal markup for this


<div class="fade in modal" [ngClass]="{'modal-open': modalOpen}">
    <div class="modal-dialog">
        Modal content and things
        <button class="btn btn-primary" (click)="closeModal($event)">Close</button>

Now to actually make the modal work, we need to add our styles to work with our ngClass


.modal {
  display: none;
  position: absolute;
  margin-top: 50%;
  top: -25%;
  right: 0;
  bottom: 0;
  left: 0;
  &-open {
    display: block;


import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import {ModalService} from './modal.service';

  selector: 'app-modal',
  templateUrl: './modal.component.html',
  styleUrls: ['./modal.component.scss']
export class ModalComponent implements OnInit {

  public modalOpen: boolean;

  constructor(private modalService: ModalService) { }

  ngOnInit() {

    this.modalService.getModal().subscribe((isOpen) => {
      this.modalOpen = isOpen as boolean;

  closeModal() {


Inside of our desired components typescript file we can add now interact with our newly created service


import { Component } from '@angular/core';
import { ModalService } from "../modal/modal.service";

    selector: 'test-component',
    templateUrl: './test.component.html',
    styleUrls: ['./test.component.scss']

export class TestComponent {
    constructor(private modalService: ModalService) {}

    openModal() {

Then inside of our markup we can add our code. this may be better to use the app-modal on the highest level html page like the app component to make sure it is consistent site wide. This example just uses it on a component.


<div class="row">
    <button (click)="openModal()">Open!</button>



Our app.module.ts will look something like this

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { ModalComponent } from './modal/modal.component';
import {ModalService} from './modal/modal.service';

  declarations: [
  imports: [
  providers: [
  bootstrap: [AppComponent]
export class AppModule { }

You can checkout a zip of the code here ( not that it’s not styled, it just needs some love with how to actually show the modal. I used bootstrap when making this. )


An inventive, entrepreneurial and positively unsatisfied mind that constantly pushes the tech boundaries to create new solutions and devices that change people’s lives.

  1. Reply James March 28, 2018 at 10:11 am

    I followed your code – but once i click the button the modal is not showing up? I don’t see where you bind the modal component/service with the modal html…

    • Reply Jon Hemstreet March 28, 2018 at 10:50 am

      You are absolutely right, there is a missing piece of the modal.component.ts that should subscribe to the modal service. This component has a public variable on it called modalOpen. I’ll update this when I get some time in the next day or so!

Leave a Reply