From c2844f90457a31683bc35de8ee44d63ed6628f0b Mon Sep 17 00:00:00 2001 From: Leo Gonzalez Date: Mon, 14 Feb 2022 16:17:45 +0100 Subject: [PATCH] optional arrays (#29) * init optional array * updated mappedfield and removed casting * removed exportable fieldset * fix tests * create array value when undefined * updated test --- sandbox-app/simple-array.tsx | 4 +--- src/field.ts | 17 ++++++++++++----- src/form.spec.ts | 13 ++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/sandbox-app/simple-array.tsx b/sandbox-app/simple-array.tsx index f6aa3c0..ca58fde 100644 --- a/sandbox-app/simple-array.tsx +++ b/sandbox-app/simple-array.tsx @@ -6,9 +6,7 @@ interface Model { emails?: string[]; } -const initialValue: Model = { - emails: ['bye@example.com', 'stay@example.com'], -}; +const initialValue: Model = {}; export function SimpleArray(): JSX.Element { const { diff --git a/src/field.ts b/src/field.ts index 8a75423..d23c3e5 100644 --- a/src/field.ts +++ b/src/field.ts @@ -5,8 +5,8 @@ import { MappedValidation, validateValue } from './validation'; for each field. In this case, for each field of T, string | number you get back a FormField type */ export type MappedFields = { - [P in keyof Required]: T[P] extends unknown[] - ? FieldSet + [P in keyof Required]: T[P] extends unknown[] | undefined + ? FieldSet[0]> : T[P] extends Record | undefined | null ? NestedField> : Field; @@ -127,6 +127,10 @@ export class FieldImplementation } add(element: T): void { + if (!this.value) { + this.value = [] as unknown as T; + } + this.value = [ ...(this.value as unknown as unknown[]), element, @@ -224,9 +228,12 @@ export class FieldImplementation #createSubfields(): void { const value = this.value; if (Array.isArray(value)) { - this.elements = value.map((e, index) => - this.createFieldSetField(e, this.#originalValue[index]) - ); + this.elements = value.map((e, index) => { + if (this.#originalValue === undefined) { + return this.createFieldSetField(e, e); + } + return this.createFieldSetField(e, this.#originalValue[index]); + }); } else { // make sure as many fields as possible are initialized if (this.isNestedValidation) { diff --git a/src/form.spec.ts b/src/form.spec.ts index b769e10..cdb352e 100644 --- a/src/form.spec.ts +++ b/src/form.spec.ts @@ -28,7 +28,7 @@ interface Model { age: number; description?: string; nullableValue: string | null; - emails: string[]; + emails?: string[]; address?: { streetName?: string; streetNumber?: number; @@ -43,7 +43,6 @@ const defaultValue: Model = { name: '', age: 18, nullableValue: null, - emails: [], hobbies: [], }; @@ -253,7 +252,7 @@ describe(Form, () => { const form = createForm({ validations: { emails: ({ model }) => - model.emails.length === 0 ? ['specify at least one'] : [], + (model.emails ?? []).length === 0 ? ['specify at least one'] : [], }, }); expect(form.fields.emails.errors).toEqual(['specify at least one']); @@ -476,18 +475,14 @@ describe(Form, () => { describe('fields array', () => { describe('creating', () => { it('creates empty array', () => { - const form = createForm({ - value: { emails: [] }, - }); + const form = createForm(); const emails = form.fields.emails; expect(emails.elements).toBeDefined(); expect(Array.isArray(emails.elements)).toEqual(true); expect(emails.elements.length).toEqual(0); }); it('adds a new field', () => { - const form = createForm({ - value: { emails: [] }, - }); + const form = createForm(); const emails = form.fields.emails; emails.add('test'); expect(emails.value.length).toEqual(1);