Skip to content

Commit da8b067

Browse files
committed
fix: error when updating arrays that aren't field arrays
1 parent 7e7c35d commit da8b067

File tree

2 files changed

+287
-4
lines changed

2 files changed

+287
-4
lines changed

Diff for: packages/core/src/store.test.tsx

+279
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,84 @@ describe("arrays", () => {
226226
expect(fieldArrayKeys.foo).toHaveLength(3);
227227
});
228228

229+
it("should push into arrays with no field array", () => {
230+
const store = testStore();
231+
store.setState({
232+
values: {
233+
foo: ["bar", "baz"],
234+
},
235+
touchedFields: {
236+
"foo[0]": true,
237+
},
238+
dirtyFields: {
239+
"foo[0]": true,
240+
},
241+
validationErrors: {
242+
"foo[1]": "not equal",
243+
},
244+
});
245+
store.getState().arrayPush("foo", "quux");
246+
const {
247+
values,
248+
touchedFields,
249+
dirtyFields,
250+
validationErrors,
251+
fieldArrayKeys,
252+
defaultValueOverrides,
253+
} = store.getState();
254+
expect({
255+
values,
256+
touchedFields,
257+
dirtyFields,
258+
validationErrors,
259+
defaultValueOverrides,
260+
}).toEqual({
261+
values: {
262+
foo: ["bar", "baz", "quux"],
263+
},
264+
defaultValueOverrides: {
265+
"foo[2]": "quux",
266+
},
267+
touchedFields: {
268+
"foo[0]": true,
269+
},
270+
dirtyFields: {
271+
"foo[0]": true,
272+
},
273+
validationErrors: {
274+
"foo[1]": "not equal",
275+
},
276+
});
277+
});
278+
279+
it("should be able to be called in quick succession", () => {
280+
const store = testStore();
281+
store.setState({
282+
values: {
283+
foo: ["bar"],
284+
bar: [],
285+
},
286+
fieldArrayKeys: {
287+
foo: ["bar"],
288+
bar: [],
289+
},
290+
});
291+
const { arrayRemove, arrayInsert } = store.getState();
292+
arrayRemove("foo", 0);
293+
arrayInsert("bar", 0, "bar");
294+
const { values, fieldArrayKeys } = store.getState();
295+
expect({ values, fieldArrayKeys }).toEqual({
296+
values: {
297+
foo: [],
298+
bar: ["bar"],
299+
},
300+
fieldArrayKeys: {
301+
foo: [],
302+
bar: [expect.any(String)],
303+
},
304+
});
305+
});
306+
229307
it("should push into nested arrays", () => {
230308
const store = testStore();
231309
store.setState({
@@ -342,6 +420,63 @@ describe("arrays", () => {
342420
expect(fieldArrayKeys.foo).toHaveLength(1);
343421
});
344422

423+
it("should pop from arrays with no field array keys", () => {
424+
const store = testStore();
425+
store.setState({
426+
values: {
427+
foo: ["bar", "baz"],
428+
},
429+
defaultValueOverrides: {
430+
"foo[0]": "bar",
431+
"foo[1]": "baz",
432+
},
433+
touchedFields: {
434+
"foo[0]": true,
435+
"foo[1]": true,
436+
},
437+
dirtyFields: {
438+
"foo[0]": true,
439+
"foo[1]": true,
440+
},
441+
validationErrors: {
442+
"foo[0]": "not equal",
443+
"foo[1]": "not equal",
444+
},
445+
});
446+
store.getState().arrayPop("foo");
447+
const {
448+
values,
449+
touchedFields,
450+
dirtyFields,
451+
validationErrors,
452+
fieldArrayKeys,
453+
defaultValueOverrides,
454+
} = store.getState();
455+
expect({
456+
values,
457+
touchedFields,
458+
dirtyFields,
459+
validationErrors,
460+
defaultValueOverrides,
461+
}).toEqual({
462+
values: {
463+
foo: ["bar"],
464+
},
465+
defaultValueOverrides: {
466+
"foo[0]": "bar",
467+
},
468+
touchedFields: {
469+
"foo[0]": true,
470+
},
471+
dirtyFields: {
472+
"foo[0]": true,
473+
},
474+
validationErrors: {
475+
"foo[0]": "not equal",
476+
},
477+
});
478+
});
479+
345480
it("should pop from nested arrays", () => {
346481
const store = testStore();
347482
store.setState({
@@ -1132,6 +1267,72 @@ describe("arrays", () => {
11321267
expect(fieldArrayKeys.foo).toHaveLength(4);
11331268
});
11341269

1270+
it("should remove items from arrays with no field array keys", () => {
1271+
const store = testStore();
1272+
store.setState({
1273+
values: {
1274+
foo: ["bar", "baz", "another", "value", "quux"],
1275+
},
1276+
defaultValueOverrides: {
1277+
"foo[0]": "bar",
1278+
"foo[1]": "baz",
1279+
"foo[2]": "another",
1280+
},
1281+
touchedFields: {
1282+
"foo[0]": true,
1283+
"foo[1]": true,
1284+
"foo[2]": true,
1285+
"foo[3]": false,
1286+
},
1287+
dirtyFields: {
1288+
"foo[0]": false,
1289+
"foo[1]": true,
1290+
"foo[2]": true,
1291+
},
1292+
validationErrors: {
1293+
"foo[0]": "not equal",
1294+
"foo[1]": "not equal",
1295+
"foo[4]": "equal",
1296+
},
1297+
});
1298+
store.getState().arrayRemove("foo", 1);
1299+
const {
1300+
values,
1301+
touchedFields,
1302+
dirtyFields,
1303+
validationErrors,
1304+
defaultValueOverrides,
1305+
} = store.getState();
1306+
expect({
1307+
values,
1308+
touchedFields,
1309+
dirtyFields,
1310+
validationErrors,
1311+
defaultValueOverrides,
1312+
}).toEqual({
1313+
values: {
1314+
foo: ["bar", "another", "value", "quux"],
1315+
},
1316+
defaultValueOverrides: {
1317+
"foo[0]": "bar",
1318+
"foo[1]": "another",
1319+
},
1320+
touchedFields: {
1321+
"foo[0]": true,
1322+
"foo[1]": true,
1323+
"foo[2]": false,
1324+
},
1325+
dirtyFields: {
1326+
"foo[0]": false,
1327+
"foo[1]": true,
1328+
},
1329+
validationErrors: {
1330+
"foo[0]": "not equal",
1331+
"foo[3]": "equal",
1332+
},
1333+
});
1334+
});
1335+
11351336
it("should remove with nested arrays", () => {
11361337
const store = testStore();
11371338
store.setState({
@@ -1321,6 +1522,84 @@ describe("arrays", () => {
13211522
expect(fieldArrayKeys.foo).toHaveLength(5);
13221523
});
13231524

1525+
it("should swap items in arrays no field array keys", () => {
1526+
const store = testStore();
1527+
store.setState({
1528+
values: {
1529+
foo: ["bar", "baz", "another", "value", "quux"],
1530+
},
1531+
defaultValueOverrides: {
1532+
"foo[0]": "a",
1533+
"foo[1]": "b",
1534+
"foo[2]": "c",
1535+
"foo[3]": "d",
1536+
},
1537+
touchedFields: {
1538+
"foo[0]": true,
1539+
"foo[1]": true,
1540+
"foo[2]": true,
1541+
"foo[3]": false,
1542+
},
1543+
dirtyFields: {
1544+
"foo[0]": false,
1545+
"foo[1]": true,
1546+
"foo[2]": true,
1547+
},
1548+
validationErrors: {
1549+
"foo[0]": "not equal",
1550+
"foo[1]": "not equal",
1551+
"foo[4]": "equal",
1552+
},
1553+
});
1554+
store.getState().arraySwap("foo", 1, 3);
1555+
const {
1556+
values,
1557+
touchedFields,
1558+
dirtyFields,
1559+
validationErrors,
1560+
fieldArrayKeys,
1561+
arrayUpdateKeys,
1562+
defaultValueOverrides,
1563+
} = store.getState();
1564+
expect({
1565+
values,
1566+
touchedFields,
1567+
dirtyFields,
1568+
validationErrors,
1569+
arrayUpdateKeys,
1570+
defaultValueOverrides,
1571+
}).toEqual({
1572+
values: {
1573+
foo: ["bar", "value", "another", "baz", "quux"],
1574+
},
1575+
defaultValueOverrides: {
1576+
"foo[0]": "a",
1577+
"foo[1]": "d",
1578+
"foo[2]": "c",
1579+
"foo[3]": "b",
1580+
},
1581+
touchedFields: {
1582+
"foo[0]": true,
1583+
"foo[1]": false,
1584+
"foo[2]": true,
1585+
"foo[3]": true,
1586+
},
1587+
dirtyFields: {
1588+
"foo[0]": false,
1589+
"foo[2]": true,
1590+
"foo[3]": true,
1591+
},
1592+
validationErrors: {
1593+
"foo[0]": "not equal",
1594+
"foo[3]": "not equal",
1595+
"foo[4]": "equal",
1596+
},
1597+
arrayUpdateKeys: {
1598+
foo: expect.any(String),
1599+
},
1600+
});
1601+
});
1602+
13241603
it("should not do anything if swapping two non-existant items", () => {
13251604
const store = testStore();
13261605
store.setState({

Diff for: packages/core/src/store.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,8 @@ export const createFormStateStore = ({
11721172
throw new Error("Can't insert to a non-array");
11731173

11741174
insert(val, insertAtIndex, value);
1175-
insert(state.fieldArrayKeys[fieldName], insertAtIndex, genKey());
1175+
if (state.fieldArrayKeys[fieldName])
1176+
insert(state.fieldArrayKeys[fieldName], insertAtIndex, genKey());
11761177
state.arrayUpdateKeys[fieldName] = genKey();
11771178

11781179
moveFieldArrayKeys(
@@ -1202,7 +1203,8 @@ export const createFormStateStore = ({
12021203
throw new Error("Can't move from a non-array");
12031204

12041205
move(val, fromIndex, toIndex);
1205-
move(state.fieldArrayKeys[fieldName], fromIndex, toIndex);
1206+
if (state.fieldArrayKeys[fieldName])
1207+
move(state.fieldArrayKeys[fieldName], fromIndex, toIndex);
12061208
state.arrayUpdateKeys[fieldName] = genKey();
12071209

12081210
moveFieldArrayKeys(
@@ -1237,7 +1239,8 @@ export const createFormStateStore = ({
12371239
throw new Error("Can't remove from a non-array");
12381240

12391241
remove(val, removeIndex);
1240-
remove(state.fieldArrayKeys[fieldName], removeIndex);
1242+
if (state.fieldArrayKeys[fieldName])
1243+
remove(state.fieldArrayKeys[fieldName], removeIndex);
12411244
state.arrayUpdateKeys[fieldName] = genKey();
12421245

12431246
deleteFieldsWithPrefix(
@@ -1317,7 +1320,8 @@ export const createFormStateStore = ({
13171320
throw new Error("Can't replace from a non-array");
13181321

13191322
replace(val, index, value);
1320-
replace(state.fieldArrayKeys[fieldName], index, genKey());
1323+
if (state.fieldArrayKeys[fieldName])
1324+
replace(state.fieldArrayKeys[fieldName], index, genKey());
13211325
state.arrayUpdateKeys[fieldName] = genKey();
13221326

13231327
// Treat a replacement as a reset / new field at the same index.

0 commit comments

Comments
 (0)