Singletons in Ionic 3, Angular 4

Dragan Malinovic picture Dragan Malinovic · Apr 13, 2017 · Viewed 8.8k times · Source

I am defining service as class, something like this:

@Injectable()
export class MyService {
 ...
}

In other components or pages, I am importing that class with just import command.

import { MyService } from '../pages/services/myservice';

In constructor:

constructor(public _MyService: MyService)

In my main app.module.ts I have added that class service as provider.

providers: [someOtherThings, MyService, someOtherThings]

In Ionic 2, things are working as expected. Service is singleton.

But in Ionic 3, which uses angular 4, it looks like every component is creating new instance of that class.

Is there some new way of creating singleton services classes in angular 4?

Answer

Ade Novan picture Ade Novan · May 19, 2017

Im using ionic 3 with lazyload an angular 4 and not having the issues. To make it singleton make sure your app module provide the service. and remove providers on @Component that use the service.

App Module

@NgModule({
  ...

  providers: [
    StatusBar,
    SplashScreen,
    { provide: ErrorHandler, useClass: IonicErrorHandler },
    Singleton // the service or provider to be single ton
  ]
})
export class AppModule { }

The Service

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class Singleton {

  data = "init data";
  constructor() {
    console.log('Hello Singleton Provider');
  }

  set(data){
    this.data = data;
  }

  log(){
    console.log(this.data);   
  }
}

Tes Case the service on ionic page

First Page

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-first',
  templateUrl: 'first.html'
})
export class FirstPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad First');
    this.single.log(); // log init data;
    this.single.set("First singleton data");
  }

}

Second Page

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-second',
  templateUrl: 'second.html'
})
export class SecondPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad Second');
    this.single.log(); // log First singleton data
  }

}

Third Page it create new instance if providers added on component

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-second',
  templateUrl: 'second.html',
  providers:[Singleton] // wrong because its create a new instance
})
export class ThirdPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ThirdPage');
    this.single.log(); // log init data
  }

}

make sure to remove the providers on component to make it singleton.