Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I put business logic intended to transform data meant for the ngrx store: into effects or reducers?

My question relates to ngrx effects and reducers.

I need to transform data retrieved from the backend before putting it into the ngrx store. The data retrieved from the backend is an plain array of Message (Message is a custom type in my application):

Message[]

I need to transform the array into the following:

Map<string, Message[]>

Basically I am grouping a user's messages by the counterparty (recipient or sender) ID (the key).

I am not sure where to perform the transformation from Message[] to Map<string, Message[]>: should I put the transformation business logic into the @Effect or into the reducer function?

like image 935
balteo Avatar asked Mar 14 '17 19:03

balteo


2 Answers

The transformation could go into either the effect or the reducer.

If there were any validation that would need to be performed, I'd put it in the effect - where I'd have the option of dispatching an error action.

Otherwise, I'd put it into the reducer, as that's where I'd typically be transforming action payloads into state.

There is another option, too: you could use a selector. That is, the messages could be stored in the state as a simple array and a selector could be used to transform the state's messages, grouping them by counterparty - or whatever. If I had multiple ways of grouping messages, this is the option that I'd choose.

The @ngrx/example-app contains some examples of selectors:

/**
 * A selector function is a map function factory. We pass it parameters and it
 * returns a function that maps from the larger state tree into a smaller
 * piece of state. This selector simply selects the `books` state.
 *
 * Selectors are used with the `select` operator.
 *
 * ```ts
 * class MyComponent {
 *  constructor(state$: Observable<State>) {
 *    this.booksState$ = state$.select(getBooksState);
 *  }
 * }
 * ```
 */
export const getBooksState = (state: State) => state.books
like image 108
cartant Avatar answered Sep 24 '22 03:09

cartant


The way i do it is to fetch and transform data in a service just like in the old days.

Effects react to an action and make the call through the service to get the data back and dispatch other actions based on the responses it receives.

This makes testing much easier since the service is kept separate from the effect which main purpose is to react on a certain action, not packaging data.

Reducer can be used for this but again you should keep it clean for readability purposes

like image 27
Julian Avatar answered Sep 23 '22 03:09

Julian