Strapi V4 populate Media and Dynamiczones from Components

Thanks @manicho you saved our week :grinning:

Let me add, this is to be installed on your STRAPI server, not the CLIENT

The same situation, but for GraphQL…
Is there any elastic way to request dynamic zones via Graphql without explicitly defining each of them in a query?
For example, I DON’T want to do something like this:

query Homepage {
  components {
    ... on SliderComponent {
      image
      text
    }
    ... on ParagraphComponent {
      title
      description
    }
    // and so on...
  }
}

Instead, somehow, I’d like to be able to get all of the dynamic zones without querying them separately.
So ideally would be something like this:

query Homepage {
  components
}

and that would return all of the possible dynamic zone components with their nested fields.

The best scenario is to query all the nested data within the dynamic zones using something like in RestApi http://localhost:1337/api/pages?populate[dynamiczones]

NOTE: I know that the queries above are not correct, but this is just an idea of the query shape.

Work for me

@urbandale @sg-code
Have you considered using this:

const collectionType = 'api::page.page';
      const allPages = await strapi.entityService.findMany(collectionType, {
        fields: ["*"],
        filters: { },
        sort: { },
        populate: {
          // content [is the name of the dynamic zone in page]
         // Note: in @urbandale's Example Content is uppercase.
          content: {
            populate: "*"
          },
        }
      });

Atleast you don’t have to manually add each new component in your dynamic-zone.

Hi guys,

I work on the new version of a magazine’s website and struggling a bit with deep population, especially in dynamic zones (articles that can contain text, images and quotes). I’ve never been able to make any of the above work, especially the “image” components in the dynamic zone were never populating. I tried to give a shot at the strapi-plugin-populate-deep - npm .

Magic! the image components are populating with captions, alternative texts, formats, etc… But there is one caveat with this plugin: An article needs to display its author, which was super easy with Strapi 3, but that I now need to extract from the strapi.entityService and reinject in the sanitized entity manually in v4 like this:

const sanitizedEntity = await this.sanitizeOutput(info, ctx);
    sanitizedEntity[0].createdBy = {
      id: info[0].createdBy.id,
      firstname: info[0].createdBy.firstname,
      lastname: info[0].createdBy.lastname
    }

Here’s what I get when I use the query: ?populate=*

{
    "data": [
        {
            "id": 1,
            "attributes": {
                "title": "Quinzième Album ",
                "slug": "caravan-quinzieme-album",
                "isOnFrontPage": false,
                "createdAt": "2021-10-15T18:05:37.571Z",
                "updatedAt": "2022-07-31T17:22:21.249Z",
                "publishedAt": "2021-10-15T18:15:22.487Z",
                "artistName": "Caravan",
                "image": {
                    "data": {
                        "id": 15,
                        "attributes": {
                            "name": "It's None Of Your Business Album Cover.jpeg",
                            "alternativeText": "Caravan Cover Image",
                            "caption": "It's None Of Your Business by Caravan",
                            "width": 1200,
                            "height": 1200,
                            "formats": {
                                "large": {
                                    "ext": ".jpeg",
                                    "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698521/v2images/large_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c.jpg",
                                    "hash": "large_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                    "mime": "image/jpeg",
                                    "name": "large_It's None Of Your Business Album Cover.jpeg",
                                    "path": null,
                                    "size": 222.33,
                                    "width": 1000,
                                    "height": 1000,
                                    "provider_metadata": {
                                        "public_id": "v2images/large_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                        "resource_type": "image"
                                    }
                                },
                                "small": {
                                    "ext": ".jpeg",
                                    "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698523/v2images/small_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c.jpg",
                                    "hash": "small_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                    "mime": "image/jpeg",
                                    "name": "small_It's None Of Your Business Album Cover.jpeg",
                                    "path": null,
                                    "size": 67.28,
                                    "width": 500,
                                    "height": 500,
                                    "provider_metadata": {
                                        "public_id": "v2images/small_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                        "resource_type": "image"
                                    }
                                },
                                "medium": {
                                    "ext": ".jpeg",
                                    "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698522/v2images/medium_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c.jpg",
                                    "hash": "medium_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                    "mime": "image/jpeg",
                                    "name": "medium_It's None Of Your Business Album Cover.jpeg",
                                    "path": null,
                                    "size": 135.74,
                                    "width": 750,
                                    "height": 750,
                                    "provider_metadata": {
                                        "public_id": "v2images/medium_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                        "resource_type": "image"
                                    }
                                },
                                "thumbnail": {
                                    "ext": ".jpeg",
                                    "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698520/v2images/thumbnail_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c.jpg",
                                    "hash": "thumbnail_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                    "mime": "image/jpeg",
                                    "name": "thumbnail_It's None Of Your Business Album Cover.jpeg",
                                    "path": null,
                                    "size": 9.98,
                                    "width": 156,
                                    "height": 156,
                                    "provider_metadata": {
                                        "public_id": "v2images/thumbnail_It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                        "resource_type": "image"
                                    }
                                }
                            },
                            "hash": "It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                            "ext": ".jpeg",
                            "mime": "image/jpeg",
                            "size": 308.79,
                            "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698519/v2images/It_s_None_Of_Your_Business_Album_Cover_4cbe83397c.jpg",
                            "previewUrl": null,
                            "provider": "cloudinary",
                            "provider_metadata": {
                                "public_id": "v2images/It_s_None_Of_Your_Business_Album_Cover_4cbe83397c",
                                "resource_type": "image"
                            },
                            "createdAt": "2022-07-01T18:02:04.135Z",
                            "updatedAt": "2022-07-01T18:02:04.135Z"
                        }
                    }
                },
                "content": [
                    {
                        "id": 1,
                        "__component": "paragraph.paragraph",
                        "paragraph": "Caravan vient de sortir son quinzième album \"It's None Of Your Business\" le 08 octobre sur le label Madfish. Il est composé de 10 titres pour une durée totale de cinquante minutes."
                    },
                    {
                        "id": 1,
                        "__component": "image.image"
                    },
                    {
                        "id": 2,
                        "__component": "paragraph.paragraph",
                        "paragraph": "1. Down From London (4:03) \n2. Wishing You Were Here (3:55) \n3. It’s None Of Your Business (9:40) \n4. Ready Or Not (4:45) \n5. Spare A Thought (4:06) \n6. Every Precious Little Thing (4:25) \n7. If I Was To Fly (3:23) \n8. I’ll Reach Out For You (8:07) \n9. There Is You (4:26) \n10. Luna’s Tuna (3:14) "
                    },
                    {
                        "id": 2,
                        "__component": "image.image"
                    },
                    {
                        "id": 1,
                        "__component": "quote.quote",
                        "quote": "Assis en cercle avec un contact visuel dans une grande salle était nécessaire. Je préfère de loin cette méthode parce que vous pouvez échanger des idées les unes avec les autres au fur et à mesure qu'elles se produisent et exprimer des encouragements lorsque tout commence à s'enclencher. Il est beaucoup plus gratifiant de pouvoir se lancer des insultes en personne plutôt que par téléphone ou par e-mail. C'est quelque chose dans lequel nous sommes tous très expérimentés, croyez-moi !",
                        "quoteAuthor": "Pye Hastings"
                    }
                ],
                "artists": {
                    "data": [
                        {
                            "id": 2,
                            "attributes": {
                                "name": "Caravan",
                                "slug": "caravan-royaume-uni",
                                "country": "Royaume-Uni",
                                "createdAt": "2022-07-01T18:09:26.154Z",
                                "updatedAt": "2022-07-01T18:09:27.544Z",
                                "publishedAt": "2022-07-01T18:09:27.541Z"
                            }
                        }
                    ]
                },
                "createdBy": {
                    "data": {
                        "id": 1,
                        "attributes": {
                            "firstname": "Thierry",
                            "lastname": "Di Lenarda"
                        }
                    }
                }
            }
        }
    ],
    "meta": {}
}

So all good, except the “image.image” components.

When using the query ?populate=deep,6, I get a 500 Error and points to my createdBy lines above (“Cannot read properties of undefined (reading ‘id’)”)
So it seems that the plugins gets rid of everything from the “admin::user” plugin because when I log the response right after strapi.entityService, createdBy, updatedBy, publishedBy are all completely gone.
On the other hand, my image components are populated completely.

{
                        "id": 2,
                        "__component": "image.image",
                        "image": {
                            "data": {
                                "id": 16,
                                "attributes": {
                                    "name": "Pye Hastings.jpeg",
                                    "alternativeText": "Pye Hastings Image",
                                    "caption": "Pye Hastings de Caravan",
                                    "width": 1280,
                                    "height": 1706,
                                    "formats": {
                                        "large": {
                                            "ext": ".jpeg",
                                            "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698667/v2images/large_Pye_Hastings_0b7d524201.jpg",
                                            "hash": "large_Pye_Hastings_0b7d524201",
                                            "mime": "image/jpeg",
                                            "name": "large_Pye Hastings.jpeg",
                                            "path": null,
                                            "size": 65.46,
                                            "width": 750,
                                            "height": 1000,
                                            "provider_metadata": {
                                                "public_id": "v2images/large_Pye_Hastings_0b7d524201",
                                                "resource_type": "image"
                                            }
                                        },
                                        "small": {
                                            "ext": ".jpeg",
                                            "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698668/v2images/small_Pye_Hastings_0b7d524201.jpg",
                                            "hash": "small_Pye_Hastings_0b7d524201",
                                            "mime": "image/jpeg",
                                            "name": "small_Pye Hastings.jpeg",
                                            "path": null,
                                            "size": 18.46,
                                            "width": 375,
                                            "height": 500,
                                            "provider_metadata": {
                                                "public_id": "v2images/small_Pye_Hastings_0b7d524201",
                                                "resource_type": "image"
                                            }
                                        },
                                        "medium": {
                                            "ext": ".jpeg",
                                            "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698668/v2images/medium_Pye_Hastings_0b7d524201.jpg",
                                            "hash": "medium_Pye_Hastings_0b7d524201",
                                            "mime": "image/jpeg",
                                            "name": "medium_Pye Hastings.jpeg",
                                            "path": null,
                                            "size": 37.99,
                                            "width": 563,
                                            "height": 750,
                                            "provider_metadata": {
                                                "public_id": "v2images/medium_Pye_Hastings_0b7d524201",
                                                "resource_type": "image"
                                            }
                                        },
                                        "thumbnail": {
                                            "ext": ".jpeg",
                                            "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698665/v2images/thumbnail_Pye_Hastings_0b7d524201.jpg",
                                            "hash": "thumbnail_Pye_Hastings_0b7d524201",
                                            "mime": "image/jpeg",
                                            "name": "thumbnail_Pye Hastings.jpeg",
                                            "path": null,
                                            "size": 3.04,
                                            "width": 117,
                                            "height": 156,
                                            "provider_metadata": {
                                                "public_id": "v2images/thumbnail_Pye_Hastings_0b7d524201",
                                                "resource_type": "image"
                                            }
                                        }
                                    },
                                    "hash": "Pye_Hastings_0b7d524201",
                                    "ext": ".jpeg",
                                    "mime": "image/jpeg",
                                    "size": 181.54,
                                    "url": "https://res.cloudinary.com/bigbangmag/image/upload/v1656698665/v2images/Pye_Hastings_0b7d524201.jpg",
                                    "previewUrl": null,
                                    "provider": "cloudinary",
                                    "provider_metadata": {
                                        "public_id": "v2images/Pye_Hastings_0b7d524201",
                                        "resource_type": "image"
                                    },
                                    "createdAt": "2022-07-01T18:04:29.349Z",
                                    "updatedAt": "2022-07-01T18:04:29.349Z"
                                }
                            }
                        }
                    },

Has anyone any idea how to make this work? Strapi 4 is really NOT making our life easier and I find the documentation so light and incomplete. I understand their choice of letting the developers decide when and what to populate, that’s fine. But then they should provide a comprehensive way or mechanism to activate population or not, this is bad DX. I’ve been turning my head upside down on this problem for 3 weeks which is ridiculous. As light and as the so-called migration guides Mongo → mySQL, which has not worked as well despite 3 attempts.

Well done, this work means an article/tutorial I would like to read.

1 Like

Found the issue in the strapi-plugin-populate-deep plugin:
In the plugin’s code in /server/helpers/index.js, there is this:

 const getFullPopulateObject = (modelUid, maxDepth = 20) => {
   if (maxDepth <= 1) {
     return true;
   }
   if (modelUid === "admin::user") {
     return undefined;
   }
...
}

Basically, it rejects and sets to undefined anything coming from the “admin::user” module!!

Went to node_modules/strapi-plugin-populate-deep/server/helpers/index.js and commented out these 3 lines :smiley:

Not only have I my image components populated, but my creator attributes as well!!

1 Like

You could report such bug on the repository and they can fix it as soon as possible.

I proposed a PR to the author where if you use “populate=deepua” instead of “populate=deep”, it keeps the user admin module and allows tapping into its data.
I’ve been using it for the last couple of days successfully!

Brother, you are amazing!

thank you for this. i don’t love that we have to edit things in node_modules, but it is what it is for this solution. Hopefully the strapi team builds something natively that makes accessing image data in components less hacky.

1 Like

Grate worked for me!

worked for me thanks!

It would be amazing!

Could this topic be related too?

Hello everone,

Since Strapi 4.5.0, I cannot access the Contents on the Admin page.

I get an error on the method "reduce’, as if “components” is not defined.

Anyone got an issue as well ?

Did you rebuild the admin after migrating to 4.5.0?

I tried this after reading your message.

But now I get another error:

main.9b85996d.js:890 Error: react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop

It is related to some of the packages or any modification in the admin, You have to check which one is conflicting with your configuration.

1 Like