Reputation: 2543
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
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
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
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