Skip to content

Commit 7def6b7

Browse files
authored
fix: defaultPopulate and populate with nested to arrays/blocks properties (#9751)
Fixes #9718 ### What? `defaultPopulate` and `populate` didn't work properly when defining nested to arrays and blocks properties: ```ts import type { CollectionConfig } from 'payload' export const Pages: CollectionConfig<'pages'> = { slug: 'pages', defaultPopulate: { slug: true, array: { title: true, }, blocks: { some: { title: true, }, }, }, access: { read: () => true }, fields: [ { name: 'slug', type: 'text', required: true, }, { name: 'additional', type: 'text', }, { name: 'array', type: 'array', fields: [ { name: 'title', type: 'text', }, { name: 'other', type: 'text', }, ], }, { name: 'blocks', type: 'blocks', blocks: [ { slug: 'some', fields: [ { name: 'title', type: 'text', }, { name: 'other', type: 'text', }, ], }, ], }, ], } ``` ### Why? This should work ### How? Turns out, it wasn't a great idea to mutate passed `select` directly in `afterRead/promise.ts` to force select some properties `id` , `blockType`. Now we do shallow copies when needed.
1 parent 840dde2 commit 7def6b7

File tree

4 files changed

+142
-7
lines changed

4 files changed

+142
-7
lines changed

packages/payload/src/fields/hooks/afterRead/promise.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,13 @@ export const promise = async ({
350350
case 'array': {
351351
const rows = siblingDoc[field.name] as JsonObject
352352

353-
const arraySelect = select?.[field.name]
353+
let arraySelect = select?.[field.name]
354354

355355
if (selectMode === 'include' && typeof arraySelect === 'object') {
356-
arraySelect.id = true
356+
arraySelect = {
357+
...arraySelect,
358+
id: true,
359+
}
357360
}
358361

359362
if (Array.isArray(rows)) {
@@ -427,7 +430,7 @@ export const promise = async ({
427430
case 'blocks': {
428431
const rows = siblingDoc[field.name]
429432

430-
const blocksSelect = select?.[field.name]
433+
let blocksSelect = select?.[field.name]
431434

432435
if (Array.isArray(rows)) {
433436
rows.forEach((row, i) => {
@@ -438,6 +441,10 @@ export const promise = async ({
438441
let blockSelectMode = selectMode
439442

440443
if (typeof blocksSelect === 'object') {
444+
blocksSelect = {
445+
...blocksSelect,
446+
}
447+
441448
// sanitize blocks: {cta: false} to blocks: {cta: {id: true, blockType: true}}
442449
if (selectMode === 'exclude' && blocksSelect[block.slug] === false) {
443450
blockSelectMode = 'include'
@@ -451,6 +458,10 @@ export const promise = async ({
451458
}
452459

453460
if (typeof blocksSelect[block.slug] === 'object') {
461+
blocksSelect[block.slug] = {
462+
...(blocksSelect[block.slug] as object),
463+
}
464+
454465
blocksSelect[block.slug]['id'] = true
455466
blocksSelect[block.slug]['blockType'] = true
456467
}
@@ -535,7 +546,6 @@ export const promise = async ({
535546
}
536547

537548
case 'collapsible':
538-
539549
case 'row': {
540550
traverseFields({
541551
collection,

test/select/collections/Pages/index.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ export const Pages: CollectionConfig<'pages'> = {
1010
// I need only slug, NOT the WHOLE CONTENT!
1111
defaultPopulate: {
1212
slug: true,
13+
array: {
14+
title: true,
15+
},
16+
blocks: {
17+
some: {
18+
title: true,
19+
},
20+
},
1321
},
1422
access: { read: () => true },
1523
fields: [
@@ -85,5 +93,38 @@ export const Pages: CollectionConfig<'pages'> = {
8593
name: 'additional',
8694
type: 'text',
8795
},
96+
{
97+
name: 'array',
98+
type: 'array',
99+
fields: [
100+
{
101+
name: 'title',
102+
type: 'text',
103+
},
104+
{
105+
name: 'other',
106+
type: 'text',
107+
},
108+
],
109+
},
110+
{
111+
name: 'blocks',
112+
type: 'blocks',
113+
blocks: [
114+
{
115+
slug: 'some',
116+
fields: [
117+
{
118+
name: 'title',
119+
type: 'text',
120+
},
121+
{
122+
name: 'other',
123+
type: 'text',
124+
},
125+
],
126+
},
127+
],
128+
},
88129
],
89130
}

test/select/int.spec.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,15 +1781,64 @@ describe('Select', () => {
17811781
describe('populate / defaultPopulate', () => {
17821782
let homePage: Page
17831783
let aboutPage: Page
1784-
let expectedHomePage: { id: number | string; slug: string }
1784+
let expectedHomePage: {
1785+
array: [
1786+
{
1787+
id: string
1788+
title: string
1789+
},
1790+
]
1791+
blocks: [
1792+
{
1793+
blockType: string
1794+
id: string
1795+
title: string
1796+
},
1797+
]
1798+
id: number | string
1799+
slug: string
1800+
}
17851801
let expectedHomePageOverride: { additional: string; id: number | string }
17861802
beforeAll(async () => {
17871803
homePage = await payload.create({
17881804
depth: 0,
17891805
collection: 'pages',
1790-
data: { content: [], slug: 'home', additional: 'additional-data' },
1806+
data: {
1807+
content: [],
1808+
slug: 'home',
1809+
array: [
1810+
{
1811+
title: 'some-title',
1812+
other: 'other',
1813+
},
1814+
],
1815+
blocks: [
1816+
{
1817+
blockType: 'some',
1818+
other: 'other',
1819+
title: 'some-title',
1820+
},
1821+
],
1822+
additional: 'additional-data',
1823+
},
17911824
})
1792-
expectedHomePage = { id: homePage.id, slug: homePage.slug }
1825+
expectedHomePage = {
1826+
id: homePage.id,
1827+
slug: homePage.slug,
1828+
array: [
1829+
{
1830+
id: homePage.array[0].id,
1831+
title: homePage.array[0].title,
1832+
},
1833+
],
1834+
blocks: [
1835+
{
1836+
blockType: homePage.blocks[0].blockType,
1837+
id: homePage.blocks[0].id,
1838+
title: homePage.blocks[0].title,
1839+
},
1840+
],
1841+
}
17931842
expectedHomePageOverride = { id: homePage.id, additional: homePage.additional }
17941843
aboutPage = await payload.create({
17951844
depth: 0,

test/select/payload-types.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,22 @@ export interface Page {
309309
| null;
310310
slug: string;
311311
additional?: string | null;
312+
array?:
313+
| {
314+
title?: string | null;
315+
other?: string | null;
316+
id?: string | null;
317+
}[]
318+
| null;
319+
blocks?:
320+
| {
321+
title?: string | null;
322+
other?: string | null;
323+
id?: string | null;
324+
blockName?: string | null;
325+
blockType: 'some';
326+
}[]
327+
| null;
312328
updatedAt: string;
313329
createdAt: string;
314330
}
@@ -657,6 +673,25 @@ export interface PagesSelect<T extends boolean = true> {
657673
};
658674
slug?: T;
659675
additional?: T;
676+
array?:
677+
| T
678+
| {
679+
title?: T;
680+
other?: T;
681+
id?: T;
682+
};
683+
blocks?:
684+
| T
685+
| {
686+
some?:
687+
| T
688+
| {
689+
title?: T;
690+
other?: T;
691+
id?: T;
692+
blockName?: T;
693+
};
694+
};
660695
updatedAt?: T;
661696
createdAt?: T;
662697
}

0 commit comments

Comments
 (0)