MrWolfZ/ngrx-forms

Reset form except 1 value

MarkHesk opened this issue · 2 comments

Hey,
hope this is the right place to post it.

I have the following reducer.ts:

export interface FormValue {
  stage: Stages,
  stati: boolean[];
  aktion: boolean[];
  workflow: boolean[];
  user: string;
  idTask: string;
  stammNr: string;
  erstellt: string;
}

export const DOCTRANS_FORM_INITIAL_STATE = createFormGroupState<FormValue>(FORM_ID, {
  stage: Stages.LOKAL,
  stati: new Array(Object.keys(Status).length).fill(false),
  aktion: new Array(Object.keys(Aktion).length).fill(false),
  workflow: new Array(Object.keys(Workflow).length).fill(false),
  user: '',
  idTask: '',
  stammNr: '',
  erstellt: ''
});

export interface State {
  entities: DoctransEntity[];
  errorMessage: string;
  loading: DataState;
  formState: FormGroupState<FormValue>;
}

export const doctransInitialState: State = {
  entities: [],
  errorMessage: null,
  loading: DataState.LOADED_STATE,
  formState: DOCTRANS_FORM_INITIAL_STATE
}

const _doctransReducer = createReducer(
  doctransInitialState,
  onNgrxForms(),
);

export function doctransReducer(state: State, action: Action) {
  return _doctransReducer(state, action);
}

When i want to reset the form i can call:

this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.id, DOCTRANS_FORM_INITIAL_STATE.value));

But i would like to reset it except of the stage.

What i do now:

    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.stati.id, DOCTRANS_FORM_INITIAL_STATE.value.stati));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.aktion.id, DOCTRANS_FORM_INITIAL_STATE.value.aktion));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.workflow.id, DOCTRANS_FORM_INITIAL_STATE.value.workflow));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.user.id, DOCTRANS_FORM_INITIAL_STATE.value.user));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.idTask.id, DOCTRANS_FORM_INITIAL_STATE.value.idTask));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.stammNr.id, DOCTRANS_FORM_INITIAL_STATE.value.stammNr));
    this.store.dispatch(new SetValueAction(DOCTRANS_FORM_INITIAL_STATE.controls.erstellt.id, DOCTRANS_FORM_INITIAL_STATE.value.erstellt));

But i think there must be a better way. Maybe some reducer which says "reset all but keep stage".

Thanks

Maybe not the most efficient way, but you could save the values you want to keep before resetting and then set them back.

I certainly think there's a better way to write this than setting each control individually. You can set the form value as a whole, in a single action. To what @Balastrong said, just grab the value you don't want to reset, and make sure that is the value you set on top of your initial state. My approach would be to do this in your own action, something like

// dispatch action you've created - obviously name whatever makes sense to you
this.store.dispatch(softResetForm())

/* in your reducer */
on(actions.softResetForm, (state) => {
  // get the current value for `stage`
  const { stage } = state.formState.value;
  // create a value from your initial form state, with `stage` overridden with the value above
  const softResetValue = { ...DOCTRANS_FORM_INITIAL_STATE.value, stage };

  // use `reset()` on your formState if, if you want reset to pristine - if not leave out
  // use `setValue()` on the entire formState, providing the value defined above
  const formState = setValue(reset(state.formState), softResetValue);

  // update your state
  return { ...state, formState };
})