From 9762c877e20b383704612b117745011e5af747fe Mon Sep 17 00:00:00 2001 From: Maxime Robert Date: Tue, 29 Dec 2020 15:52:30 +0100 Subject: [PATCH] WIP this fix is not working entirely as it seem to have the error just fine on the component itself but it's not propagating this error to the parent components on the same tick. It's fine after another CD though but unsure why we're missing 1 tick for now --- projects/ngx-sub-form/src/lib/helpers.ts | 36 ++++++++++--------- .../src/lib/shared/ngx-sub-form-utils.ts | 6 ++-- src/app/app.spec.e2e.ts | 22 +++++++++--- .../crew-members/crew-members.component.html | 3 ++ .../crew-members/crew-members.component.ts | 24 +++++++++++-- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/projects/ngx-sub-form/src/lib/helpers.ts b/projects/ngx-sub-form/src/lib/helpers.ts index 55e7304b..76eb5615 100644 --- a/projects/ngx-sub-form/src/lib/helpers.ts +++ b/projects/ngx-sub-form/src/lib/helpers.ts @@ -1,26 +1,20 @@ -import { - AbstractControlOptions, - ControlValueAccessor, - FormArray, - FormControl, - FormGroup, - ValidationErrors, -} from '@angular/forms'; +import { AbstractControlOptions, ControlValueAccessor, FormArray, FormGroup, ValidationErrors } from '@angular/forms'; import { ReplaySubject } from 'rxjs'; import { Nilable } from 'tsdef'; import { + ControlValueAccessorComponentInstance, + FormBindings, + NgxSubFormArrayOptions, + NgxSubFormOptions, +} from './ngx-sub-form.types'; +import { + AAAAAA, ArrayPropertyKey, ControlsNames, NewFormErrors, OneOfControlsTypes, TypedFormGroup, } from './shared/ngx-sub-form-utils'; -import { - ControlValueAccessorComponentInstance, - FormBindings, - NgxSubFormArrayOptions, - NgxSubFormOptions, -} from './ngx-sub-form.types'; export const deepCopy = (value: T): T => JSON.parse(JSON.stringify(value)); @@ -88,7 +82,7 @@ export const getFormGroupErrors = ( // with the index and the error // this way, we avoid holding a lot of potential `null` // values in the array for the valid form controls - const errorsInArray: Record = {}; + const errorsInArray: AAAAAA = {}; for (let i = 0; i < control.length; i++) { const controlErrors = control.at(i).errors; @@ -97,8 +91,18 @@ export const getFormGroupErrors = ( } } + // following fixes + // https://github.com/cloudnc/ngx-sub-form/issues/161 + // if we've got a form array we can't only take into account + // the errors in the form array coming from its items + // we also need to take into account the errors attached to + // the form array itself if it has any validator + if (control.errors) { + errorsInArray['formArray'] = control.errors; + } + if (Object.values(errorsInArray).length > 0) { - const accHoldingArrays = acc as Record>; + const accHoldingArrays = acc as Record; accHoldingArrays[key as keyof ControlInterface] = errorsInArray; } } else if (control.errors) { diff --git a/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts b/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts index 650c5069..de9ea8cf 100644 --- a/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts +++ b/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts @@ -10,7 +10,7 @@ import { ValidationErrors, } from '@angular/forms'; import { getObservableLifecycle } from 'ngx-observable-lifecycle'; -import { Observable, Subject, timer } from 'rxjs'; +import { Observable, timer } from 'rxjs'; import { debounce, takeUntil } from 'rxjs/operators'; import { NgxSubFormComponent } from '../deprecated/ngx-sub-form.component'; @@ -47,9 +47,11 @@ export type FormErrors = null | Partial< } >; +export type AAAAAA = { [key in number | 'formArray']?: ValidationErrors }; + // @todo rename to `FormErrorsType` once the deprecated one is removed export type NewFormErrorsType = { - [K in keyof T]-?: T[K] extends any[] ? Record : ValidationErrors; + [K in keyof T]-?: T[K] extends any[] ? AAAAAA : ValidationErrors; }; // @todo rename to `FormErrors` once the deprecated one is removed diff --git a/src/app/app.spec.e2e.ts b/src/app/app.spec.e2e.ts index f60c80b9..77a8793a 100644 --- a/src/app/app.spec.e2e.ts +++ b/src/app/app.spec.e2e.ts @@ -8,10 +8,10 @@ import { Spaceship, Speeder, VehicleType } from './interfaces/vehicle.interface' import { hardCodedListings } from './services/listings.data'; context(`EJawa demo`, () => { - const testContexts = [ - { id: 'old', testName: 'Old implementation', url: '' }, + const testContexts: { id: any; testName: any; url: any }[] = [ + // { id: 'old', testName: 'Old implementation', url: '' }, { id: 'new', testName: 'New implementation', url: '/rewrite' }, - ] as const; + ]; testContexts.forEach(({ id, testName, url }) => { context(testName, () => { @@ -124,7 +124,7 @@ context(`EJawa demo`, () => { }); }); - it(`should display the (nested) errors from the form`, () => { + it.only(`should display the (nested) errors from the form`, () => { DOM.createNewButton.click(); DOM.form.errors.should($el => { @@ -176,6 +176,14 @@ context(`EJawa demo`, () => { }, crewMembers: { required: true, + crewMembers: { + formArray: { + minLengthArray: { + currentLength: 0, + minimumLength: 3, + }, + }, + }, }, wingCount: { required: true, @@ -250,6 +258,12 @@ context(`EJawa demo`, () => { required: true, }, }, + formArray: { + minLengthArray: { + currentLength: 1, + minimumLength: 3, + }, + }, }, }, wingCount: { diff --git a/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.html b/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.html index a4b024c6..024cc82d 100644 --- a/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.html +++ b/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.html @@ -24,3 +24,6 @@ Add a crew member + + +
{{ form.formGroupErrors | json }}
diff --git a/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts b/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts index 47c8c1ed..5b205639 100644 --- a/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts +++ b/src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { FormArray, FormControl, Validators } from '@angular/forms'; +import { AbstractControl, FormArray, FormControl, Validators } from '@angular/forms'; import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form'; import { CrewMember } from '../../../../../interfaces/crew-member.interface'; @@ -18,7 +18,12 @@ export class CrewMembersComponent { public form = createForm(this, { formType: FormType.SUB, formControls: { - crewMembers: new FormArray([]), + crewMembers: new FormArray( + [], + // the following validator is here to make sure we have a proper fix to + // https://github.com/cloudnc/ngx-sub-form/issues/161 + this.minLengthArray(3), + ), }, toFormGroup: (obj: CrewMember[]): CrewMembersForm => { return { @@ -50,4 +55,19 @@ export class CrewMembersComponent { }), ); } + + private minLengthArray(minimumLength: number) { + return (c: AbstractControl): { [key: string]: any } | null => { + if (c.value.length >= minimumLength) { + return null; + } + + return { + minLengthArray: { + currentLength: c.value.length, + minimumLength, + }, + }; + }; + } }