0

I have LoginService which MUST be singleton - but angular create two instances and use them randomly - here is my code:

app.module.ts :

providers: [
        { provide: AbstractLoginService, useClass: LoginService },
        { provide: HTTP_INTERCEPTORS, useClass: HTTPDemoInterceptor, multi: true },
        ...
]

HTTPDemo.interceptor.ts :

@Injectable({ providedIn: 'root' })
export class HTTPDemoInterceptor implements HttpInterceptor {

    constructor(
        private AbstractLoginService: LoginService,
    ) { 
      console.log('CONSTRUCTOR HTTPDemoInterceptor');
    }

login.service.ts

@Injectable({ providedIn: 'root' })
export class LoginService implements AbstractLoginService {
    private timestamp = 0

    constructor(private timestamp = 0;) {
        this.timestamp = +new Date();
        console.trace('CONSTRUCTOR LoginService', this.timestamp);
    }

abstract-login.service.ts

@Injectable({ providedIn: 'root' })
export abstract class AbstractLoginService {
   // (no constructor) ...

When I run code I see in console

CONSTRUCTOR LoginService 1632224055035
CONSTRUCTOR LoginService 1632224055036
CONSTRUCTOR HTTPDemoInterceptor

Here are screenshots with stacktraces (first constructor call on left, second on right) - we see clearly that HTTPDemoInterceptor constructor is call only once, but LoginService is called twice. How to fix it?

enter image description here

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • Is the `+` in `this.timestamp = +new Date();` a typo ? – Toodoo Sep 21 '21 at 11:43
  • @Toodoo no - it is only for debug (create timestamp from date shortcut) – Kamil Kiełczewski Sep 21 '21 at 11:45
  • What happens if you remove the @injectable from the login.service? – eko Sep 21 '21 at 11:47
  • @eko if I remove It I get `Error: src/app/app.module.ts:166:16 - error NG2005: The class 'LoginService' cannot be created via dependency injection, as it does not have an Angular decorator. This will result in an error at runtime. Either add the @Injectable() decorator to 'LoginService', or configure a different provider (such as a provider with 'useFactory').` – Kamil Kiełczewski Sep 21 '21 at 11:50

1 Answers1

2

You are providing your service twice, once through the providedIn property in injectable decorator, the other is when you add it to the providers array in your module, that's why there are 2 different instances of the service, just use one approach to provide your service.

Munzer
  • 2,216
  • 2
  • 18
  • 25
  • 1
    wow - It was It - thank you (when I remove `{ providedIn: 'root' }` from `@Injectable` inside `LoginService` it start working properly :) ) – Kamil Kiełczewski Sep 21 '21 at 12:43