Ionic 3 - Ngrx Feature State is empty

Hi all,

I finished an Ionic v3 app that has a lot of lazy loaded pages.

The problem is that when I build the app with the prod flag, all the state belonging to lazy loaded pages is empty. If I move those same reducers to the main store everything works fine. I already shipped an angular 5 application with lazy loaded modules + ngrx and everything works fine.

Does anyone has a solution besides transfering all the reducers to the main store?

Something’s wrong in your code. You do not need lazily loaded state slices to be in your global state. Defeats the purpose. Do you define a lazily loaded store?

I do know that…thats the reason why I opened this topic. Everything works fine in dev mode, it’s only when AOT is enabled that the lazy loaded reducers are empty

I can’t say anything specific if you don’t share code. Whatever you’re doing, it breaks in ngc/ngo. It might be a really simple fix, if it works in dev mode. If you aren’t comfortable posting code, take a look at this thread, to see what might be causing your code to break. What does --prod flag do exactly?

I can post code no problem. So this is my main store. The “cartoons” reducer is working now, but it is originally a lazy loaded page with it’s own reducer.

export interface IAppState {
    notifications: fromNotifications.NotificationsState,
    menu: fromMenu.State,
    cartoons: fromCartoon.State
}

export const reducers: ActionReducerMap<IAppState> = {
    notifications: fromNotifications.reducer,
    menu: fromMenu.reducer,
    cartoons: fromCartoon.cartoonsReducer
};


export function logger(reducer: ActionReducer<IAppState>): ActionReducer<any, any> {
    return function (state: IAppState, action: any): IAppState {
        console.log('state', state);
        console.log('action', action);

        return reducer(state, action);
    };
}

export const metaReducers: MetaReducer<IAppState>[] = !environment.production
    ? [logger/* , storeFreeze, localStorageSyncReducer */]
    : [/* localStorageSyncReducer */];

And this is the original lazy loaded cartoon reducer:

export interface CartoonState {
    cartoons: fromCartoons.State;
}

export interface State extends fromRoot.IAppState {
    cartoons: CartoonState;
}

export const reducers: ActionReducerMap<CartoonState> = {
    cartoons: fromCartoons.cartoonsReducer
};

export const selectCartoonState = createFeatureSelector<CartoonState>(CommonEntities.CARTOONS.toLowerCase());

export const getCartoonState = createSelector(
    selectCartoonState,
    (state: CartoonState) => state.cartoons.obj ? state.cartoons.obj.items : null
)

export const isLoading = createSelector(
    selectCartoonState,
    (state: CartoonState) => state.cartoons.loading
)

export const getCartoonPage = createSelector(
    selectCartoonState,
    (state: CartoonState) => state.cartoons.pageNumber
)

export const isFinished = createSelector(
    selectCartoonState,
    (state: CartoonState) => state.cartoons.finishedPages
)

This is in ngrx 4?

…post must be 20 characters…

It’s ngrx v5 with angular v5

In my own code, I have lazily loaded features modules. Some of those features have their own stores. Let’s say there’s a feature Foo. I don’t make the Foo store extend the fromRoot store. Instead, I have what you could consider a second root, that only exists while the Foo feature is loaded. Store<fromFoo> instead of Store<fromRoot> so to speak.

And you initializite in the feature module with StoreModule.forFeature right?

I will try that approach. But this approach is the same I used in my last Angular App and the same it is used in the Ngrx Example App

I haven’t looked at that example for maybe 5 months, but it isn’t lazy loaded I don’t think. At least it didn’t use to be, and I don’t see loadChildren after looking now for 1 minute. At any rate, I’m not 100% sure of the best practice here, but I know my way works for my use case. I define a rootStore that I can call root actions on, if I need to do that in a lazily loaded page. And I define a more local store, the Foo store, with which I can perform the foo actions.

loadChildren is from Angular Router, Ionic3 does not use Angular router. I don’t have this problem with an angular-only project. Just with Ionic and it’s lazy loaded pages.

And yes in that example the book module is lazy loaded.

Maybe move to Ionic 4 then? Sidestep the problem completely.

Ionic 4 is not even in the final version, I would have to rewrite a lot of code, and the app ships next week lol.

If there is no workaround I’ll keep the lazy loaded pages, but the reducers move to being eagerly loaded.