DEV Community

Slavius
Slavius

Posted on

Wait for injectable service init() in Angular

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...

Top comments (2)

Collapse
 
geromegrignon profile image
Gérôme Grignon

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.

Collapse
 
slavius profile image
Slavius

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.