The scenario goes as follows:
1. App has root module and it's constructor resolves a Promise and returns a Constant.
@NgModule({
....,
providers : [
...
{
provide: SAMPLE_INJECTOR_TOKEN,
useFactory: sampleFactoryFn(SAMPLE_GLOBAL_CONSTANT.DATA)
}
]
})
export class AppModule {
constructor() {
// To be clear: This code runs on window.onLoad(). window argument is actually window object
setupPromiseAPI(window).then(data => {
SAMPLE_GLOBAL_CONSTANT.DATA = data; // Once promise resolves this gets expected value. [ Step 3 ]
}).catch({
...
})
}
2. As this value is an object and also, as it will be available at run time, I have created a Injection Token using "useFactory" and registered at the module level.
// Injector Token
export SAMPLE_INJECTOR_TOKEN = new InjectionToken<CustomDataType>('SampleInjectorToken');
// Factory Function
export function sampleFactoryFn(data: CustomDataType) {
return (/* No deps to be passed */): CustomDataType => data; // simply return what ever it received.
}
3. I have created a global constant initialized to null and passed as argument to the factory function, using which angular is constructing the Injector Token and assigning the value null (initial state) at bootstrap.
export const SAMPLE_GLOBAL_CONSTANT = {
DATA: null // Initial State
}
4. When promise gets resolved from Step 1, I am capturin the returned constant value from Promise and assiging to this declared Global Constant, as its a constant, obviously that is being updated and available all through the app.
Also, angular documentation states that useFactory provider creates its value lazily, which I am understanding that it will created when its injected. If so, by the time code injects my Injection Token, the global constant is updated. Still the injector token is having null.
Q1. Is there a way, to invoke provider factory function with the updated local state, so that my injector token will have received value?
Q2. As am using global constant, its making the code work, but its not loosely coupled which also making unit testing hard. Are there any alternatives to consume received constant and use it in code, so that it will be loosely coupled?