Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for examples to immer produce with the ngrx 8

Looked around the web and can't find an example of using import produce, {Draft} from "immer"; with the ngrx on() the closest I can find is: a non complete solution on: https://github.com/immerjs/immer/issues/252

import produce, { Draft } from 'immer';
import { ActionCreator, createReducer, on } from '@ngrx/store';
import { ActionType, FunctionWithParametersType } from '@ngrx/store/src/models';

function produceOn<Type extends string, C extends FunctionWithParametersType<any, object>, State>(
  actionType: ActionCreator<Type, C>,
  callback: (draft: Draft<State>, action: ActionType<ActionCreator<Type, C>>) => any,
) {
  return on(actionType, (state: State, action): State => produce(state, (draft) => callback(draft, action)));
}

// Usage:

const featureReducer = createReducer(
  initialState,
  produceOn(action, (draft, action) => {
     // TODO STUFF
  }
);

export function reducer(state = initialState, action) {
  return featureReducer(state, action);
}

not sure how to incoperate the on() with immer with ngrx 8

Sean.

like image 425
born2net Avatar asked Jul 10 '19 04:07

born2net


2 Answers

found the answer:

import {createReducer} from '@ngrx/store';
import {on} from "@ngrx/store";
import produce, {Draft} from "immer";

export const initialUserState: IUserState = {
    knownUsers: [user1, user2],
    selectedUser: null,
    scenes: null
};

export function produceOn<Type extends string, C extends FunctionWithParametersType<any, object>, State>(
    actionType: ActionCreator<Type, C>,
    callback: (draft: Draft<State>, action: ActionType<ActionCreator<Type, C>>) => any,
) {return on(actionType, (state: State, action): State => produce(state, (draft) => callback(draft, action)));}

export const loadRequest = createAction('[Scenes API] Scene Load Request', props<{ businessId: BusinessId }>());
export const loadSuccess = createAction('[Scenes API] Scene Load Success', props<{ scenes: List<SceneModel> }>());

// ngrx 8+ with immer and support for on() within reducer

const featureReducer = createReducer(
    initialUserState,
    produceOn(loadSuccess, (draft, action) => {
        draft.scenes = {myList: [1,2,3]};
    }),
    produceOn(loadFailure, (draft, action) => {
        draft.scenes = {myList: []};
        console.log('error loading...');
    })
);
like image 55
born2net Avatar answered Oct 27 '22 23:10

born2net


There is an repo from a ngrx-maintainer https://github.com/timdeschryver/ngrx-etc which gives you a mutableOn function, which can be used like here

mutableOn(increment, (state, {incrementBy}) => {
  state.count += incrementBy;
})
like image 45
Bene Avatar answered Oct 28 '22 01:10

Bene