简体   繁体   中英

Ionic3 Events not working

I am using events in my Ionic3 app.

For eg I am using events to redirect the user to login screen whenever any API response gives HTTP 401.

So in my app.component.ts file I am doing:

import { Component, ViewChild } from '@angular/core';
import { StatusBar } from '@ionic-native/status-bar';
import { Events } from 'ionic-angular';
import { Network } from '@ionic-native/network';
import { Toast } from '../utilities/toast';
import { LocalStorage } from '../utilities/localstorage';
import { Platform, MenuController, Nav } from 'ionic-angular';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {

  @ViewChild(Nav) nav: Nav;
  rootPage: any;
  pages: Array<{title: string, pageName: string}>;
  guardian: any;

  constructor(
    public platform: Platform,
    public menu: MenuController,
    public statusBar: StatusBar,
    public events: Events,
    public network: Network,
    public toast: Toast,
    public storage: LocalStorage)
  {
    console.log('before unauthorised'); //This line works when a 401 occurs
    events.subscribe('unauthorised', () => {
      console.log('user unauthorised take to login page'); //While this doesn't
      this.storage.clear();
      this.nav.setRoot('LoginPage');
    });
  }
}

And in my api services file I am publishing the event:

import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import { Toast } from '../utilities/toast';
import { Events } from 'ionic-angular';
import { LocalStorage } from '../utilities/localstorage';

@Injectable()
export class ServiceProvider {
    constructor(public http: Http,
        private toast: Toast,
        public events: Events,
        private storage: LocalStorage) {

    }

    getErrorMessages(errors) {
        if (errors.status == 401) {  //<= unauthorised
            this.toast.present('You need to login first!');
            this.events.publish('unauthorised');
        }

        let error_messages = [];
        if (errors.status == 422) { //<= validation error
            let validation_messages = JSON.parse(errors.text())
            for (var key in validation_messages) {
                if (validation_messages.hasOwnProperty(key)) {
                    var messages = validation_messages[key];
                    error_messages.push(...messages);
                }
            }
        } else { //<= timeout or http code 500, 405 etc.
            error_messages.push('Technical error occured... please try again later.');
        }
        return error_messages;
    }

}

What could have been the problem? The code looks correct as per the ionic documentation.

EDIT I am adding the child service code. So basically the service provider is the parent class for all the api services. For eg the auth service class extends the service class above and has the following method for fetching auth user:

getAuthUser() {
    console.log('will fetch auth');

    let headers = new Headers({
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer ' + this.getAuthToken()
    });
    let options = new RequestOptions({ headers: headers });

    return new Promise((resolve, reject) => {
        this.http.get(this.getApiUrl() + '/me', options)
            .timeout(this.getTimeOut())
            .map(res => res.json())
            .subscribe(response => {
                resolve(response);
                this.events.publish('auth_user_fetched');
            }, errors => {
                reject(this.getErrorMessages(errors));
            });
    });
}

Not that I am not using try catch here.

What is happening is that app.component.ts acts as a Parent and your provider as a child. Therefore, the event cannot be published and subscribed.

In your code console.log('before unauthorised'); //This line works when a 401 occurs console.log('before unauthorised'); //This line works when a 401 occurs works because app.component.ts is a file that gets called everytime you do some activity. And this console is written in the constructor(resulting in it called everytime).

What you can do is instead of using event for unauthorized functionality. Create a function in your provider itself that will do

unauthorized() {
      console.log('user unauthorised take to login page'); 
      this.storage.clear();
      this.nav.setRoot('LoginPage');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM