Skip to content

Commit 9762c87

Browse files
committed
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
1 parent 687ce21 commit 9762c87

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

projects/ngx-sub-form/src/lib/helpers.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
1-
import {
2-
AbstractControlOptions,
3-
ControlValueAccessor,
4-
FormArray,
5-
FormControl,
6-
FormGroup,
7-
ValidationErrors,
8-
} from '@angular/forms';
1+
import { AbstractControlOptions, ControlValueAccessor, FormArray, FormGroup, ValidationErrors } from '@angular/forms';
92
import { ReplaySubject } from 'rxjs';
103
import { Nilable } from 'tsdef';
114
import {
5+
ControlValueAccessorComponentInstance,
6+
FormBindings,
7+
NgxSubFormArrayOptions,
8+
NgxSubFormOptions,
9+
} from './ngx-sub-form.types';
10+
import {
11+
AAAAAA,
1212
ArrayPropertyKey,
1313
ControlsNames,
1414
NewFormErrors,
1515
OneOfControlsTypes,
1616
TypedFormGroup,
1717
} from './shared/ngx-sub-form-utils';
18-
import {
19-
ControlValueAccessorComponentInstance,
20-
FormBindings,
21-
NgxSubFormArrayOptions,
22-
NgxSubFormOptions,
23-
} from './ngx-sub-form.types';
2418

2519
export const deepCopy = <T>(value: T): T => JSON.parse(JSON.stringify(value));
2620

@@ -88,7 +82,7 @@ export const getFormGroupErrors = <ControlInterface, FormInterface>(
8882
// with the index and the error
8983
// this way, we avoid holding a lot of potential `null`
9084
// values in the array for the valid form controls
91-
const errorsInArray: Record<number, ValidationErrors> = {};
85+
const errorsInArray: AAAAAA = {};
9286

9387
for (let i = 0; i < control.length; i++) {
9488
const controlErrors = control.at(i).errors;
@@ -97,8 +91,18 @@ export const getFormGroupErrors = <ControlInterface, FormInterface>(
9791
}
9892
}
9993

94+
// following fixes
95+
// https://github.com/cloudnc/ngx-sub-form/issues/161
96+
// if we've got a form array we can't only take into account
97+
// the errors in the form array coming from its items
98+
// we also need to take into account the errors attached to
99+
// the form array itself if it has any validator
100+
if (control.errors) {
101+
errorsInArray['formArray'] = control.errors;
102+
}
103+
100104
if (Object.values(errorsInArray).length > 0) {
101-
const accHoldingArrays = acc as Record<keyof ControlInterface, Record<number, ValidationErrors>>;
105+
const accHoldingArrays = acc as Record<keyof ControlInterface, AAAAAA>;
102106
accHoldingArrays[key as keyof ControlInterface] = errorsInArray;
103107
}
104108
} else if (control.errors) {

projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
ValidationErrors,
1111
} from '@angular/forms';
1212
import { getObservableLifecycle } from 'ngx-observable-lifecycle';
13-
import { Observable, Subject, timer } from 'rxjs';
13+
import { Observable, timer } from 'rxjs';
1414
import { debounce, takeUntil } from 'rxjs/operators';
1515
import { NgxSubFormComponent } from '../deprecated/ngx-sub-form.component';
1616

@@ -47,9 +47,11 @@ export type FormErrors<FormInterface> = null | Partial<
4747
}
4848
>;
4949

50+
export type AAAAAA = { [key in number | 'formArray']?: ValidationErrors };
51+
5052
// @todo rename to `FormErrorsType` once the deprecated one is removed
5153
export type NewFormErrorsType<T> = {
52-
[K in keyof T]-?: T[K] extends any[] ? Record<number, ValidationErrors> : ValidationErrors;
54+
[K in keyof T]-?: T[K] extends any[] ? AAAAAA : ValidationErrors;
5355
};
5456

5557
// @todo rename to `FormErrors` once the deprecated one is removed

src/app/app.spec.e2e.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { Spaceship, Speeder, VehicleType } from './interfaces/vehicle.interface'
88
import { hardCodedListings } from './services/listings.data';
99

1010
context(`EJawa demo`, () => {
11-
const testContexts = [
12-
{ id: 'old', testName: 'Old implementation', url: '' },
11+
const testContexts: { id: any; testName: any; url: any }[] = [
12+
// { id: 'old', testName: 'Old implementation', url: '' },
1313
{ id: 'new', testName: 'New implementation', url: '/rewrite' },
14-
] as const;
14+
];
1515

1616
testContexts.forEach(({ id, testName, url }) => {
1717
context(testName, () => {
@@ -124,7 +124,7 @@ context(`EJawa demo`, () => {
124124
});
125125
});
126126

127-
it(`should display the (nested) errors from the form`, () => {
127+
it.only(`should display the (nested) errors from the form`, () => {
128128
DOM.createNewButton.click();
129129

130130
DOM.form.errors.should($el => {
@@ -176,6 +176,14 @@ context(`EJawa demo`, () => {
176176
},
177177
crewMembers: {
178178
required: true,
179+
crewMembers: {
180+
formArray: {
181+
minLengthArray: {
182+
currentLength: 0,
183+
minimumLength: 3,
184+
},
185+
},
186+
},
179187
},
180188
wingCount: {
181189
required: true,
@@ -250,6 +258,12 @@ context(`EJawa demo`, () => {
250258
required: true,
251259
},
252260
},
261+
formArray: {
262+
minLengthArray: {
263+
currentLength: 1,
264+
minimumLength: 3,
265+
},
266+
},
253267
},
254268
},
255269
wingCount: {

src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@
2424
Add a crew member
2525
</button>
2626
</fieldset>
27+
28+
<!-- todo: remove as this is just for debugging -->
29+
<pre>{{ form.formGroupErrors | json }}</pre>

src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ChangeDetectionStrategy, Component } from '@angular/core';
2-
import { FormArray, FormControl, Validators } from '@angular/forms';
2+
import { AbstractControl, FormArray, FormControl, Validators } from '@angular/forms';
33
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form';
44
import { CrewMember } from '../../../../../interfaces/crew-member.interface';
55

@@ -18,7 +18,12 @@ export class CrewMembersComponent {
1818
public form = createForm<CrewMember[], CrewMembersForm>(this, {
1919
formType: FormType.SUB,
2020
formControls: {
21-
crewMembers: new FormArray([]),
21+
crewMembers: new FormArray(
22+
[],
23+
// the following validator is here to make sure we have a proper fix to
24+
// https://github.com/cloudnc/ngx-sub-form/issues/161
25+
this.minLengthArray(3),
26+
),
2227
},
2328
toFormGroup: (obj: CrewMember[]): CrewMembersForm => {
2429
return {
@@ -50,4 +55,19 @@ export class CrewMembersComponent {
5055
}),
5156
);
5257
}
58+
59+
private minLengthArray(minimumLength: number) {
60+
return (c: AbstractControl): { [key: string]: any } | null => {
61+
if (c.value.length >= minimumLength) {
62+
return null;
63+
}
64+
65+
return {
66+
minLengthArray: {
67+
currentLength: c.value.length,
68+
minimumLength,
69+
},
70+
};
71+
};
72+
}
5373
}

0 commit comments

Comments
 (0)