Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular service instantiated twice?

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

like image 476
Schadenn Avatar asked Nov 16 '17 11:11

Schadenn


People also ask

Can we have multiple instances of a service in Angular?

By adding service in the component's providers array, we make the nature of service non-singleton. Now it is a service that can be used between parent and child components. In this case, service is a non-singleton nature. It will create multiple instances of a service.

How many instances of service is created in Angular?

Angular give us three way to create instance from our service, and those will cover every use cases we have.

What is the use of providedIn in Angular?

By default, this decorator has a providedIn property, which creates a provider for the service. In this case, providedIn: 'root' specifies that Angular should provide the service in the root injector.

What is injectable ({ providedIn root })?

Simply.. providedIn :'root' creates one instance to the whole application without the need to provide it from any NgModule . Just declaring it in the service through the @Injectable decorator. if you want to have one new instance of this service for any component, then declare it through component's provider.


2 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

like image 118
golfadas Avatar answered Sep 18 '22 07:09

golfadas


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';
like image 29
Ernstjan Freriks Avatar answered Sep 18 '22 07:09

Ernstjan Freriks