0
votes

I am using ngrx/store in my Angular 5 project. The Application state I store looks something like this

class AppState{
    private customerList: Customer [];
    private selectedCustomer: Customer;
    private countriesOperational: Country [];
}

I have individual reducers for each property of the state object, so I can listen to changes individually for each property. This state is then exposed via a service to the application components.

In my reducer (SelectedCustomerReducer), one of the actions is to replace the currently selected customer (2nd property above) with a new Customer object. I am confused about how the reducer should return the new value.

My reducer, already gets a new Customer object in the action.payload; so should i just return that as the new state?

For e.g.

export function SelectedCustomerReducer(state: Customer = new Customer(), action: Action){
    switch(action.type){
        case 'updateSelectedCustomer':
               return action.payload; 
               //OR               
               return Object.assign({}, state, action.payload);
    }
}
1
I don't think that you should have a SelectedCustomerReducer. Rather just a CustomersReducer where at the top level of it you have a variable selectedCustomermaxime1992
Do you mean a single reducer for the entire AppState? And in the CustomersReducer should I return a new instance of AppState, whenever a property changes? For e.g. if selectedCustomer changes, do I return a new instance of AppState with the corresponding property updated?Vikas

1 Answers

0
votes

First of all you have to initialize your "Reducers" into "app.module.ts".

import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';

import { AppComponent } from './app.component';
import { Reducers } from './store/app.reducers';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    StoreModule.forRoot(Reducers)
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Then you have to place all your "Reducers" into "ActionReducerMap". It is generic type and needless to say you must to hand interface with actions into "app.reducers.ts" file maybe. Look code below.

import { ActionReducerMap } from '@ngrx/store';

import * as shoppingList from '../shopping-list/store/shopping-list.reducers';

export interface AppState{
  shoppingList: shoppingList.State,
}

export const reducers: ActionReducerMap<AppState> = {
  shoppingList: shoppingList.shoppingListReducer
}

Then you can to create "Reducer" and to hand "State" and "Action" maybe into "shopping-list.reducers.ts" file

import * as productListActions from './shopping-list.actions';
import { Product } from '../product/product.model';

export interface State{
  products: Product[];
}

const initialState: State = {
  products: [
    new Product('PC', 5),
    new Product('OS', 10),
  ]
};

export function shoppingListReducer(state = initialState, action: productListActions.ProductListActions){
  switch(action.type){
    case productListActions.ADD:
      return {
        ...state,
        products: [...state.products, action.payload]
      };
    default:
      return state;
  }
}