3

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

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
a.p. patel
  • 103
  • 4
  • 25

1 Answers1

3

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

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
  • 1
    But is it good practice to keep the subscription on in app.component? – app Mar 27 '21 at 02:17
  • 2
    As long as you ensure to unsubscribe I believe its fine. Another option would be to simply move the modal to its own component. that way you wouldn't have to worry about subscribing in the app.component – Owen Kelvin Mar 27 '21 at 02:23
  • 1
    Cool. Is it possible for you to provide the example of modal as own component...? Thanks in advance – app Mar 27 '21 at 02:27
  • 2
    see this fork https://stackblitz.com/edit/angular-nested-component-modal-ngx-bootstrap-n-6xdtaq?file=app%2Fapp.component.ts – Owen Kelvin Mar 27 '21 at 02:30
  • 1
    Thanks..just one suggestion.. do you know any Library who supports this function like material in Angular 8 https://stackoverflow.com/questions/66802189/how-to-add-arrows-for-left-and-right-navigations-in-primeng-tab-view-in-angular – app Mar 27 '21 at 03:03
  • 1
    @app one way would be to create your own directive, I have provided a solution, kindly check – Owen Kelvin Mar 27 '21 at 09:33
  • Thanks a lot Owen.. you are life saver... One more question if you can help... https://stackoverflow.com/questions/66570025/how-to-group-suggestions-list-in-the-primeng-autocomplete-angular-8/66740654#66740654 – a.p. patel Mar 27 '21 at 13:22
  • Any luck @owen ? – a.p. patel Mar 28 '21 at 04:31
  • 1
    @a.p.patel have a look, I have provided my approach – Owen Kelvin Mar 28 '21 at 07:30
  • @OwenKelvin thanks a lot.. modal component approach is really nice. but can we make it configurable for a specific component for future use? – app Mar 29 '21 at 14:22
  • 1
    @app I believe its already configurable, Passing different config values to the `show()` function should bring about different configurations – Owen Kelvin Mar 30 '21 at 16:44
  • Is there any way we can configure for some component we can close instance right away vs for some component we can use multiple instances? – a.p. patel Apr 03 '21 at 03:34