Search code examples
angularrxjsngrxangular-forms

How can I use rxjs operators along with ngrx-form?


[This question is about ngrx-forms]

Question 1.

Imagine that this is my reducer.ts

//reducer.ts

import { Action, combineReducers } from '@ngrx/store';
import { createFormGroupState, formGroupReducer, FormGroupState } from 'ngrx-forms';

import { State as RootState } from '../app.reducer';

export interface FormValue {
  firstName: string;
  lastName: string;
  email: string;
  sex: string;
  favoriteColor: string;
  employed: boolean;
  notes: string;
}

export interface State extends RootState {
  simpleForm: {
    formState: FormGroupState<FormValue>;
  };
}

export class SetSubmittedValueAction implements Action {
  static readonly TYPE = 'simpleForm/SET_SUBMITTED_VALUE';
  readonly type = SetSubmittedValueAction.TYPE;
  constructor(public formValue: FormValue) { }
}

export const FORM_ID = 'simpleForm';

export const INITIAL_STATE = createFormGroupState<FormValue>(FORM_ID, {
  firstName: '',
  lastName: '',
  email: '',
  sex: '',
  favoriteColor: '',
  employed: false,
  notes: '',
});

const reducers = combineReducers<State['simpleForm'], any>({
  formState(s = INITIAL_STATE, a: Action) {
    return formGroupReducer(s, a);
  }
});

export function reducer(s: State['simpleForm'], a: Action) {
  return reducers(s, a);
}

& each field is connected to ngrx-forms state via


//template html

[ngrxFormControlState]="(formState$ | async).controls.firstName"
[ngrxFormControlState]="(formState$ | async).controls.lastName"
[ngrxFormControlState]="(formState$ | async).controls.email"

...

How can I add a debounceTime() and distinctUntillChanged() or any other rxjs operators for each of the form fields before the values reaches the store (or leaves)?

with angular's native form-builder we can pipe the valueChanges property:

this.myControl.valueChanges
.pipe(
 distinctUntilChanged(),
 debounceTime(200)
)

How can we achieve something similar with ngrx-forms

Remember that the state doesnot contain any custom actions We are dealing with the native ngrx-forms actions only (like ngrx/forms/SET_VALUE etc,..).

Something like intercepting between template/component & the store.


Question 2.

How can we customize the labels for ngrx-forms native actions like : ngrx/forms/SET_VALUE, ngrx/forms/MARK_AS_TOUCHED to some custom labels?


Solution

  • Author of ngrx-forms here.

    Question 1

    Instead of trying to debounce values before reaching the store, I would suggest you debounce the value before any observable side-effect occurs. The core model of ngrx-forms is to keep the state and view in sync.

    For example, similar to your example from @angular/forms you can use the following to debounce a form value:

    this.store.select(s => s.myForm.value.myControl).pipe(debounceTime(200))
    

    Question 2

    It is not possible to customize the action types of ngrx-forms.