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?
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.
Try storing the Service's instance in your AppModule
and get the instance (instead of instancing it) later in other components.
import {Injector} from '@angular/core'; export class AppModule { // Allows for retrieving singletons using 'AppModule.injector.get(MyService)' later in the code static injector: Injector; constructor(injector: Injector) { AppModule.injector = injector; } }
And to retrive the Service's instance use:
const myService = AppModule.injector.get(MyService);
Check the documentation Here!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With