Reputation: 2866
I'm trying to load some cached details when app initializing. I'm using builtin APP_INITIALIZER
provider of angular.
In this provider I'm running the init method of the AppService
and loading those cached information, dispatching some actions. 3 of 4 actions are gracefully dispatching but when I try to dispatch order details reducer doesn't get this action and I can't transfer order details to store.
But when I look at redux chrome extension I'm able to see my action that getting dispatch, but if I log incoming actions in reducer I can't see my action.
The weird part it is if I run loadCachedOrderDetails
method after three seconds later with setTimeOut method, setCachedOrderDetails
action dispatched successfully..
What is exactly happening ? How can I dispatch setCachedOrderDetails
action properly ?
Here is full definition of the provider
{
provide: APP_INITIALIZER,
useFactory: (app: AppService) => () => app.init(),
deps: [AppService],
multi: true
}
AppService init method
init() {
const request = this.loadCachedRequest();
if (request) {
this.loadCurrentLocation(request);
}
this.loadCachedBasketItems();
this.loadCachedOrderDetails();
}
and the method
loadCachedOrderDetails() {
const details = JSON.parse(localStorage.getItem('orderDetails'));
if (details) {
this.store.dispatch(PanelActions.setCachedOrderDetails({details}));
}
}
and panel store where I register the reducer
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule
]
})
export class PanelStoreModule {
}
Upvotes: 3
Views: 1101
Reputation: 13539
If you use EffectsModule.forFeature
it means this module isn't main one and your app has been initialized already and your module was highly likely lazyloaded or initialized later once app is needed in it.
Therefore you can't rely on any INIT triggers. Because they can emit earlier than your feature has been set and is ready to listen to actions.
but you can simply use constructor of your module to dispatch required actions.
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule,
]
})
export class PanelStoreModule {
constructor(app: AppService) {
app.init();
}
}
Or simply move the effect and the reducer to the forRoot
part.
Upvotes: 2