1.0.0-alpha.11 • Published 5 years ago

@larscom/ngrx-form-sync v1.0.0-alpha.11

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

@larscom/ngrx-form-sync

npm-prerelease travis build license

Easily sync Angular reactive forms to the @ngrx/store with minimal setup.

This library synergizes really well with @larscom/ngrx-store-storagesync if you would also like to save the form state to a persistant storage solution like sessionStorage or localStorage.

Dependencies

@larscom/ngrx-form-sync depends on @ngrx/store >= 8.0.0 and Angular >=8.0.0.

Setup

  1. Install package @larscom/ngrx-form-sync
npm i --save @larscom/ngrx-form-sync
  1. Add the NgrxFormSyncModule to the (feature) module where you are using the reactive forms.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { NgrxFormSyncModule } from '@larscom/ngrx-form-sync';

@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    /* import `NgrxFormSyncModule` in every (feature) module */
    NgrxFormSyncModule
  ]
})
export class MyFeatureModule {}
  1. Register the formSyncReducer
import { NgModule, InjectionToken } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule, ActionReducerMap, MetaReducer, ActionReducer } from '@ngrx/store';
import { formSyncReducer, IFormSyncState } from '@larscom/ngrx-form-sync';
import * as fromApp from './store/reducer';

export const FORM_SYNC_REDUCER = new InjectionToken<ActionReducer<IFormSyncState>>('FORM_SYNC_REDUCER');

@NgModule({
  imports: [
    BrowserModule,
    StoreModule.forRoot({ app: fromApp.reducer }),
    /* register the formSyncReducer */
    StoreModule.forFeature('form', FORM_SYNC_REDUCER)
  ],
  providers: [
    {
      provide: FORM_SYNC_REDUCER,
      useValue: formSyncReducer
    }
  ]
})
export class AppModule {}

Usage

Add formGroupId to the element where formGroup is present. Without formGroupId, the form doesn't get synced.

<form [formGroup]="myFormGroup" [formGroupId]="'myFormGroup'">
  <div>
    <input formControlName="firstName" />
    <input formControlName="lastName" />
  </div>
  <button type="submit">Submit</button>
</form>

If you want to exclude / ignore certian form controls you can't use the formControlName attribute.

Instead bind to formControl and set formControlSync to false.

<form [formGroup]="myFormGroup" [formGroupId]="'myFormGroup'">
  <div>
    /* firstName will not get synced */
    <input [formControl]="myFormGroup.get('firstName')" [formControlSync]="false" />
    <input formControlName="lastName" />
  </div>
  <button type="submit">Submit</button>
</form>

Get the form value anywhere in your app

import { Component } from '@angular/core';
import { getFormSyncValue } from '@larscom/ngrx-form-sync';
import { Store, select } from '@ngrx/store';

@Component({
  selector: 'app-my-component',
  template: `
    <div>
      <h1>My Form Value</h1>
      {{ myFormValue$ | async | json }}
    </div>
  `,
  styleUrls: ['my-component.component.scss']
})
export class MyComponent {
  constructor(private store: Store<any>) {}

  myFormValue$ = this.store.pipe(select(getFormSyncValue, { id: 'myFormGroup' }));
}

Update the form via the action dispatcher

import { Component } from '@angular/core';
import { setForm, patchForm, resetForm, deleteForm } from '@larscom/ngrx-form-sync';
import { Store, select } from '@ngrx/store';

@Component({
  selector: 'app-my-component',
  templateUrl: 'my-component.component.html'
  styleUrls: ['my-component.component.scss']
})
export class MyComponent {
  constructor(private store: Store<any>) {}

  /* patch form value, lastName can be omitted */
  patchValue(): void {
    const value = {
      firstName: 'Jan',
      //lastName: 'Jansen'
    };
    this.store.dispatch(patchForm({ id: 'myFormGroup', value }));
  }

  /* sets the initial form value */
  setValue(): void {
    const value = {
      firstName: 'Jan',
      lastName: 'Jansen'
    };
    this.store.dispatch(setForm({ id: 'myFormGroup', value }));
  }

  /* reset form value (sets every property to null)  */
  resetValue(): void {
    this.store.dispatch(resetForm({ id: 'myFormGroup' }));
  }

    /* remove form value from store  */
  deleteValue(): void {
    this.store.dispatch(deleteForm({ id: 'myFormGroup' }));
  }
}

Configuration

You can override the default configuration on component level

import { Component } from '@angular/core';
import { IFormSyncConfig, FORM_SYNC_CONFIG } from '@larscom/ngrx-form-sync';

const formSyncConfig: IFormSyncConfig = {
  /* Only sync to the store when submitting the form. */
  syncOnSubmit: true
};

@Component({
  selector: 'app-my-component',
  templateUrl: 'my-component.component.html',
  styleUrls: ['my-component.component.scss'],
  providers: [
    {
      provide: FORM_SYNC_CONFIG,
      useValue: formSyncConfig
    }
  ]
})
export class MyComponent {}
export interface IFormSyncConfig {
  /**
   * Only sync to the store when submitting the form.
   */
  syncOnSubmit?: boolean;
  /**
   * Only sync to the store when the form status is valid.
   */
  syncValidOnly?: boolean;
  /**
   * Sync the raw form value to the store (this will include disabled form controls)
   */
  syncRawValue?: boolean;
}

FormGroup Directive API

AttributeTypeDefaultRequiredDescription
formGroupIdstringnullyesThe unique ID for the form group.
formGroupSyncbooleantruenoWhether the form group value should sync to the @ngrx/store.

FormControl Directive API

AttributeTypeDefaultRequiredDescription
formControlSyncbooleantruenoWhether the form control value should sync to the @ngrx/store.
1.0.0-alpha.11

5 years ago

1.0.0-alpha.10

5 years ago

1.0.0-alpha.9

5 years ago

1.0.0-alpha.8

5 years ago

1.0.0-alpha.7

5 years ago

1.0.0-alpha.6

5 years ago

1.0.0-alpha.5

5 years ago

1.0.0-alpha.4

5 years ago

1.0.0-alpha.3

5 years ago

1.0.0-alpha.0

5 years ago