Anton Bohomaz
Anton Bohomaz

Reputation: 99

Multiple instantiations of singleton service in angular 6

I have an angular service provided in root

import {Injectable} from "@angular/core";
import {BehaviorSubject} from "rxjs";
import {Admin} from "../models/admin.model";
import {AdminsService} from "./admins.service";

@Injectable({
  providedIn: 'root'
})
export class CurrentUserService {
  public user$: BehaviorSubject<Admin> = new BehaviorSubject(null);

  constructor(private _adminsService: AdminsService) {
    console.log('current user service instantiated');
    this._adminsService.getCurrentUser()
      .subscribe(user => {
        this.user$.next(user);
      });
  }

  public update() {
    this._adminsService.getCurrentUser().subscribe(user => {
      this.user$.next(user);
    })
  }

  public clear() {
    this.user$.next(null);
  }
}

I provide it and Http Interceptor in app.module in this way:

providers: [
    CurrentUserService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ],

And when I try to inject it into interceptor i get a lot of messages from constructor, that indicates that service instantiates many times. Can anybody explain this behavior and may be have some idea of how to fix it?

console with messages screenshot

Upvotes: 1

Views: 656

Answers (2)

pmartinezga
pmartinezga

Reputation: 1

Another option is deleting the second declaration. If you use useExisting instead of useClass then the framework won't create a new instance of the class but tries to find an existing instance of the class that is the one created in the first declaration.

In summary, you can have the

@Injectable({
  providedIn: 'root'
})

and the provider as:

providers: [
    CurrentUserService,
    {
      provide: HTTP_INTERCEPTORS,
      useExisting: AuthInterceptor,
      multi: true
    }
  ],

Upvotes: 0

Sunil
Sunil

Reputation: 11241

This is because of you are providing the same service multiple times in the same module -

First by

@Injectable({
  providedIn: 'root'
})

Second by

providers: [
    CurrentUserService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ],

Better you remove from the first one.

Upvotes: 2

Related Questions