rashadb
rashadb

Reputation: 2543

How to use Ionic2 Events

I'm getting inconsistent results from the login event created in my Login service. When the user logs in or logs out the event is not getting picked up on the subscription pages changing the links on the page accordingly.

UPDATE After more testing I've found that each page does pick up on the subscription but only after it has been entered first. In other words if I go to pageWithLink.ts before logging in then the page will correctly read the subscription update but if I login before going to the page it will ignore the subscription update.

tabs.ts

import { Component } from '@angular/core';
import { NavParams } from 'ionic-angular';

import { page1 } from '../page1';
import { page2 } from '../page2';
import { page3 } from '../page3';
@Component({
  templateUrl: 'tabs.html'
})
export class Tabs {
  index:any;
  tab1Root: any = page1;
  tab2Root: any = page2;
  tab3Root: any = page3;

  constructor(public navParams: NavParams) {
    if(navParams.get('index') === undefined || navParams.get('index') === null){
        this.index = "0";
    } else {
        this.index = navParams.get('index');
    }
  }
}

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';

import { Tabs } from '../tabs';
import { page1 } from '../page1';
import { page2 } from '../page2';
import { page3 } from '../page3';

import { LoginService } from '../services/loginService';

@NgModule({
  declarations: [
    page1,
    page2,
    page3,
    Tabs
],
  imports: [
    IonicModule.forRoot(MyApp, {
      swipeBackEnabled: true
    })
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    page1,
    page2,
    page3,
    Tabs
],
  providers: [LoginService]
})
export class AppModule {}

loginService.ts

import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular';
import { AlertController, NavController, ViewController, Events, App } from 'ionic-angular';
import { Tabs } from '../tabs';
import { page1 } from '../page1';

@Injectable()
export class LoginService {
  userStatus: boolean;
  constructor(public events:Events, public alertController:AlertController, public navController: NavController, public viewController:ViewController, public app:App){}
  sendUserStatus(statusOfUser) {
    this.events.publish('login:Status', statusOfUser);
  }

  login(){
   //login successful
   this.sendUserStatus(true)
  }

  logout(){
   //logout successful
     this.sendUserStatus(false)
      }
    }

pageWithLink.ts

import { Component } from '@angular/core';
import { Events } from 'ionic-angular';

@Component({
  selector: 'pageWithLink',
  templateUrl: 'pageWithLink.html',
  providers: [LoginService]
})
export class pageWithLink {
      person: any;
      constructor(public events:Events){
         this.events.subscribe('login:Status', login => {
         this.person = login;
        })
      }
}

pageWithLink.html

<ion-header class="opaque">
   <ion-buttons end>
      <button ion-button icon-only *ngIf="person" (click)="signout()">
        <ion-icon name="log-out"></ion-icon>
      </button>
      <button ion-button icon-only *ngIf="!person" (click)="openModal()">
        <ion-icon name="log-in"></ion-icon>
      </button>
    </ion-buttons>
</ion-header>

Upvotes: 1

Views: 3653

Answers (3)

rashadb
rashadb

Reputation: 2543

@suraj had most of it which led to several other fixes adjustments including: 1) making much of what goes into my constructors private as appropriate 2) what got the fix for me was adding a login in check to each of pages to provide a beginning state in case a user logged in already.

New loginService.ts

import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular';
import { AlertController, Events, App } from 'ionic-angular';//don't use NavController or ViewController in Injectables!
import { Tabs } from '../tabs';
import { page1 } from '../page1';

@Injectable()
export class LoginService {
  userStatus: boolean;
  constructor(private events:Events, private alertController:AlertController,  private app:App){}
  sendUserStatus(statusOfUser) {
    this.events.publish('login:Status', statusOfUser);
  }

  login(){
   //login successful
   this.sendUserStatus(true)
  }

  logout(){
   //logout successful
     this.sendUserStatus(false)
      }
    }

new pageWithLink.ts

import { Component } from '@angular/core';
import { Events } from 'ionic-angular';

@Component({
  selector: 'pageWithLink',
  templateUrl: 'pageWithLink.html'//no provider for LoginService, that's all in app.module.ts!
})
export class pageWithLink {
      person: any;
      constructor(private events:Events){

  if(UserExists){//this is a condition stating the current login status
    this.person = true;
   }

     this.events.subscribe('login:Status', login => {
     this.person = login;
    })
  }
}

Upvotes: 0

Suraj Rao
Suraj Rao

Reputation: 29614

Set

providers: [LoginService] in app.module.ts within ngModule.

Currently you have set LoginService as provider for each page. So a new service is created for every component. For your events to work LoginService needs to be singleton.

@NgModule({
    //declarations,imports etc.
    providers:[LoginService]
})

and remove provider from all other pages.This way only one event is published for the single service and will be picked by every page. The

No provider for navcontroller

is because you are injecting Navcontroller into a service. Check this answer for explanation

Upvotes: 3

ranakrunal9
ranakrunal9

Reputation: 13558

I think you need to subscribe to events of LoginService so check by updating 'pageWithLink' as below :

import { Component } from '@angular/core';
import { Events } from 'ionic-angular';

@Component({
  selector: 'pageWithLink',
  templateUrl: 'pageWithLink.html',
  providers: [LoginService]
})
export class pageWithLink {
  person: any;
  constructor(private loginService: LoginService){
     this.loginService.events.subscribe('login:Status', login => {
       this.person = login;
     });
  }
}

Upvotes: 0

Related Questions