NgrxForm
A lib for Angular that binds reactive-forms and @ngrx/store together. Every change in a form is reflected in the store and vice versa. The store object for each form is automatically generated by the library.
The lib is designed to work in a feature modules, but it can be implemented in the root module as well. A feature module can handle multiple forms.
Installation
Npm : npm i @yoozly/ngrx-form -s
Yarn : yarn add @yoozly/ngrx-form
Setup
Root Module
In the root module of your application, add ngrxForm
in the array of metareducers
import { ngrxForm } from '@yoozly/ngrx-form';
@NgModule({
StoreModule.forRoot(reducers, {
metaReducers: [ngrxForm]
})
})
export class RootModule {}
Feature Module
First, we need to import the following dependendies in the feature module :
NgrxFormModule
NgrxFormReducer
, a utility that creates the reducers for usFEATURE_REDUCER_TOKEN
to inject the feature name
import {
NgrxFormModule,
NgrxFormReducer,
FEATURE_REDUCER_TOKEN
} from '@yoozly/ngrx-form';
Then, use the same feature name (StoreModule
and NgrwFormModule
) and use the FEATURE_REDUCER_TOKEN
injection token.
@NgModule({
imports: [
...
StoreModule.forFeature('someFeatureName', FEATURE_REDUCER_TOKEN),
NgrxFormModule.forFeature('someFeatureName')
...
]
})
Finally, use the providers array to configure the reducers that will be created. You need to pass an array of names to the NgrxFormReducer
factory function.
@NgModule({
...
providers: [
{
provide: FEATURE_REDUCER_TOKEN,
useFactory: function(): ActionReducerMap<any> {
return {
...reducers,
...NgrxFormReducer(['formNameA','formNameB','formNameC'])
};
}
}
]
})
Here is the full configuration :
import {
NgrxFormModule,
NgrxFormReducer,
FEATURE_REDUCER_TOKEN
} from '@yoozly/ngrx-form';
@NgModule({
StoreModule.forFeature('someFeatureName', FEATURE_REDUCER_TOKEN),
NgrxFormModule.forFeature('someFeatureName')
providers: [
{
provide: FEATURE_REDUCER_TOKEN,
useFactory: function(): ActionReducerMap<any> {
return {
...reducers,
...NgrxFormReducer(['formNameA','formNameB','formNameC'])
};
}
}
]
})
Usage
Use the NgrxFormConnect
directive to bind your form group to the store.
<form [formGroup]="myFormGroup" NgrxFormConnect="formNameA">...</form>
The form name must be the same that the one provided in NgrxFormReducer
array.
return {
...reducers,
...NgrxFormReducer(['formNameA', 'formNameB'])
};
<form [formGroup]="myFormGroupA" NgrxFormConnect="formNameA">...</form>
<form [formGroup]="myFormGroupA" NgrxFormConnect="formNameB">...</form>
API
Models
NgrxFormState<T>
: the interface for each generated form. An optional type can be passed with the form content (ie form fields).
export interface NgrxFormState<T> {
value: T;
errors?: { [fieldName: string]: string };
pristine?: Boolean;
valid?: Boolean;
}
UpdateFormPayload
: the interface for the UpdateForm action payload.
export interface UpdateFormPayload<T> {
feature: string;
path: string;
form: NgrxFormState<T>;
}
Action
Important : Version 0.1.1 is now compatible with ngrx v8.x and a new action is available :
- updateform (v.8 with action creator)
- Updateform (older syntaxe based on a class)
We recommend to use the new syntax but both are still perfectly valid.
updateform
: [v8.x] the action used to update the store.
The payload must contains :
- the feature name
- the path of the form state (featurename.pathname --> ie the form name)
- the form datas
this.store.dispatch(
updateform({
payload:
{
feature: 'theFeatureName',
path: 'theFormName',
form: {
value: { },
errors: {},
pristine: false,
valid: false
}
})
)
Updateform
: the action used to update the store.
The payload must contains :
- the feature name
- the path of the form state (featurename.pathname --> ie the form name)
- the form datas
this.store.dispatch(
new Updateform({
feature: 'theFeatureName',
path: 'theFormName',
form: {
value: { },
errors: {},
pristine: false,
valid: false
})
)