Issues with Ionic3 Events functionality

In my Ionic3 app, I utilize events for various functionalities.

For example, I employ events to automatically redirect the user to the login screen whenever an API response returns HTTP 401.

Thus, within my app.component.ts file, I have the following setup:

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');
    });
  }
}

Furthermore, in my API services file, I trigger the event as follows:

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;
    }

}

Despite following the Ionic documentation, there seems to be an issue. What could possibly be causing it?

EDIT Adding the child service code: The service provider serves as the parent class for all API services. For instance, the authentication service class extends the aforementioned service class and includes a method for retrieving the authenticated 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));
            });
    });
}

It's worth noting that no try-catch statements are used here.

Answer №1

It seems that the relationship between app.component.ts and your provider is like that of a Parent and child. Due to this dynamic, events cannot be published and subscribed.

The reason why

console.log('before unauthorised'); //This line works when a 401 occurs
functions as intended is because app.component.ts is a file that is invoked each time an action is taken. This console statement is placed in the constructor, ensuring it gets called every time.

To address unauthorized functionality without using events, consider creating a method within your provider:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Step-by-step guide on how to include the "content-based-recommender" package in a Reactjs project

I recently started learning React.js and I'm interested in using the "Content-Based Recommender" package from npm. However, after downloading it, I encountered an issue with importing it. The documentation suggests the following: const ContentBasedRec ...

Is it possible for TypeScript to deduce the type of a discriminated union using "extracted" boolean logic?

Recently, I've been using discriminated unions (DU) more frequently and have really started to appreciate their benefits. However, I've encountered a challenge that I can't seem to resolve. When I include a boolean check inline for the DU, T ...

Issue with Aligning Elements Horizontally

I am looking to align this content at the center horizontally: <a href='/large.jpg' class='cloud-zoom' id='zoom1' rel=""> <img src="/small.jpg" alt='' title="Optional title display" /> ...

Regular Expressions for Strings in JavaScript

I want to create a regular expression in JavaScript that can search for patterns like ${.............}. For example, if I have a string like { "type" : "id", "id" : ${idOf('/tar/check/inof/high1')}, "details" : [ { ...

What is the best method for transferring files using jQuery or JavaScript?

Is there a way to use jQuery AJAX to send file information to PHP for uploading? The data in question is the file that needs to be uploaded. $.ajax({ type: "POST", url: url, data: data, /* This is where you can includ ...

The non-disappearing nature of -webkit-appearance

I have been attempting to eliminate the -webkit-appearance:none; property using jQuery, but all my efforts have been unsuccessful. Here are the methods I have tried: jQuery(document).ready(function(){ jQuery("select").removeAttr('style'); j ...

Testing Functions Defined on Window Object in Jest and TypeScript: A Comprehensive Guide

I have been struggling to test a function call that is defined on the global window object. Despite reviewing various examples, I am still unable to successfully execute a simple test case. Api.ts import "./global.d"; const verifier = window.Ver ...

incorporating a timer into a JavaScript game

I am currently working on a memory card game where I want to include a stopwatch feature. I'm looking to display the time elapsed from when the user selects the first card until they win. However, I am struggling with keeping the stopwatch running smo ...

I am interested in redirecting command line output to a file rather than displaying it in the standard

Is it possible to use child-process and spawn in node.js to execute a command and save the output to a file instead of displaying it on the standard output? test.js const expect = require('chai').expect; const { spawn } = require('child_pr ...

Vue component does not display FabricJS image

Currently, I am facing an issue where I want to manipulate images on a canvas using FabricJS inside a VueJS app. In the view component, there is a prop called background which I pass in and then use fabric.Image.fromURL() to load it onto the canvas. Howeve ...

AngularJS blank drop-down selection

I am currently working on an AngularJS select element with ng-options using the code below: <select ng-model="vm.selectedship" ng-change="vm.updateShip()" data-ng-options="ship as ('ship' + ' is ready (' + ship.currentlocation + & ...

ReactJS: Error in syntax detected in src/App.js at line 16, column 6. This token is unexpected

Just starting out with reactjs and encountered a simple example in a tutorial. Ran into a syntax error when trying to return html tags. Below is the error that popped up: ./src/App.js Syntax error: C:/Users/react-tutotial/src/App.js: Unexpected token ...

Arranging Elements in Reverse Order Using ngx-order-pipe

I have successfully sorted an Array in ascending order, but now I am struggling to figure out how to implement sorting in descending order using ngx-order-pipe. $ npm install ngx-order-pipe --save TS dummyData: any[] = [ { name: 'G' }, ...

Creating a class that can be easily mocked for connecting to mongoDB

I've been attempting to develop a class that connects to MongoDB (and accesses a gridFS connection using gridfs-stream). However, I have encountered two specific problems: Sometimes, I receive the mongo Error server instance in invalid state connect ...

Guide to integrating global interfaces into your Nuxt project

Recently diving into the world of Nuxt 3, I've encountered a challenge while exploring TypeScript functionalities. My current goal is to create a versatile NavBar featuring multiple buttons with unique links. To achieve this, I aimed to establish an ...

Discover the DOM events present in an HTML response

When sending multiple HTTP requests to a server and receiving a HTML + JS response, I need to determine which responses trigger JS alerts or DOM-based events. Node.js is being used to send the requests. Especially in cases where there is local JS on the c ...

JavaScript Scrolling Functionality Not Functioning as Expected

I have implemented a scroll function on my website $('#lisr').scroll( function() { if($(this).scrollTop() + $(this).innerHeight()>= $(this)[0].scrollHeight) { //Perform some action here } } However, I am encountering an ...

What is the proper way to utilize the component prop when working with custom components?

I'm currently experimenting with using the Link component from react-router along with my customized button component. However, I seem to be encountering an issue that I can't quite figure out: <Button component={Link} to="/"> "This works" ...

Do you need to define a schema before querying data with Mongoose?

Is it necessary to adhere to a model with a schema before running any query? And how can one query a database collection without the schema, when referred by the collection name? This scenario is demonstrated in an example query from the Mongoose document ...

Displaying checkbox values with JavaScript

How can I display multiple checkbox values when checked in HTML code? Whenever I check a checkbox, I want its value to be shown alongside the previously checked values. Right now, my code only displays one value at a time. Any suggestions on how to achie ...