(ngx-bootstrap) Close a modal that has been created with a component programmatically

Fabian Beyerlein picture Fabian Beyerlein · Dec 12, 2017 · Viewed 15.1k times · Source

I have an Angular 5 application using ngx-bootstrap. I create two modals using the Modal Component. I need to close the first modal after some time and then open the second modal.

I tried both of these before opening the second modal but...

  • ...when I use this.modalService.hide(0) in the component I show the modals in, nothing happens
  • ...when I use this.modalService.hide(1) in the component I show the modals in, the second modal opens and closes right after

Also this.modalReference.hide() didn't do it.

Any suggestions highly appreciated!

Answer

JeanPaul A. picture JeanPaul A. · Dec 12, 2017

I managed to get your scenario working with the following implementation

In app.component.html

<div bsModal #modalone="bs-modal" class="modal fade" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal ONe</h4>
            </div>
            <div class="modal-body">
                <button (click)="toggle()">Toggle</button>
            </div>
        </div>
    </div>
</div>

<div bsModal #modaltwo="bs-modal" class="modal fade" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal Two</h4>
            </div>
            <div class="modal-body">
                <button (click)="toggle()">Toggle</button>
            </div>
        </div>
    </div>
</div>

In the above modal sections note two important things; 1) Each modal section has a reference to the modal directive via bsModal 2) there's a reference to the element node using #... Also it is imperative that reference has different names... In this example, i've opted to use #modalone and #modaltwo. Each reference here is passed an instance of ModalDirective.

In app.component.ts obtain a reference of the modal elements using the @ViewChild() decorator with the reference name used above. (see full docs here https://angular.io/api/core/ViewChild)

 @ViewChild('modalone') public modalone: ModalDirective;
 @ViewChild('modaltwo') public modaltwo: ModalDirective;

 // Required to toggle
 one: boolean = true;

In your ngAfterViewInit() life cycle hook toggle the first modal using the show() function. The initial show() call is performed within the AfterViewInit lifecycle hook in order to have the element's node at hand. This will enable the first modal.

ngAfterViewInit(): void {
    this.modalone.show();
}

Add a simple toggle function (that is referenced in the modal html above) to switch between the two modals.

toggle() {
    if (this.one) {
        this.modalone.hide();
        this.modaltwo.show();
    } else {
        this.modalone.show();
        this.modaltwo.hide();
    }

    this.one = !this.one;
}

This should demonstrate the toggling between two modals as you require... Here's a working plunker https://plnkr.co/edit/F5oWAI?p=preview