0
votes

I have a very serious architecture issue using ngrx in my angular App.

So i have a multiple Store module for this i use forFeature in each store module and i have one root store module.

My Root store module look like store.module.ts

export interface RootState {
     rootAuthState: RootAuthState,
     rootRefState: RootRefState,
     rootProductState:RootProductState
   }

 @NgModule({
        imports: [
            AuthModule,
            RefModule,
            ProductModule,
            StoreModule.forRoot([]),
            EffectsModule.forRoot([])
        ],
        exports: [
            StoreModule
        ]
    })

export class SharedStoreModule { }

My child store module look like product.module.ts

export interface Product {
    product: ProductState
}
export const reducers: ActionReducerMap<Product> = {
    product: prouctReducers.product
}

@NgModule({
    imports: [
        StoreModule.forFeature('proudct', reducers),
        EffectsModule.forFeature([ProductEffect]),
    ],
    providers: [
        ProductService
    ]
})
export class ProductModule {
}

My issue when i dispatch action after action, for example when i want a list of products i use this this.store.dispatch(new ListProductAction()); now when i select list i get list of product using code above

this.store.pipe(select(SelectListOfProduct)).subscribe(res => {
    console.log(res); // i get list [{"id": 1},{"id": 2}]
 });

But when i dipatch new action for example this.store.dispatch(new CountClickedAction()); of other store my list of product become empty, res in code above become undefinded

this.store.pipe(select(SelectListOfProduct)).subscribe(res => {
        console.log(res); // undefinded
     });

For each store i add own reducer example product.reducer.ts

  export function prouctReducer(state = initProductState, action: ProductActions): ProductState {
    switch (action.type) {
        case GET_LIST_PRODUCT: {
            return {
                listProduct: null,
            }
        }
        case GET_LIST_PRODUCT_SUCCESS: {
            return {
                ...state,
                listProduct: action.payload
            };
        }
        case GET_LIST_PRODUCT_FAILURE: {
            return {
                ...state,
            };
        }
      }
  }

Example auth reducer auth.reducer.ts

export function authReducer(state = initAuthState, action: AuthActions): AuthState {
        switch (action.type) {
            case GET_COUNT: {
                return {
                    count: null,
                }
            }
            case GET_COUNT_SUCCESS: {
                return {
                    ...state,
                    count: action.payload
                };
            }
            case GET_COUNT_FAILURE: {
                return {
                    ...state,
                };
            }
          }
      }

The purpose i want to get state like this rootProductState: {listProduct:[{"id": 1},{"id": 2}]} rootAuthState: {count: 5}

But actuel geted rootProductState: {listProduct:[]} rootAuthState: {count: 5}

How to avoid delete list when i dispatch new action ? any idea and thanks.

2
May be an issue with your reducer. Why not show it?pixelbits

2 Answers

0
votes

You forgot to preserve the original state:

        case GET_COUNT: {
            return {
                ...state,
                count: null,
            }
        }
0
votes

OMG, my issue was because i didn't add default to mes reducers

The above code resolve my issue that i spent a lot of time :(

default: {
  return state;
}

So my productReducer and all other reducers has now default

export function prouctReducer(state = initProductState, action: ProductActions): ProductState {
    switch (action.type) {
        case GET_LIST_PRODUCT: {
            return {
                listProduct: null,
            }
        }
        case GET_LIST_PRODUCT_SUCCESS: {
            return {
                ...state,
                listProduct: action.payload
            };
        }
        case GET_LIST_PRODUCT_FAILURE: {
            return {
                ...state,
            };
        }
      default: {
        return state;
         }
      }
  }