I am fairly new to Typescript/JavaScript. So this probably a noob question:
I have a Typescript class, lets call it serviceActions.
In the constructor of that class I make a connection to a Web API service via BreezeJS. I also get the metadata for service (fetchMetadata).
However, the fetchMetadata call returns a promise. So the constructor returns before it is done.
Now this serviceActions class is injected (via Aurelia) into another class:
@autoinject
export class BoxVm {
constructor(serviceActions: serviceActions) {
this.box = this.serviceActions.createNewBox();
}
So I never really get to await anything. So when the createNewBox is called, the fetchMetadata call is not done, and the call errors out.
Now I could put in an initialize method on my ServiceActionsclass. But then I have to wrap everything I do in my BoxVM in the promise for that. All calls to get data, save data create any entity would have to be done in a call to initalize.then.
Is there another way? Am I missing the point? Or is this the way that Typescript/JavaScript is done?
The problem is that ServiceActions is waiting for a promise to be fulfilled before it can be usable. There are several solutions:
await the results of a promise. Your createNewBox function will wait patiently for the promise to finish before returning. This is the cleanest solution.fetchMetadata into the constructor (possibly making the call before running your DI framework initialization). This avoids the problem.initialize().then, though it seems mildly error-prone (someone might forget to wrap code in init).onInit function in ServiceActions that takes a callback - it's a mildly refactored version of what you're suggesting.createNewBox return a promise to hand over a new Box once ServiceActions is done waiting for the fetchMetadata promise. This might pollute everything with many promises.I would try for option 2, especially since you seem to need to call this only once.
I think this is more a question of how your framework works with dependency injection. Syringe lets you inject a "lazy" dependency, which you have to call .get().then(callback) on in order to use that dependency.
In general, though, yes: any time you need to use something that gets produced by an asynchronous operation, you're going to need to access it through the promise interface. This will become syntactically easier once TypeScript adds better async/await support, but you can't just assume you've got access to a resource for injection if that resource is produced via an asynchronous operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With