DEV Community

Cover image for How to use Bootstrap Modals in Angular in separate components
Federico Navarrete
Federico Navarrete

Posted on • Edited on • Originally published at supernovaic.blogspot.com

How to use Bootstrap Modals in Angular in separate components

As many might have experienced, there are some Bootstrap controls that you cannot use easily in Angular, and that's why a good solution is: ng-Bootstrap.

npm install --save @ng-bootstrap/ng-bootstrap
Enter fullscreen mode Exit fullscreen mode

However, not all controls are so easy to use and one complex situation happens, when you want to split Modals into multiple components. The regular Modal looks like this:

HTML Code:



<a (click)="openModal(contentModal)" class="nav-link">Open modal</a>

<ng-template #contentModal let-c="close" let-d="dismiss">
  <div class="modal-header">
      <h4 class="modal-title" id="modal-primary-title">Title</h4>
      <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
  </div>
  <div class="modal-body centered">
    <!--Body-->
  </div>
</ng-template>


Enter fullscreen mode Exit fullscreen mode

TypeScript code:



openModal(contentModal) {
    this.modalService.open(contentModal);
}


Enter fullscreen mode Exit fullscreen mode

And it's perfectly fine if you have one or two Modals and they don't have any logic behind, besides popping up as in an About Modal, but what if you have 3+ Modals with full logic?

Many times, these are business requirements and this could create a big mess in your code. The previous solution is not feasible at all in this case. And let's not talk about scalability or many other examples related.

After many attempts, I designed a solution that helped split the Modals into independent components.

The first step is to create your new component:

ng generate component ModalComponent
Enter fullscreen mode Exit fullscreen mode

After, register your Modal in the entryComponents section of your app.module.ts:



entryComponents: [
    ModalComponent,
],


Enter fullscreen mode Exit fullscreen mode

Next, copy your old Modal to your new component and remove these 2 lines:



<ng-template #contentModal let-c="close" let-d="dismiss">
</ng-template>


Enter fullscreen mode Exit fullscreen mode

It should look like this:



<div class="modal-header">
    <h4 class="modal-title" id="modal-primary-title">Title</h4>
    <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
        <span aria-hidden="true">&times;</span>
    </button>
</div>
<div class="modal-body centered">
    <!--Body-->
</div>


Enter fullscreen mode Exit fullscreen mode

Now, it comes a small change in the logic of the click event and how to call it:

This is the new HTML code:



<a class="nav-link" (click)="openModal()">About</a>


Enter fullscreen mode Exit fullscreen mode

This is the new TypeScript event:



openModal() {
    //Here you define the name of your component
    this.modalService.open(ModalComponent);
    //This section is if you want to have any variable to initialize
    //compConst.componentInstance.weight = undefined;
}


Enter fullscreen mode Exit fullscreen mode

Also, in your new Component, you need to add change your constructor and add an instance of NgbActiveModal.



constructor(public activeModal: NgbActiveModal) { }


Enter fullscreen mode Exit fullscreen mode

Another important change is in the logic of closing the modal, it needs to be changed to this:



<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    <span aria-hidden="true">&times;</span>
</button>


Enter fullscreen mode Exit fullscreen mode

You need to change the old: (click)="d('Cross click')" to (click)="activeModal.dismiss('Cross click')"

And with all these changes it will work like charm. I got some inspiration from here:

https://stackblitz.com/edit/angular-uwtgs6

Follow me on:

Personal LinkedIn YouTube Instagram Cyber Prophets Sharing Your Stories
Personal LinkedIn YouTube Instagram RedCircle Podcast RedCircle Podcast

sponsor me

Top comments (0)