Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docusaurus/docs/cms/api/document-service/populate.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ Use the `populate` parameter with the Document Service API to explicitly load re
By default the [Document Service API](/cms/api/document-service) does not populate any relations, media fields, components, or dynamic zones. This page describes how to use the `populate` parameter to populate specific fields.

:::tip
You can also use the `select` parameter to return only specific fields with the query results (see the [`select` parameter](/cms/api/document-service/fields) documentation).
You can also use the `fields` parameter to return only specific fields with the query results (see the [`fields` parameter](/cms/api/document-service/fields) documentation).
:::

:::caution
If the Users & Permissions plugin is installed, the `find` permission must be enabled for the content-types that are being populated. If a role doesn't have access to a content-type it will not be populated.
If the Users & Permissions feature is enabled, the `find` permission must be enabled for the content-types that are being populated. If a role doesn't have access to a content-type it will not be populated.
:::

<!-- TODO: add link to populate guides (even if REST API, the same logic still applies) -->
Expand Down Expand Up @@ -278,6 +278,10 @@ Omit `sort` from a `populate` object to preserve the default connect order (the

## Components & Dynamic Zones

:::note
When populated, empty `morphMany` relations (including `type: 'media', multiple: true` fields such as a gallery) return `[]` instead of `null`, consistent with `oneToMany` and `manyToMany`. See the [morphMany serialization breaking change](/cms/migration/v4-to-v5/breaking-changes/morph-many-serialization) for migration guidance.
:::

Components are populated the same way as relations:

<Endpoint
Expand Down
6 changes: 5 additions & 1 deletion docusaurus/docs/cms/api/rest/populate-select.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const query = qs.stringify(
}
);

await request(`/api/users?${query}`);
await request(`/api/restaurants?${query}`);
```

</TabItem>
Expand Down Expand Up @@ -322,3 +322,7 @@ For many-to-many and other join-table relations, an explicit `sort` within a `po
:::tip Performance tip
In production, always use explicit population instead of wildcards like `populate=*`. Limit population depth to 2-3 levels and consider centralizing population logic in route middlewares. See <ExternalLink to="https://strapi.io/blog/building-high-performance-strapi-applications-common-pitfalls-and-best-practices" text="Building High-Performance Strapi Applications" /> on the Strapi blog.
:::

:::note
When populated, empty `morphMany` relations (including `type: 'media', multiple: true` fields such as a gallery) return `[]` instead of `null`, consistent with `oneToMany` and `manyToMany`. See the [morphMany serialization breaking change](/cms/migration/v4-to-v5/breaking-changes/morph-many-serialization) for migration guidance.
:::
1 change: 1 addition & 0 deletions docusaurus/docs/cms/migration/v4-to-v5/breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ You can click on the description of any breaking change in the following tables
| [Upload a file at entry creation is no longer possible](/cms/migration/v4-to-v5/breaking-changes/no-upload-at-entry-creation) | Yes | No |
| [Components and dynamic zones should be populated using the detailed population strategy](/cms/migration/v4-to-v5/breaking-changes/no-shared-population-strategy-components-dynamic-zones) | Yes | No |
| [Updating repeatable components with the Document Service API is not recommended](/cms/migration/v4-to-v5/breaking-changes/do-not-update-repeatable-components-with-document-service-api) | Yes | No |
| [Empty `morphMany` relations return `[]` instead of `null` when populated](/cms/migration/v4-to-v5/breaking-changes/morph-many-serialization) | Yes | No |
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: Empty morphMany relations return [] instead of null when populated
description: In Strapi 5, populating an empty morphMany relation or multiple media field returns an empty array instead of null.
sidebar_label: Empty morphMany returns []
displayed_sidebar: cmsSidebar
tags:
- breaking changes
- Content API
- media
- morphMany
- populate
- upgrade to Strapi 5
---

import Intro from '/docs/snippets/breaking-change-page-intro.md'
import MigrationIntro from '/docs/snippets/breaking-change-page-migration-intro.md'

# Empty morphMany relations return [] instead of null when populated

<Tldr>

In Strapi 5, populating an empty `morphMany` relation (including `type: 'media', multiple: true` fields such as a gallery) returns `[]` instead of `null`. Update client code that checks `field === null` to treat `[]` as the empty state.

</Tldr>

In Strapi 5, empty `morphMany` relations and `type: 'media', multiple: true` fields (such as a gallery) now serialize as an empty array when populated, consistent with `oneToMany` and `manyToMany` relations. Previously, these fields returned `null` when no related entries existed.

<Intro />

<BreakingChangeIdCard plugins />

## Breaking change description

<SideBySideContainer>

<SideBySideColumn>

**In Strapi v4**

Populating an empty `morphMany` relation or a multiple media field returned `null`:

```json
{
"gallery": null
}
```

</SideBySideColumn>

<SideBySideColumn>

**In Strapi 5**

Populating an empty `morphMany` relation or a multiple media field returns an empty array:

```json
{
"gallery": []
}
```

</SideBySideColumn>

</SideBySideContainer>

## Migration

<MigrationIntro />

### Notes

- This change applies to all `morphMany` relation types, including `type: 'media', multiple: true` fields (for example, gallery fields).
- The change is unconditional and is not controlled by the `api.documents.strictRelations` setting.
- See [Document Service API: Populating fields](/cms/api/document-service/populate) and [REST API: Population & Field Selection](/cms/api/rest/populate-select#population) for related information on populating relations.

### Manual procedure

Check client code, webhooks, and integrations that consume populated `morphMany` or multiple media fields.

1. Search your codebase for code that branches on `field === null` or treats `null` as "no value" for populated `morphMany` or multiple media fields.
2. Replace `null` checks with array checks, for example using `!field?.length`.

<SideBySideContainer>
<SideBySideColumn>

**Before**

```js
if (entry.gallery === null) {
// handle empty gallery
}
```

</SideBySideColumn>

<SideBySideColumn>

**After**

```js
if (!entry.gallery?.length) {
// handle empty gallery
}
```

</SideBySideColumn>
</SideBySideContainer>
Loading