25

THE SITUATION:

In my Ionic 2 app i have a simple login which form is contained inside the right menu. You click on the right icon in the header - will appear the menu with the login form.

The login code is inside the app.component and the login view is app.html. The successful login will set a boolean global variable - loginState - to true.

The aim is that every other component - importing the global variable - can know that login state.

The problem is that - after a successful login I need to see the changes immediately reflect on the homePage component and this is not the case.

For instance on the homepage certain content should immediately become available to you after the login.

THE CODE:

This is where i set up the global variable in a separate file named global.ts that I then import in other components:

export var global = {
    loginState : false
};

app.component:

This is the app component where I import the global variable and set it to true after successful login:

import {global} from "./global";

loginSubmit()
{
    var email = this.loginForm.value.email.trim();
    var password = this.loginForm.value.password.trim();

    this.userService.submitLogin(email, password)
        .subscribe((response) => {
            if(response.result == 1) 
            {
                global.loginState = true;
                this.menu.close();
            }
        }, (error) => {
            console.log(error);
        });

}

THE QUESTION:

What should be the way to proceed in order to deal with changes on a global variable being immediately reflect on other components?

Can I call a homePage component method from the app.component?

Thank you!

FrancescoMussi
  • 20,760
  • 39
  • 126
  • 178

2 Answers2

46

I think you need to define your global variable in a Service (aka Provider).

Like that:

import { Injectable } from '@angular/core';

@Injectable()
export class SingletonService {
  public loginState:boolean = false;
}

Then you declare that service only once in the app.module.ts file:

...other imports...
import { SingletonService } from '../services/singleton/singleton';

@NgModule({
  declarations: [
    MyApp,
    ...
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    ...
  ],
  providers: [
    ...
    SingletonService
  ]
})
export class AppModule {}

On each Ionic page you use, you import the service on top of your page but don't declare it in the @Component part. Since it'll have been declared (or instantiate, not sure about the right vocabulary here) only once with app.module.ts, the value will be global from one page to an other:

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

import { SingletonService } from '../../services/singleton/singleton';
@Component({
    selector:'my-page',
    templateUrl: 'my-page.html',
})
export class MyPage {
    constructor(public navCtrl: NavController,public singleton:SingletonService){} 
}

Then in your html template (my-page.html here) linked to a specific page (thru the @Component) you put conditional on fields you want to display if singleton.loginState == true.

nyluje
  • 3,573
  • 7
  • 37
  • 67
  • Thanks for answer. I have in the end a similar situation. After login successful i set this. SingletonService.loginState = true; and if log i can see it is properly set to true. But in the HomePage component is not reflected the change. – FrancescoMussi Nov 28 '16 at 12:03
  • I haven t tried to implement your particular case myself, but I ve seen quite a lot of post that advised to use Services to carry Global var in Ionic 2 - I'm sure you'll see it too- and started to use it myself. Also so far I did not have a situation where I needed my view to be updated as the global var changes like you seem to look for. – nyluje Nov 28 '16 at 12:11
  • I am sorry. It was correct your answer. There was an error in my implementation of it because in the constructor there was a second passage loginData: = singletonService.loginState that of course was called only once. But singletonService.loginState it was indeed properly reflecting immediately the changes. Both in the view and in the logic. Thanks! – FrancescoMussi Nov 28 '16 at 14:40
  • I tried to do the same with ion-menu `` modifying type from a homepage. My buttons are `` and ``, but the type changehappens only the first time, second click has ignored. Any idea? – levipadre Jun 15 '17 at 07:11
-3

In Ionic 3 you can use localStorage to perform this operation Example:

Page 1

let page1Data = 'This is Page 1 Data';
localStorage.setItem('storedData': page1Data);

Page 2

Use this Data in page 2:

let page1Data = localStorage.getItem('storedData');
console.log(page1Data);

For more details: https://answerdone.blogspot.com/2018/03/how-to-store-and-use-data-globally-in.html

Ganesh Garad
  • 381
  • 2
  • 6
  • 5
    using local storage is not ideal in this case. Since you have to deal with async nature of persistence. So this can over complicate the code without reason. – Sergey Rudenko Mar 06 '18 at 01:27