How to upload an image via REST for a dynamic-zone component

In the process of migrating to strapi v4 we try to get our various media upload controllers to work.

We send formData via POST to our controller that should create a collectionType page with a dynamicZone content with multiple components.

In the v4 documentation there’s a green hint:

If you want to upload files for a component, you will have to specify the index of the item you want to add the file to: files.my_component_name[the_index].attribute_name

However this is not working for us.
The media is uploaded to the media gallery but not linked to the component inside of the dynamic-zone.
(a media outside of the dynamic-zone gets linked correctly)

So my questions…

  1. Is this even working in v4 or just some “promise for the future”?
  2. In v3 it was files.my_name_of_the_dynamic_zone[the_index].attribute_name - so we also assumed a typo here, but that is also not working.

Can anyone confirm or explain how we can upload images via REST in one request to components inside a dynamic-zone, like we did in v3?

Cheers,
Olaf - lost in v4 migration since 4 days -

I am currently stucked at the exact same thing. can anybody provide an example how this

files.my_component_name[the_index].attribute_name (Upload | Strapi Documentation )

works?

In my collection type the non nested media attributes are getting correctly assigned.

Example:
files.avatar does work in my formData on save the attribute avatar is filled with the new uploaded file/image.

files.todolist[0].img does not work. The file is uploaded to the media library but is not assigned to my nested field todolist[0].img while todolist is a dynamic zone and at position 0 there is a component with an attribute called img

In strapi v3 I did the exact same thing and it was working fine.

EDIT: I am using a custom controller and no create/update core controller from my entity. I am trying to get this working with my own controller logic

Update: I tried it with the core controller without success.

Same behaviour as the custom controller. I dont know whats the problem here. Help would be much appreciated.

Here is a screenshot with my configuration (Content types builder and Postman):

and this is my custom controller:

async customCreate(ctx) {
    console.log(ctx.is("multipart"));

    if (ctx.is("multipart")) {
      const { data, files } = parseMultipartData(ctx);
      
      const entry = await strapi.entityService.create(pageApi, {
        data: { ...data },
        files: { ...files },
      });
      
      return entry;
    }
}

Can anybody help me out?

1 Like

Thanks for sharing @CucumberJoe.

The problem with uploading images to component is also described here:

So it seems to be a bug in v4 and I consider delaying the migration to v4 until basic functionalities work like they did in v3. (though for you this might be not an option)

Hi, I’m also facing the same problem. In my case, I can upload image file to my ‘music’ field when creating entries via strapi.entityService like this:

await strapi.entityService.create(“api::article.article”, {
data: article,
files: {
music: {
path: filePath,
name: fileName,
type: mime.lookup(filePath),
size: stats.size,
}
},
});

However, I don’t know how to upload image file to component’s field, what if, my ‘music’ field is within a ‘content’ component, then how can I upload using the method I provided ?

Please help me out @lolafkok @CucumberJoe

Has this been resolved? I am facing the same issue.

Yes, I was able to solve it with this code:

await strapi.entityService.create(“api::article.article”, {
data: article,
files: {
“content.music”: {
path: filePath,
name: fileName,
type: mime.lookup(filePath),
size: stats.size,
}
},
populate: [“content.music”],
});

Hi,

Anyone can solve this using REST POST “/upload” ?

    $data = [
        "files" => $file,
        "ref" => "api::blog-post.blog-post",
        "field" => "blocks.media[0].image",
        "refId" => 5,
    ];

I have a dynamic zone called “blocks” and a component called “media”

2 Likes

Hi, have you been able to solve this ?

1 Like

Using Martin’s code above, this is how I was able to do it:

$data = [
    "files" => $file,
    "ref" => "blocks.media", // the name of the dynamic zone and component
    "field" => "image", // the field within the component
    "refId" => 5, // the id of the component "media" block
];

I hope this helps!

1 Like

thanks! this work for my.