1

I'm trying to get mat-dialog to open whenever a specific url is loaded. Currently it only works if you do a full page reload. I want it to launch the mat-dialog whenever this specific angular route is loaded no matter if it's a full page load or already loaded angular app that is using the angular router. I've tried putting the following code inside ngOnInit() and also tried inside ngAfterViewInit() but same issue. Another thing I tried was putting it in the constructor right after getting userIsAuthenticated value, but same problem. I appreciate any help!

 ngAfterViewInit() {
    if (!this.userIsAuthenticated) {
      const dialogRef = this.dialog.open(ConfirmationAgeComponent, {
        panelClass: "dialogBoxStyler"
      });

      dialogRef
        .afterClosed()
        .pipe(takeUntil(this.destroy))
        .subscribe(result => {
          if (result) {
            this.over21Agreed = true;
          }
        });
    }
  }

I also tried adding the following to the constructor:

 constructor(private router: Router){
    this.url = this.router.url;
    if (this.url === '/' || this.url.includes('search-results')) {
      alert("HERE")
    }
}

but the alert only pops up the first time. If I click the url in the address bar to highlight the url and hit enter, the alert doesn't come up.

user6680
  • 79
  • 6
  • 34
  • 78

3 Answers3

1

We are using angular lifecycle in the wrong manner.

Define Dialog :-

 openAgeConfirmationDialog() {

    const dialogRef = this.dialog.open(ConfirmationAgeComponent, {
      panelClass: 'dialogBoxStyler'
    });

    dialogRef
      .afterClosed()
      .pipe(takeUntil(this.destroy))
      .subscribe(result => {
        if (result) {
          // I defined over21Agreed to true so that component appears on screen fyi
          this.over21Agreed = true;
        }
      });

  }

Then, call openAgeConfirmationDialog() once in ngOnInit() and once in router.events within ngOninit().

ngOnInit() {

    this.openAgeConfirmationDialog();

    this.router.events.pipe(
      filter((event: RouterEvent) => event instanceof NavigationEnd),
      takeUntil(this.destroy),
      debounceTime(1000)
    ).subscribe(() => {
      this.openAgeConfirmationDialog();
    });

We are using debounceTime because it is bypassing issue caused by the route change.

abhay tripathi
  • 3,547
  • 4
  • 20
  • 25
  • I added your answer to ngOnInit, but it's still not triggering mat-dialog correctly. I also added a condition to only execute if route matches ```search-results``` Also if I highlight the address bar and hit enter, it doesn't trigger mat-dialog. Also I noticed that the mat-dialog won't start appearing till I navigate to ```search-results``` I could go to a bunch of routes before and nothing happens. When I go to ```search-results``` then all routes trigger mat-dialog after navigating there. Any suggestions? Updated code: https://pastebin.com/zxScqeBi – user6680 Aug 05 '20 at 16:06
  • than I believe there must be something else that we are doing wrong – abhay tripathi Aug 05 '20 at 16:09
  • Can you provide a slackblitz of your code replicating the issue ? – abhay tripathi Aug 05 '20 at 16:10
  • I haven't been able to make a stackblitz to reproduce problem. I could share my screen via google hangouts/zoom or something if that works... I was trying to send you a DM to your twitter handle, but it says you can't accept messages. If you change it to accept messages maybe I can send you details. lmk if this is doable... – user6680 Aug 05 '20 at 17:12
  • @user6680 Sorry to here that you are still stuck in this issue.You may try twitter again. – abhay tripathi Aug 05 '20 at 17:18
  • If slackBlits dont work, I would strongly suggest you to push your code to github or bitbucket and share that link. Once your code is in repo, I will surely give my best to help you out. – abhay tripathi Aug 05 '20 at 17:21
  • I created a github repo for you. If you can send me your email via twitter then I'll give you access to it – user6680 Aug 05 '20 at 19:04
0

you should subscribe to the router events in your main app.component constructor to be able to track navigation, for example:

constructor(private router: Router) {
        router.events.subscribe((event: RouterEvent) => this.handleEvent(event));
}

handleEvent(event: RouterEvent) {
        if (event instanceof NavigationStart) {
            // do your thing here using `event.url` for example
        }
        if (event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError) {
            // or here
        }
}

Documentation about RouterEvent can be found here

Yuriy Kravets
  • 1,183
  • 2
  • 13
  • 28
  • I moved it to the app component and if I put the ```if (!this.userIsAuthenticated) {``` block inside the NavigationStart section then when I refresh the page, it shows the popup, but still doesn't show it after page loads and I highlight address bar and hit enter. If I move it to the other section with the ```//or there``` comment then when I refresh the page, it shows the popup twice before loading the component. Do you know why? – user6680 Aug 04 '20 at 21:56
  • Also I tried event.url and router.url === '/search-results' but it seems to also trigger the mat-dialog on page refresh if I set it to ```!== '/search-results'``` so it's not evaluating the route correctly either. Updated Code: https://pastebin.com/Y69KYKPr – user6680 Aug 04 '20 at 21:56
  • @user6680 you should debug your code in a browser and see what is causing double navigation, maybe your authentication is forcing page reload, thus firing code in `handleEvent` twice? As for url matching you should set breakpoints where you perform checks and see for yourself which exactly strings you're comparing. – Yuriy Kravets Aug 05 '20 at 12:59
0

One way of doing it is to place the dialog component as the children of the header component in the routing config and provide the 'url' you want the dialog component to open as routerLink in the header component. Take a look at the below stackblitz link. Hope this is what you are looking for..

Loading mat-dialog component on a particular route