strapi-plugin-populate-deep icon indicating copy to clipboard operation
strapi-plugin-populate-deep copied to clipboard

Some images are not populated in a dynamic zone when repeatable field named as "items"

Open whitetown opened this issue 2 years ago • 6 comments

I discovered some weird bug with naming.

I have a collection "pages". it contains a dynamic zone (sections) with a few components. For example there are four components:

  • hero
  • cards
  • tabs
  • instructions

All these components have another, the same repeatable component.

  • In "hero" I named it breadcrumbs
  • in "cards" just items
  • in "tabs" - tabs
  • in "instructions" - also items

For some reason images are not populated in cards and instructions

you can see see the output from the api there: https://cms.propera.ch/api/energy-pages/43?populate=deep,10

if I explicitly ask to populate sections.items.image - it returns the image for cards and instructions https://cms.propera.ch/api/energy-pages/43?populate[0]=sections.items.image but of course everything else is missing

What could be a reason? Initially I blamed myself, then recently updated strapi, so I tried to downgrade it. Finally I added one more repeatable field to "cards" and named it differently (cards:). and images start working for the field.

initial compare hero and cards

hero-cards

the same component in tabs

tabs

the same component in cards but named differently

cards

So I think that it's definitely because of the name "items".

of course I can rename it although it requires some extra work for me on the company web portal. :/

whitetown avatar Sep 30 '23 13:09 whitetown

Hey @whitetown, we had similar issues with fields not being populated in some dynamic zones. Following patch fixed it (used with patch-package library)

diff --git a/node_modules/strapi-plugin-populate-deep/server/helpers/index.js b/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
index 7f026b8..e82c1ee 100644
--- a/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
+++ b/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
@@ -1,4 +1,20 @@
-const { isEmpty, merge } = require("lodash/fp");
+const { isEmpty } = require("lodash/fp");
+
+const deepAssign = (target, source) => {
+    for (const key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        if (typeof source[key] === 'object' && source[key] !== null) {
+          if (!target[key] || typeof target[key] !== 'object' || target[key] === null) {
+            target[key] = source[key];
+          }
+          deepAssign(target[key], source[key]);
+        } else if (!target[key] || typeof target[key] !== 'object' || target[key] === null) {
+          target[key] = source[key];
+        }
+      }
+    }
+    return target;
+}
 
 const getModelPopulationAttributes = (model) => {
   if (model.uid === "plugin::upload.file") {
@@ -32,7 +48,7 @@ const getFullPopulateObject = (modelUid, maxDepth = 20, ignore) => {
       } else if (value.type === "dynamiczone") {
         const dynamicPopulate = value.components.reduce((prev, cur) => {
           const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
-          return curPopulate === true ? prev : merge(prev, curPopulate);
+          return curPopulate === true ? prev : deepAssign(prev, curPopulate);
         }, {});
         populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
       } else if (value.type === "relation") {

HonzaTuron avatar Oct 03 '23 08:10 HonzaTuron

Hey @whitetown, we had similar issues with fields not beint populated in some dynamic zones. Following patch fixed it (used with patch-package library)

Wow. it helped. thanks a lot!

whitetown avatar Oct 03 '23 17:10 whitetown

same here, but my collections are not named items but rather links - that said the image inside is named image.

y-nk avatar Dec 04 '23 09:12 y-nk

Hey, encounter the same problem ... When the fix will be delivered as a new release plz ?

JunkyDeLuxe avatar Jan 29 '24 14:01 JunkyDeLuxe

without changing the code in the suggestion I was able to see this working by changing:

http://localhost:1337/api/homepage?populate=deep to http://localhost:1337/api/homepage?populate=deep,10

this made the images in my dynamic / repeating component render in the JSON.

maybe this had already been fixed in the plugin and/or strapi? i just installed yesterday:

"dependencies": { "@strapi/plugin-cloud": "4.24.5", "@strapi/plugin-graphql": "^4.24.5", "@strapi/plugin-i18n": "4.24.5", "@strapi/plugin-users-permissions": "4.24.5", "@strapi/strapi": "4.24.5", "better-sqlite3": "8.6.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-dom": "5.3.4", "strapi-plugin-populate-deep": "^3.0.1", "styled-components": "5.3.3" },

denglert23 avatar Jun 11 '24 15:06 denglert23

Hey @whitetown, we had similar issues with fields not being populated in some dynamic zones. Following patch fixed it (used with patch-package library)

diff --git a/node_modules/strapi-plugin-populate-deep/server/helpers/index.js b/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
index 7f026b8..e82c1ee 100644
--- a/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
+++ b/node_modules/strapi-plugin-populate-deep/server/helpers/index.js
@@ -1,4 +1,20 @@
-const { isEmpty, merge } = require("lodash/fp");
+const { isEmpty } = require("lodash/fp");
+
+const deepAssign = (target, source) => {
+    for (const key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        if (typeof source[key] === 'object' && source[key] !== null) {
+          if (!target[key] || typeof target[key] !== 'object' || target[key] === null) {
+            target[key] = source[key];
+          }
+          deepAssign(target[key], source[key]);
+        } else if (!target[key] || typeof target[key] !== 'object' || target[key] === null) {
+          target[key] = source[key];
+        }
+      }
+    }
+    return target;
+}
 
 const getModelPopulationAttributes = (model) => {
   if (model.uid === "plugin::upload.file") {
@@ -32,7 +48,7 @@ const getFullPopulateObject = (modelUid, maxDepth = 20, ignore) => {
       } else if (value.type === "dynamiczone") {
         const dynamicPopulate = value.components.reduce((prev, cur) => {
           const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
-          return curPopulate === true ? prev : merge(prev, curPopulate);
+          return curPopulate === true ? prev : deepAssign(prev, curPopulate);
         }, {});
         populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
       } else if (value.type === "relation") {

I was looking for morph logic in strapi source for whole day and saw your comment. You saved me sirrrrr!!

vuletiki avatar Jul 15 '24 00:07 vuletiki