Angular service instantiated twice?

Viewed 4212

somehow I've got a service that seems to be instantiated twice (its properties are not in sync), by doing the following:

@Component
export class MyComponent extends someOtherComponent {
  constructor(service: Service, service2: Service2) {
    super(service, service2);
  }

  isStateEqual() {
    return this.service.serviceState === this.service2.service.serviceState;
  }
}

@Injectable
export class Service {
  serviceState = {}
}

@Injectable
export class Service2 {
  constructor(service: Service) {}
}

This is just a very basic example, but that's what it comes down to. To be more precise: We're building our own datepicker and extending NgbDatepicker component which has KeyMapService (this uses NgbDatepickerService) and a local NgbDatepickerService.
Here is a link to the component: https://ng-bootstrap.github.io/#/components/datepicker/examples

In our app isStateEqual will always return false (even right after initialising the component) while in the demo you can find in the link above it will always return true (which is how it should be).

Anyone knows why it could be like that?

Thanks in advance.

Regards Dennis

5 Answers

Application wide singletons must be defined on the bootstrapped module:

platformBrowserDynamic()
  .bootstrapModule(AppModule)

@NgModule({
  providers: [SingletonService1, SingletonService2],
  bootstrap: [AppComponent]
})

export class AppModule {}

source

or by setting providedIn: 'root' on the service decorator:

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

source

In my case the service was instantiated twice, because I imported the service using two different approaches (my IDE (VS2019) mishelped me here by automatically generating the incorrect import):

import { Service } from '@mycompany/mymodule' 

and

import { Service } from '../../../dist/@mycompany/mymodule/@mycompany-mymodule';

Visual code import my service in this way automatically

import { ConfigService } from 'src/app/services/config.services.js';

And the correct way is:

import { ConfigService } from 'src/app/services/config.services';

It depends where you declare the provider for your services - this determines the scoping. You don't specify in your question where you've done this - try doing it in AppModule, for example.

"service" must be a public propertie of Service2.

@Injectable
export class Service2 {
  service:Service
  constructor(service: Service) 
  {
      this.service=service;
  }
}
Related