Ionic 5 service singleton?

Hi,

In my ionic app, i have a service that has an instance of a websocket, in the constructor method, i create the socket and pass the reference to it to the pages that need it, Aren’t services supposed to be singleton? as i’m getting multiple instances of the sockets as i navigate between pages.

Also for this page i’ve set ViewEncapsulation to None if it makes any difference.

Services should be singletons as you create them and provide them in the root with

@Injectable({ providedIn: 'root'})

We’d be able to help further if you provide a snippet of what your service looks like.

1 Like

Thanks for the reply.

So basically, i have a service generated using the ionic cli and it does have the providedIn root injectable.

In the service’s constructor, i create the reference to the socket and its callbacks, I’m using socket.io

import { Injectable, EventEmitter } from '@angular/core';
declare var io:any;

@Injectable({
    providedIn: 'root'
})

export class SocketService {

    socket:any;
    socketEmitter = new EventEmitter<any>();

    constructor() {

        this.socket = io.connect('https://my_socket_address');

        this.socket.on('connect',(data)=>{
        });

        this.socket.on('reconnect', (data)=>{
        })

        this.socket.on('myEvent',(data)=>{
            console.log('received data from socket')
            this.socketEmitter.emit(data);
        }) 
    }
}

Next in my page , i subscribe to the events, when i navigate multiple times between the page, i receive the data emitted multiple times.

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SocketService } from "../../services/socket.service";
import { Injectable, NgZone } from '@angular/core';
import { Router } from '@angular/router';



@Component({
  selector: 'page-selector',
  templateUrl: './template.html',
  styleUrls: ['./page.scss'],
  encapsulation: ViewEncapsulation.None
})


export class Page implements OnInit {
    constructor(private socketService:SocketService) { 
        this.socketService.socketEmitter.subscribe(data:any=>{
            console.log(data)
        })
    })
}

So what you are probably seeing is that the pages that are in the navigation stack are not destroyed when you navigate away from them. So any subscriptions/logic that are in place will still log out values. So you’re not seeing multiple subscriptions, but multiple logs all from the same singleton…if that make sense :smile:

1 Like

To add to what @mhartington said, I would suggest moving the subscription to ngOnInit (since you’re already implementing it), and tearing it down in ngOnDestroy. The ngneat/until-destroy decorator provides a clean way of doing this, but you can always manually manage it if you prefer.

1 Like

Thanks Mike, that was indeed the case. Thanks for the suggestion @rapropos.