So I’ve solved this and I’m adding an example work through here so that if/when others find this page they know what to do.
So let’s assume you’ve posted a file to your Strapi backend
const form = new FormData();
form.append("my_file", file);
axios.post("/api/restaurant", form);
In your controller, you receive a ctx
object, which contains the file in it’s request:
module.exports = async (ctx) => {
const { my_file } = ctx.request.files;
}
To upload it and attach it to a top-level field (i.e. a field that is not in a component/dynamic zone), you can simply do
strapi.service("api::restaurant.restaurant").create({
data: {
// spread any other data
...ctx.request.body
}
files: {
// use the top-level field name as your key, and the file as your value
name_of_the_field: my_file
}
});
To add a file to a component, whilst you create it, you need to upload it. I couldn’t find any docs on how upload works… So what I did was
// the file
const my_file;
const uploaded_file = strapi.service("plugin::upload.upload").upload(
my_file,
{
alternativeText: "Some alt text",
caption: "Some caption or empty string?",
// This line is important for some reason...
// If you don't include it, your media library won't work
mime: my_file.type,
}
);
// this is a file object, and will have a uid that corresponds to a media library object
console.log(uploaded_file);
strapi.service("api::restaurant.restaurant").create({
data: {
// spread all your other data
...ctx.request.body,
// create your component, same for repeatable or single (just no array on single)
some_component: [{
// Your other component data
...component_data,
// Use the id from uploaded_file, in the field of your component that takes a file
component_field_that_takes_a_file: uploaded_file.id
}],
}
});
Hope this helps anyone struggling to understand how add files programmatically.