Skip to content

Commit

Permalink
fix: fixed dbxFormlyForm async validation issue
Browse files Browse the repository at this point in the history
- Fixed issue where the async form status was not taking into account, causing values to be returned as valid before async validation finished. Now status values are passed through and cause updates on the overall state.
- Added status to DbxFormEvent
  • Loading branch information
dereekb committed May 12, 2022
1 parent 8cb2052 commit afb3f96
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/dbx-form/src/lib/form/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { forwardRef, Provider, Type } from '@angular/core';
import { Observable } from 'rxjs';
import { LockSet } from '@dereekb/rxjs';
import { BooleanStringKeyArray, Maybe } from '@dereekb/util';
import { FormControlStatus } from '@angular/forms';

/**
* Current state of a DbxForm
Expand All @@ -26,6 +27,7 @@ export const DEFAULT_FORM_DISABLED_KEY = 'dbx_form_disabled';
export interface DbxFormEvent {
readonly isComplete: boolean;
readonly state: DbxFormState;
readonly status: FormControlStatus;
readonly pristine?: boolean;
readonly untouched?: boolean;
readonly lastResetAt?: Date;
Expand Down
4 changes: 2 additions & 2 deletions packages/dbx-form/src/lib/formly/formly.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Provider } from '@angular/core';
import { BehaviorSubject, Observable, of, switchMap, shareReplay, distinctUntilChanged } from 'rxjs';
import { DbxForm, DbxFormDisabledKey, DbxFormEvent, DbxFormState, DbxMutableForm, DEFAULT_FORM_DISABLED_KEY, ProvideDbxMutableForm } from '../form/form';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { LockSet, filterMaybe } from '@dereekb/rxjs';
import { LockSet, filterMaybe, tapLog } from '@dereekb/rxjs';
import { BooleanStringKeyArray, BooleanStringKeyArrayUtilityInstance, Maybe } from '@dereekb/util';

export interface DbxFormlyInitialize<T> {
Expand Down Expand Up @@ -39,7 +39,7 @@ export class DbxFormlyContext<T = any> implements DbxForm<T> {

readonly lockSet = new LockSet();

private static INITIAL_STATE = { isComplete: false, state: DbxFormState.INITIALIZING };
private static INITIAL_STATE: DbxFormEvent = { isComplete: false, state: DbxFormState.INITIALIZING, status: 'PENDING' };

private _fields = new BehaviorSubject<Maybe<FormlyFieldConfig[]>>(undefined);
private _initialValue = new BehaviorSubject<Maybe<Partial<T>>>(undefined);
Expand Down
9 changes: 6 additions & 3 deletions packages/dbx-form/src/lib/formly/formly.form.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
import { distinctUntilChanged, map, throttleTime, startWith, BehaviorSubject, Observable, Subject, switchMap, shareReplay, of, scan } from 'rxjs';
import { distinctUntilChanged, map, throttleTime, startWith, BehaviorSubject, Observable, Subject, switchMap, shareReplay, of, scan, filter, first, combineLatest } from 'rxjs';
import { AbstractSubscriptionDirective } from '@dereekb/dbx-core';
import { DbxForm, DbxFormDisabledKey, DbxFormEvent, DbxFormState, DEFAULT_FORM_DISABLED_KEY, ProvideDbxMutableForm } from '../form/form';
import { DbxFormlyContext, DbxFormlyContextDelegate, DbxFormlyInitialize } from './formly.context';
Expand Down Expand Up @@ -35,7 +35,7 @@ export interface DbxFormlyFormState {
export class DbxFormlyFormComponent<T extends object> extends AbstractSubscriptionDirective implements DbxForm, DbxFormlyContextDelegate<T>, OnInit, OnDestroy {

private _fields = new BehaviorSubject<Maybe<Observable<FormlyFieldConfig[]>>>(undefined);
private _events = new BehaviorSubject<DbxFormEvent>({ isComplete: false, state: DbxFormState.INITIALIZING });
private _events = new BehaviorSubject<DbxFormEvent>({ isComplete: false, state: DbxFormState.INITIALIZING, status: 'PENDING' });
private _disabled = new BehaviorSubject<BooleanStringKeyArray>(undefined);

private _reset = new BehaviorSubject<Date>(new Date());
Expand All @@ -55,9 +55,11 @@ export class DbxFormlyFormComponent<T extends object> extends AbstractSubscripti
distinctUntilChanged(),
throttleTime(50, undefined, { leading: true, trailing: true }),
scanCount(),
// update on validation changes too.
switchMap(x => this.form.statusChanges.pipe(startWith(this.form.status), distinctUntilChanged()).pipe(map(_ => x))),
map((changesSinceLastResetCount: number) => ({
changesSinceLastResetCount,
isFormValid: this.form.valid,
isFormValid: this.form.status !== 'PENDING' && this.form.valid,
isFormDisabled: this.form.disabled
})),
scan((acc: DbxFormlyFormState, next: DbxFormlyFormState) => {
Expand All @@ -82,6 +84,7 @@ export class DbxFormlyFormComponent<T extends object> extends AbstractSubscripti
const nextState: DbxFormEvent = {
isComplete: complete,
state: (isReset) ? DbxFormState.RESET : DbxFormState.USED,
status: this.form.status,
untouched: this.form.untouched,
pristine: this.form.pristine,
changesCount: changesSinceLastResetCount,
Expand Down

0 comments on commit afb3f96

Please sign in to comment.