Wait for injectable service init() in Angular
Slavius

Slavius @slavius

About: Currently developing futuristic smart-device, IoT connected, highway construction site safety system in EU. Used to work on infrastructure, application architecture and cloud engineering.

Location:
Slovakia, Europe
Joined:
Aug 9, 2018

Wait for injectable service init() in Angular

Publish Date: Aug 6 '20
3 2

Hey Angularists,

I'm learning Angular and I still cannot figure out one important thing to do properly.

What I'm trying to achieve is to create global @Injectable Service that has some initialization function that needs to finish before the Service should be used.

Right now the Service does its initialization in the constructor, as AFAIK services do not use ngOnInit() functions. Let's say the initialization calculates some random prime number which takes about 200ms to finish.

Unfortunately when the Service is injected into a Component and a public function of the Service that's supposed to return this prime number is being called in the onInit() of the Component the returned value is always undefined as the constructor of that Service did not finish yet at that time.

Of course if there would be some async function to call (e.g. an HttpClient) I would return a Promise or Observable and subscribe to it in the Component. However the constructor does not call any of it.

I also tried EventEmitter and emit true at the end of the constructor work when the initialization is done while subscribing to it in the Component OnInit function. This however does not work for me for some reason and it never receives the emitted event.

I come from C# and I simply find it amusing that DI can provide you with an uninitialized object. ;)

I found possible solution with APP_INITIALIZER and ProviderFactory but I find it too complex so I wanted to know about other options.

Any advice and help on how this should be properly handled in Angular is welcome. Thanks in advance!

Edit: I figured out that when I hide the property behind a function call getPrime() { return this.prime; } it works. However it's still a mystery to me how a non-static property can be read before the constructor has finished...

Comments 2 total

  • Gérôme Grignon
    Gérôme GrignonAug 10, 2020

    another solution would be to delegate the calculation to a function inside your service. This function would ever return the already calculated value or calculate it and save it for further usages.

    • Slavius
      SlaviusAug 19, 2020

      I see the point. I believe though that does not cover my requirement to get that value as observable to be able to wait for it to finish and continue my code inside the component when the value is ready.

Add comment