Sarp IŞIK brand logo.

How To Generate Different Image Formats With Strapi-plugin-upload Part II

2020-07-27 - by Sarp IŞIK

Photo by Green Chameleon on Unsplash

In this tutorial, we will handle the delete process of generated different format images.

Not: This is the second part of the tutorial series about how to customize the strapi-plugin-upload to generate different image formats on the fly. If you jumped here directly, you may want to check the first part.

As we did in the previous part, we need to copy the original related implementation from source code and modify it to delete all generated images in different formats. Copy the following method called "remove" and paste inside the Upload.js file after the "uploadFileAndPersist" method:

module.exports = {
...
async remove(file) {
const config = strapi.plugins.upload.config;
// execute delete function of the provider
if (file.provider === config.provider) {
await strapi.plugins.upload.provider.delete(file);
if (file.formats) {
await Promise.all(
Object.keys(file.formats).map((key) => {
return strapi.plugins.upload.provider.delete(file.formats[key]);
})
);
}
}
const media = await strapi.query("file", "upload").findOne({
id: file.id,
});
strapi.eventHub.emit("media.delete", { media });
return strapi.query("file", "upload").delete({ id: file.id });
},
};

Because we kept generated formats and its different sizes as an array of objects, we need to iterate over each format key under the formats property of the original image object to delete:

...
// execute delete function of the provider
if (file.provider === config.provider) {
await strapi.plugins.upload.provider.delete(file);
const formats = file.formats;
if (formats) {
const promises = [];
const formatKeys = Object.keys(formats).filter(
(key) => key !== "base64"
);
for (const key of formatKeys) {
const images = formats[key];
const shouldSkip = !(Array.isArray(images) && images.length > 0);
if (shouldSkip) continue;
for (const image of images) {
promises.push(strapi.plugins.upload.provider.delete(image));
}
}
await Promise.all(promises);
}
}
...

Let's go step by step over the implementation:

  1. We define an empty list of promises which will keep the delete request of each image.
  2. We filter all formats except the base64, which is stored as a string value inside the database instead of as a file on the disk. So it will be deleted automatically when the image entity deleted from the database.
  3. We iterate over-filtered format keys and checking if each format's images list is not an empty array.
  4. We are calling the upload provider's delete method which returns a promise for each image and pushing into the list of the promises.
  5. When the iteration is over, we are waiting for the list of the promises resolved. The rest lines from this part stay the same.

Below is the final version of the remove method:

module.exports = {
...
async remove(file) {
const config = strapi.plugins.upload.config;
// execute delete function of the provider
if (file.provider === config.provider) {
await strapi.plugins.upload.provider.delete(file);
const formats = file.formats;
if (formats) {
const promises = [];
const formatKeys = Object.keys(formats).filter(
(key) => key !== "base64"
);
for (const key of formatKeys) {
const images = formats[key];
const shouldSkip = !(Array.isArray(images) && images.length > 0);
if (shouldSkip) continue;
for (const image of images) {
promises.push(strapi.plugins.upload.provider.delete(image));
}
}
await Promise.all(promises);
}
}
const media = await strapi.query("file", "upload").findOne({
id: file.id,
});
strapi.eventHub.emit("media.delete", { media });
return strapi.query("file", "upload").delete({ id: file.id });
},
};

Ending Notes

So far we can upload images, generate different formats in different sizes, and delete all of them successfully. You can find the final code of this part in Github repo.



© 2020, Sarp IŞIK