1

I am using Angular2 with OpenFin to build an application. I have a service class which is marked as Injectable and is listed as a provider in NgModule. It is being injected into a component but it is only when the component is created that my service class is instantiated. I would like the service class to be created when the application starts up regardless of whether my component is created but when my component is created the instance I created upfront should be injected into the component.

I suspect what I want to do is create an instance of the service at startup and then pass that to Angular to tell it to use that instance when any component requires it. Is that possible or do I have to rely on Angular to instantiate my service.

Thanks Andy

  • It seems like you are looking for a singleton object of the service. You can register your service in `ngModule` decorator of the `rootcompoent`. Then that single instance will be available to be used throughout your application. – micronyks Feb 11 '17 at 20:31

4 Answers4

2

Registering your service in the AppModule's providers meta data will make the service available to any component in the application.

import { YourService } from './your-service.service';

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    ...
  ],
  providers: [YourService], // YourService as a provider to the application
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(private yourService: YourService){
    this.yourService.Init();
  }
}

This is the same a registering a singleton with the container at application start time. Angular will take care of the rest.

Hope this helps you out!

David Walschots
  • 12,279
  • 5
  • 36
  • 59
R. Richards
  • 24,603
  • 10
  • 64
  • 64
  • Thanks for the answer. The issue I have is that the service is only instantiated when the first component that requires it is created - what I want is for the service to be created when the app is started regardless of what component, if any, requests it. – Andrew Coleman Feb 11 '17 at 20:41
  • Is your service written to do something that needs to start right away? Or, do you just want the object to be created, no matter what? – R. Richards Feb 11 '17 at 20:59
  • My service is being used by another service running in another process which is why I do not it to depend upon a component in the same process that also needs it requesting it. Ideally I would create an instance of the service pass it to Angular and Angular would pass it to any component in the same process that needs it. – Andrew Coleman Feb 11 '17 at 21:11
  • I see... I added to this. There is now a constructor in the AppModule that asks for the YourService service, and runs an Init function that may, or may not, be there in your service. I know this will compile; the application will run like this. Will it do what you need considering there is another process involved? No idea. :) – R. Richards Feb 11 '17 at 21:43
  • That does work, so thanks very much. The solution Kemsky provided also works and and although I don't understand yet why it works I prefer it as it only needs something to be added to the serrvice. – Andrew Coleman Feb 11 '17 at 21:53
  • 1
    I think using the implementation of `OnDestroy` for this purpose is very obscure and might very well break in the future. I believe the answer given by R. Richards is the only correct long-term solution for your use case. I'd suggest changing the accepted answer. – David Walschots Feb 11 '17 at 22:13
0

To do this simply register your service in @ngModule decorator of the rootcomponent as shown below,

@NgModule({
  ...
  ...
  providers:[AppService],   //scoped to entire application
  ...
})

Now use this service in any component whenever required.

NOTE : don't try to use/register providers:[AppService] in any individual component. If you try do so, it will create a different instance scoped to that component only.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
micronyks
  • 54,797
  • 15
  • 112
  • 146
0

Angular DI is lazy, but there is one trick make service instantiation eager: you need to implement OnDestroy interface.

kemsky
  • 14,727
  • 3
  • 32
  • 51
  • OK, great I am not in a position to try that now will report back if that does the job. Thank you. – Andrew Coleman Feb 11 '17 at 21:12
  • Just realised I can try this out on an example app I had on my laptop. This solution actually works, not sure why it does and would interested to know why but it does. Thanks very much. – Andrew Coleman Feb 11 '17 at 21:46
  • This is undocumented feature of angular DI, however official documentation mentions that this callback can be used with services https://angular.io/docs/ts/latest/api/core/index/OnDestroy-class.html – kemsky Feb 11 '17 at 21:54
0

You can just provide it as APP_INITIALIZER:

providers: [{provide: APP_INITIALIZER, useClass: YourService, multi: true}],

https://angular.io/docs/ts/latest/api/core/index/APP_INITIALIZER-let.html

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567