Reactable Forms API

RxFormActions

Actions available to trigger state changes on Form Reactable.

updateValues

Updates values of a FormControl. For form group and form arrays, updates will only occur if the specified descendant controls exists. Otherwise it will throw an error.

type updateValues = <T>(payload: UpdateValuesPayload<T>) => void;

interface UpdateValuesPayload<T> {
  value: T;
  controlRef: ControlRef;
}

addControl

Adds a control to a form group.

type addControl = (payload: AddControlPayload) => void;

interface AddControlPayload {
  config: AbstractControlConfig;
  controlRef: ControlRef;
}

pushControl

Pushes a control to a form array.

type pushControl = (payload: PushControlPayload) => void;

interface PushControlPayload {
  config: AbstractControlConfig;
  controlRef: ControlRef;
}

removeControl

Removes a specified control from the form.

type removeControl = (payload: ControlRef) => void;

markControlAsPristine

Marks a control and all descendant controls as pristine.

type markControlAsPristine = (payload: ControlRef) => void;

markControlAsTouched

Marks a control and all ancestors as touched. Can set markAll to true to mark all descendants as touched as well (defaults to false).

type markControlAsTouched = (payload: MarkTouchedPayload) => void;

interface MarkTouchedPayload {
  controlRef: ControlRef;
  markAll?: boolean;
}

markControlAsUntouched

Marks a control and all descendants as untouched. This will recheck ancestor controls and update the touched status.

type markControlAsUnTouched = (payload: ControlRef) => void;

resetControl

Resets a control by removing existing control and rebuilding it with the original configuration.

type resetControls = (payload: ControlRef) => void;

FormBuilders

build

Factory function for creating a form Reactable. Accepts a configuration object generated by one or more helper methods - control, group, array. Also accepts an RxFormOptions object.

type build = (config: AbstractControlConfig, options?: RxFormOptions) => Reactable<Form<unknown>, RxFormActions>

load

Function to create a reactable from a previously saved form state.

type load = <Value, Actions = RxFormActions>(
  state: Form<Value>,
  options: RxFormOptions = {},
) => Reactable<Form<Value>, Actions>

RxFormOptions

Options to customize RxForm behaviour.

export interface RxFormOptions extends EffectsAndSources {
  reducers?: CustomReducers<unknown>;
  providers?: RxFormProviders;
  name?: string;
  debug?: boolean;
  storeValue?: boolean;
}
PropertyDescription
reducers (optional)Dictionary of CustomReducers to implement custom form behaviour. The CustomReducerFunc(#api-custom-reducers) provides built in FormReducers. Form state updates need to be made with FormReducers to maintain integrity of the form state tree (i.e validation states of parent and child controls).
effects (optional)Array of Effects to be registered to the Reactable.
sources (optional)Additional Action Observables the Reactable is listening to. Can be an array or a dictionary where key is the action type and value is the Observable emitting the payload.
providers (optional)See RxFormProviders which provides the ValidatorFns, ValidatorAsyncFns and normalizer functions to be used in form

RxFormProviders

The key in the dictionaries should match the name declared for the validator/normalizer in the configuration creation with control, array and group.

type NormalizerFunction<T> = (value: T) => T;

export interface RxFormProviders {
  normalizers?: { [key: string]: NormalizerFunction<unknown> };
  validators?: { [key: string]: ValidatorFn };
  asyncValidators?: { [key: string]: ValidatorAsyncFn };
}

control

Function to create a FormControlConfig configuration object. Accepts a configuration object or a tuple.

type control = <T>(config: FormControlConfig<T> | FbControl<T>) => FormControlConfig<T>

interface FormControlConfig<T>  {
  initialValue: T;
  validators?: ValidatorFn[];
  asyncValidators?: ValidatorAsyncFn[];
}

type FbControl<T> = [T, (ValidatorFn | ValidatorFn[])?, (ValidatorAsyncFn | ValidatorAsyncFn[])?];

group

Function to create a FormGroupConfig configuration object. Accepts a configuration object containing a controls dictionary of additional configuration objects generated by control, group, or array.

type group = (config: FormGroupConfig) => FormGroupConfig

interface FormGroupConfig{
  validators?: ValidatorFn[];
  asyncValidators?: ValidatorAsyncFn[];
  controls: { [key: string]: AbstractControlConfig };
}

array

Function to create a FormArrayConfig configuration object. Accepts a configuration object containing a controls array of additional configuration objects generated by control, group, or array.

type array = (config: FormArrayConfig) => FormArrayConfig

interface FormArrayConfig {
  validators?: ValidatorFn[];
  asyncValidators?: ValidatorAsyncFn[];
  controls: AbstractControlConfig[];
}

Other Interfaces

Form

Form state. Dictionary of FormControl(s) where the key is a period separated representation of the ControlRef tuple.

interface Form<T> {
  root?: FormControl<T>;
  [key: string]: FormControl<unknown>;
}

FormControl


interface FormControl<T> {
  pristineValue: T;
  controlRef: ControlRef;
  value: T;
  dirty: boolean;
  touched: boolean;
  validatorErrors: FormErrors;
  key: string;
  asyncValidatorErrors: FormErrors;
  asyncValidateInProgress: { [key: string | number]: boolean };
  errors: FormErrors;
  valid: boolean;
  childrenValid: boolean;
  pending?: boolean;
  config: AbstractControlConfig;
}
PropertyDescription
pristineValueOriginal value of control. Use to determine if control is dirty.
controlRefControls ControlRef.
valueControl value.
touchedTouched status of control
validatorErrorsFormErrors from validators (non-async)
asyncValidatorErrorsFormErrors from async validators
errorsFormErrors validatorErrors and asyncValidatorErrors merged.
validValid status of control. Also checks descendants.
childrenValidValid status of direct child controls.
configOriginal config for form control

ControlRef

Control Reference represented as a tuple for the FormControl

FormErrors

Dictionary of errors for the control.

interface FormErrors {
  [key: string]: boolean;
}

ValidatorFn

Validator function that reads the value of the FormControl and returns a FormErrors object.

type ValidatorFn = (value: unknown) => FormErrors

ValidatorFnAsync

Validator function takes in an BaseControl observable and returns an Observable<FormErrors>.

type ValidatorAsyncFn = <T>(control$: Observable<BaseControl<T>>) => Observable<FormErrors>;

FormReducers

Built in reducers which can be used to update the state of the form tree. Payload and behaviour is the same and described in RxActions;


interface FormReducers {
  updateValues: <T>(state: BaseFormState<T>, payload: UpdateValuesPayload<unknown>,
  ) => BaseFormState<T>;
  removeControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
  pushControl: <T>(state: BaseFormState<T>, payload: PushControlPayload) => BaseFormState<T>;
  addControl: <T>(state: BaseFormState<T>, payload: AddControlPayload) => BaseFormState<T>;
  markControlAsPristine: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
  markControlAsTouched: <T>(state: BaseFormState<T>, payload: MarkTouchedPayload) => BaseFormState<T>;
  markControlAsUntouched: <T>(state: BaseFormState<T>, payload: ControlRef,
  ) => BaseFormState<T>;
  resetControl: <T>(state: BaseFormState<T>, payload: ControlRef) => BaseFormState<T>;
}

CustomReducers

export type CustomReducerFunc = (
  reducers: FormReducers,
  state: BaseFormState<unknown>,
  action: Action<unknown>,
) => BaseFormState<unknown>;

export type CustomReducer =
  | CustomReducerFunc
  | {
      reducer: CustomReducerFunc;
      effects?: Effect<unknown, unknown>[] | ((payload?: unknown) => ScopedEffects<unknown>);
    };

export type CustomReducers<T> = {
  [key in keyof (T & {
    [key: string]: CustomReducer;
  })]: CustomReducer;
};

BaseFormState

Form state before it is fully validated. This is accessible in CustomReducers so developer can read the current state and implement custom form behaviours.

interface BaseFormState<T> {
  form: BaseForm<T>;
}

interface BaseForm<T> {
  root?: BaseControl<T>;
  [key: string]: BaseControl<unknown>;
}

BaseControl

BaseControl contains some control information before a fully validated FormControl is created.


interface BaseControl<T> {
  pristineValue: T;
  controlRef: ControlRef;
  value: T;
  dirty: boolean;
  touched: boolean;
  validatorErrors: FormErrors;
  config: AbstractControlConfig;
  key: string;
}