Skip to content

Commit

Permalink
Correctly Reset Array Fields, fixes #20
Browse files Browse the repository at this point in the history
commit 30dab5d1f555a856475b18bce3554aeb41009ffb
Author: Jens Ravens <jens@nerdgeschoss.de>
Date:   Thu Jan 27 11:50:33 2022 +0100

    correctly reset array fields

commit 654c2a7
Author: Pascal Ernst <linucc@linu.cc>
Date:   Wed Jan 26 13:32:30 2022 +0100

    Update test to fail on changing a field with an array value
  • Loading branch information
JensRavens committed Jan 27, 2022
1 parent e829cfa commit 6fba224
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
17 changes: 13 additions & 4 deletions src/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,21 @@ export class FieldImplementation<T, Model>

constructor({
value,
originalValue,
validations,
onUpdate,
onRemove,
getModel,
}: {
value: T;
originalValue: T;
onUpdate: () => void;
validations: MappedValidation<T>;
onRemove?: () => void;
getModel: () => Model;
}) {
this.value = copy(value);
this.#originalValue = value;
this.#originalValue = originalValue ?? value;
this.#validations = validations;
this.#getModel = getModel;
if (
Expand Down Expand Up @@ -108,6 +110,7 @@ export class FieldImplementation<T, Model>
if (!target[key]) {
const field = new FieldImplementation({
value: this.value[key],
originalValue: this.value[key],
onUpdate: () => {
this.value[key] = field.value;
this.#onUpdate();
Expand All @@ -128,7 +131,7 @@ export class FieldImplementation<T, Model>
...(this.value as unknown as unknown[]),
element,
] as unknown as T;
this.elements.push(this.createFieldSetField(element));
this.elements.push(this.createFieldSetField(element, element));
this.#onUpdate();
}

Expand Down Expand Up @@ -216,7 +219,9 @@ export class FieldImplementation<T, Model>
private createSubfields(): void {
const value = this.value;
if (Array.isArray(value)) {
this.elements = value.map((e) => this.createFieldSetField(e));
this.elements = value.map((e, index) =>
this.createFieldSetField(e, this.#originalValue[index])
);
} else {
// make sure as many fields as possible are initialized
if (this.isNestedValidation) {
Expand All @@ -228,9 +233,13 @@ export class FieldImplementation<T, Model>
}
}

private createFieldSetField(value: T): FieldImplementation<T, Model> {
private createFieldSetField(
value: T,
originalValue: T
): FieldImplementation<T, Model> {
const field = new FieldImplementation({
value,
originalValue,
onUpdate: () => {
const index = this.elements.indexOf(field);
this.value[index] = field.value;
Expand Down
17 changes: 14 additions & 3 deletions src/form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ describe(Form, () => {
beforeEach(() => tracker.reset());

describe('instantiation', () => {
const form = createForm();
let form = null as unknown as Form<Model>;
beforeEach(() => (form = createForm()));
it('creates an empty field name', () => {
expect(form.fields.name).toBeTruthy();
expect(form.fields.name.value).toEqual('');
Expand Down Expand Up @@ -110,7 +111,7 @@ describe(Form, () => {
});

describe('tracking changes', () => {
let form: Form<Model> = createForm();
let form = null as unknown as Form<Model>;
beforeEach(() => (form = createForm()));

it('returns the updated model', () => {
Expand Down Expand Up @@ -376,10 +377,20 @@ describe(Form, () => {

describe('reseting', () => {
it('resets fields', () => {
const form = createForm();
const form = createForm({
value: {
emails: ['bye@example.com', 'stay@example.com'],
},
});
form.fields.name.onChange('hello');
form.fields.emails.onChange(['hello@example.com', 'stay@example.com']);
form.reset();
expect(form.changes).toEqual({});
expect(form.fields.name.value).toEqual('');
expect(form.fields.emails.value).toEqual([
'bye@example.com',
'stay@example.com',
]);
});

it('resets error', async () => {
Expand Down
1 change: 1 addition & 0 deletions src/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class Form<T> {
this.#validations = validations ?? {};
this.#field = new FieldImplementation<T, T>({
value: model,
originalValue: model,
onUpdate: this.onUpdate.bind(this),
validations: this.#validations,
getModel: () => this.model,
Expand Down

0 comments on commit 6fba224

Please sign in to comment.