Controlling navigation from within a provider


#1

I created a provider that handles incoming push notifications using:

pushObject.on(‘notification’).subscribe((data: any)

What I’d like to do is handle navigation to a specific page depending on the user’s response to the incoming push notification. For example, if the incoming push notification shows has “yes” and “no” buttons in the dialog, I’d like automatically navigate to the respective “yes” and “no” pages within the app. I’d also like this to occur whether or not the user is actively using the app at the time the push notification arries.

However, I’m not sure how to handle it. Using the NavController doesn’t seem to work within a provider. Based on this link:


I think that the case I need to handle is the “Navigating from the Root component”… but I’m not sure.

Any help would be appreciated. Thanks.


#2

I would put all the navigation logic in the app component and trigger it from an Observable in the provider:

class NotificationService {
  notifications = new ReplaySubject<'yes' | 'no'>();
}

class AppComponent {
  constructor(notifs: NotificationService, nav: NavController) {
    notifs.notifications.subscribe((yesno) {
      if (yesno === 'yes') {
        nav.setRoot(YesPage);
      } else {
        nav.setRoot(NoPage);
      }
    });
  }
}

Then, when a notification is received, simply call next('yes') or next('no') on the notifications Subject.


#3

Personally I would keep the provider and just use Events.

Create an events method and call it within your app components constructor to subscribe to all your app-wide events, within those event subscribers add code to perform your navigation logic and simply trigger those events from your notification provider.

The conference app demonstrates a similar example of listening to app-wide events.

I feel it’s cleaner that way as your notification logic remains seperated into its own provider and not mixed with your app component logic.


#4

Why I don’t use, like, or recommend Events:

  • they use strings for dispatch, meaning typos are easy to make, hard to catch, and neither IDE code assistance or compile-time tools can be of any use

  • neither event data nor handlers provide any type security, so we have all the same problems described above, plus the lack of any way of writing meaningfully self-documenting code

I think that since they address both of these concerns, Observables are an objectively superior solution for any problem one may be tempted to solve using Events.


How to change page from service (@Injectable())
Where to subscribe to events to avoid duplications
Reload/refresh parent activity on button click
How to write async operations in providers
How to run a method in app.component.ts when a particular page loads
Creating a single event handler service
#5

So… when you say AppComponent, are you referring to app.component.ts?

I’m unclear where to put that code since it would need to be running all the time to handle the observable triggered in the NotificationService. That is, right now I can’t associate it with any particular page within the app, since the user could be on any page when the notification arrives. (Additionally, the app might not even be open)


#6

So, let me see if I understand.

You’re suggesting that within the notification provider that handles the incoming notification, the user’s button selection (yes/no) would trigger a yes or no event.

There is a listener, then, that handles that event and navigates to the correct page.

I guess I have the same question that I asked rapropos… where does the listening code live, since it needs to listening from any page, or even when the app is closed. Should the handling code go in the “yes” and “no” pages code to handle yes and no events respectively?

I guess it’s the hand-off that is confusing me. It seems like the navigation code (the event handler) would need to go into it’s own provider to ensure that it’s always running… but then I’m back to square one: trying to navigate from within a provider.

(and by the way… both to you and to rapropos… thank you very much for getting back to me)


#7

I’m more inclined to believe what you say than myself lol :slight_smile:


#8

Right.

That is why I suggest the app component’s constructor. That subscription will be active as long as your app is.


#9

Outstanding. That did the trick. Thank you!