Skip to content
Draft
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
4 changes: 4 additions & 0 deletions docusaurus/docs/cms/api/document-service/populate.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,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
4 changes: 4 additions & 0 deletions docusaurus/docs/cms/api/rest/populate-select.md
Original file line number Diff line number Diff line change
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