Skip to content

Commit ae6c71b

Browse files
authored
fix(live-preview): client-side live preview cannot clear all array rows (#9439)
When using Client-side Live Preview, array fields are unable to clear all their rows. This is because `reduceFieldsToValues` sets the array's value as 0 within form-state when no rows exist, as opposed to an empty array as one might expect. For now, we can simply handle this data shape within Live Preview's merge logic. In the future we may want to take to consider changing the behavior of empty arrays within form-state itself.
1 parent 27acdae commit ae6c71b

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

packages/live-preview/src/traverseFields.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export const traverseFields = <T>(args: {
2525

2626
switch (fieldSchema.type) {
2727
case 'array':
28+
if (
29+
!incomingData[fieldName] &&
30+
incomingData[fieldName] !== undefined &&
31+
result?.[fieldName] !== undefined
32+
) {
33+
result[fieldName] = []
34+
}
35+
2836
if (Array.isArray(incomingData[fieldName])) {
2937
result[fieldName] = incomingData[fieldName].map((incomingRow, i) => {
3038
if (!result[fieldName]) {
@@ -85,7 +93,7 @@ export const traverseFields = <T>(args: {
8593
break
8694

8795
case 'group':
88-
96+
// falls through
8997
case 'tabs':
9098
if (!result[fieldName]) {
9199
result[fieldName] = {}
@@ -100,8 +108,9 @@ export const traverseFields = <T>(args: {
100108
})
101109

102110
break
103-
case 'relationship':
104111

112+
case 'relationship':
113+
// falls through
105114
case 'upload':
106115
// Handle `hasMany` relationships
107116
if (fieldSchema.hasMany && Array.isArray(incomingData[fieldName])) {

test/live-preview/int.spec.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,53 @@ describe('Collections - Live Preview', () => {
169169
expect(mergedData._numberOfRequests).toEqual(0)
170170
})
171171

172+
it('— arrays - can clear all rows', async () => {
173+
const initialData: Partial<Page> = {
174+
title: 'Test Page',
175+
arrayOfRelationships: [
176+
{
177+
id: '123',
178+
relationshipInArrayMonoHasOne: testPost.id,
179+
},
180+
],
181+
}
182+
183+
const mergedData = await mergeData({
184+
depth: 1,
185+
fieldSchema: schemaJSON,
186+
incomingData: {
187+
...initialData,
188+
arrayOfRelationships: [],
189+
},
190+
initialData,
191+
serverURL,
192+
returnNumberOfRequests: true,
193+
collectionPopulationRequestHandler,
194+
})
195+
196+
expect(mergedData.arrayOfRelationships).toEqual([])
197+
expect(mergedData._numberOfRequests).toEqual(0)
198+
199+
// do the same but with arrayOfRelationships: 0
200+
201+
const mergedData2 = await mergeData({
202+
depth: 1,
203+
fieldSchema: schemaJSON,
204+
incomingData: {
205+
...initialData,
206+
// @ts-expect-error eslint-disable-next-line
207+
arrayOfRelationships: 0, // this is how form state represents an empty array
208+
},
209+
initialData,
210+
serverURL,
211+
returnNumberOfRequests: true,
212+
collectionPopulationRequestHandler,
213+
})
214+
215+
expect(mergedData2.arrayOfRelationships).toEqual([])
216+
expect(mergedData2._numberOfRequests).toEqual(0)
217+
})
218+
172219
it('— uploads - adds and removes media', async () => {
173220
const initialData: Partial<Page> = {
174221
title: 'Test Page',

0 commit comments

Comments
 (0)