Ionic 2 - How to manage global variables?

FrancescoMussi picture FrancescoMussi · Nov 28, 2016 · Viewed 44.2k times · Source

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!

Answer

nyluje picture nyluje · Nov 28, 2016

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.