angulartypescriptngx-bootstrapngx-modal

How to close the existing ngx-modal when new modal open up from same component in Angular 8


I am trying to make a reusable modal component that can be called from the same modal itself.

How I can configure the component and modal such that when the reusable component opens up the older instance will get closed directly?

Below is my stackblitz.

https://stackblitz.com/edit/angular-nested-component-modal-ngx-bootstrap-n


Solution

  • I would use one modal...

    Here is the strategy

    1. Have the modal on the app component
    2. Create a service that will communicate when user would like to open an new modal
    3. From each of the component buttons call the service

    Lets begin by defining our Service

    my.service.ts

    import { Injectable } from "@angular/core";
    import { BehaviorSubject, Subject } from "rxjs";
    
    interface IModalParams {
      component: any;
      config?: any;
      title?: any;
    }
    @Injectable()
    export class MyService {
      modalOpen$ = new BehaviorSubject(false);
      component;
      config;
      title;
      show({ component, config, title }: IModalParams) {
        this.component = component;
        this.config = config;
        this.title = title;
        this.modalOpen$.next(true);
      }
    }
    
    

    So we have defined a show method that will set some variabes (component, configuration and title)

    We have also defined a subject modalOpen$. Now any property that subscribes to this will be informed when a user has opened a new modal

    app.component.ts

      ngOnInit() {
        this.myService.modalOpen$.pipe(
          tap(() => this.modalRef?.hide()),
          filter(isOpen => isOpen)
        ).subscribe({
          next: () => {
            const {component, config, title} = this.myService
              this.modalRef = this.modalService.show(component, config);
              if(title) {
                this.modalRef.content.title = title; 
              }
          }
        })
      }
    

    Here we subscribe to modalOpen$ and open or close the component provided

    any-other.component.ts

     this.myService.show({
         component: ModalContentComponent,
         config: {
          ignoreBackdropClick: false
        },
        title: "Modal with component"
       })
      }
    

    In other components, we can now use our show method as specified above

    See Demo Here