Question: 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**?

Answer: 
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](https://github.com/ngrx/example-app/blob/master/src/app/reducers/index.ts#L86-L101):

```ts
/**
 * 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

```
My opinions: 

1. Data retrieved from backend will be kept unchanged in the store.
2. Using selectors as your business logic (combine, transform and etc.) for the dumb components.
3. Maybe the only transformation is to use normalizr to flat the data.