For anyone trying to do this and searching for workarounds …
You can’t use the Upload service or API route to upload a file and relate it with a field OF A COMPONENT.
If you need to upload and relate with a field of a component, a workaround is to create a custom route that first upload de image without any relation and then update the entry and the field you want to relate with the image.
In my case, i have the component “documents” that have two field of type media (the names are rg_front and rg_back). I’m using this component in my User collection (user-permissions).
So, i created a custom controller for the collection User called updateDocument, that receive a file and a name of the component it should related with inside the “documents” component.
I know it’s really specific, but i’m sure you can use the same logic and create custom controllers for want you need to update.
plugin.controllers.user.updateDocument = async (ctx) => {
if (!ctx.state.user || !ctx.state.user.id) {
return (ctx.response.status = 401);
}
const body = { ...ctx.request.body };
const acceptedNames = ["rg_front", "rg_back"];
const isDocNameAuthorized =
body.docName && acceptedNames.includes(body.docName);
if (!isDocNameAuthorized) {
return (ctx.response.status = 400);
}
try {
const { files } = ctx.request.files;
const data = {};
if (files) {
const uploadedFile = await strapi
.service("plugin::upload.upload")
.upload({
data,
files,
});
await strapi.entityService.update(
"plugin::users-permissions.user",
ctx.state.user.id,
{
data: {
documents: {
[body.docName]: uploadedFile[0].id,
},
},
}
);
return uploadedFile;
} else {
return ctx.send({ error: "There is no file uploaded" }, 400);
}
} catch (error) {
console.error(error);
return ctx.send({ error: "Error uploading files" }, 500);
}
};
plugin.routes["content-api"].routes.push({
method: "PUT",
path: "/user/updateDocument",
handler: "user.updateDocument",
config: {
prefix: "",
},
});
Be aware to use strapi.entityService.update() instead of strapi.query().update, because the second one don’t update component fields, at least in this case.