Sending event to app controller from service/components

Hello,

I’m facing an issue that a lot of people have and debates on : I need to change the view when something happens in my service.

OK, broken design, I understood from many posts. But no solutions.

My problem :
I have API calls, and when one of them failed with 401, I need to redirect the user to login page. All my API calls are in a provider, and (of course), I don’t want to handle that case in every controllers.
I have also some angular2 components (@Component decorator) that are used in many places of the app, and they have link to other pages. But I can’t inject NavController in components (and components are part of the view isn’t it ?).

Some people said in old posts: “use events to send to controllers.” Ok. But how does it work ?

The only common piece of every call, is the “App” that bootstraps the application. How to send it an event through a @Component that is injected in deeper @Page, and in @Providers (and how to throw events in @Providers, that’s weird ?)

I (and I’ll probably not be the only one) will really appreciate a concrete example on how you can manage this kind of problems, 'cause I really don’t have a clean idea after many many days and tries.

Best regards,
Peekmo

One way to handle this is to have a service that contains an Observable<boolean> representing “are we authenticated?”. I use a ReplaySubject with a stack depth of 1. The app’s root page can inject NavController, subscribe to the authentication record service, and call nav.setRoot appropriately whenever a new state is entered. You can also employ similar logic in an attribute directive, if you want to go that way. When an API call gets a 401 error, you can call next(false) on the authentication recorder. When a login is successful, you call next(true) on it.

Hi,

Thank you, it’s a good idea for services, but how to do that with components ?
Is there an other way for components to modify navigation stack ?

Which version of ionic are you using? almost a month ago the @Page was deprecated and now we use @Component decorator.

Also why not putting all http calls in a single service and in there override the actions when a 401 status code is received to go to login, for example i have a service that wraps all http calls, add then the access token as well as some info like dbUrl and user company, i only tell it to add the headers inside that service while i call it all over the app, you could do the same, just add this to be able to use the nav controller in injectables:

class httpService {
  constructor(
    public app: App
  ) { ... }

  redirectToLogin() {
    let nav = this.app.getActiveNav()
    nav.setRoot(LoginPage);
  }
}
1 Like

In fact, the migration solved my issue.

Thank you !

Wow how did you put that solution checkmark? i didn’t know that existed.