How to upload images from local disk and create relation on json import?

System Information
  • Strapi Version: 3.5.1
  • Operating System: Ubuntu 20.04
  • Database: mysql
  • Node Version: 14.15.5
  • NPM Version: 6.14.11
  • Yarn Version: 1.22.5

I am importing data from a json file using this article as a reference, the only difference is that I am using a local json file stored inside a folder called data on my strapi-app instead of using axios to call an endpoint, I have the images on a local folder where strapi runs. I need to upload this images and create a relation when the entry gets created but I get this error:

error TypeError: strapi.plugins.upload.services.upload.bufferize is not a function

I turns out is because that article is very outdated and bufferize was removed, so how can I accomplish the same without bufferize?

this is the current code I am using to acomplish this task.

api/post/controllers/post.js
"use strict";

/**
 * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
 * to customize this controller
 */

module.exports = {
  import: async (ctx) => {
    const jsonfile = require("fs").readFileSync(
      "./data/posts-test.json",
      "utf8"
    );
    const data = JSON.parse(jsonfile);

    const posts = await Promise.all(
      data.map(
        (post) =>
          new Promise(async (resolve, reject) => {
            try {
              const allimages = await strapi.config.functions.images(
                  post.image
              );
              const [{ id: fileId }] = await strapi.config.functions.upload(
                  allimages
              );

              const postData = {
                title: post.title,
                summary: post.summary,
                body: post.body,
                views: post.views,
                published_at: post.published_at,
                image: [fileId]
              };

              const created = await strapi.services.post.create(postData);
              resolve(created);
            } catch (err) {
              reject(err);
            }
          })
      )
    );

    ctx.send(posts);
  },
};
config/functions/images.js
module.exports = async (url) => {
  const filePath = `./data/images/posts/${url}`;

  return new Promise((resolve) => {
    resolve(filePath);
  });
}
config/functions/upload.js
const path = require("path");
const fs = require("fs").promises;

module.exports = async (imgPath) => {
  // we want the file type without the "." like: "jpg" or "png"
  const ext = path.extname(imgPath).slice(1);
  // name of the file like image01.jpg
  const name = path.basename(imgPath);
  // read contents of file into a Buffer
  const buffer = await fs.readFile(imgPath);
  // get the buffersize using service function from upload plugin
  const buffers = await strapi.plugins.upload.services.upload.bufferize({
    path: imgPath,
    name,
    type: `image/${ext}`,
    size: buffer.toString().length,
  });
  // pass the `buffers` variable to the service function upload which
  // returns a promise that gets resolved upon upload
  return strapi.plugins.upload.services.upload.upload(buffers, {
    provider: "local",
    enabled: true,
    sizeLimit: 10000000,
  });
};

Thanks in advance.

PD: All the data is imported without any problem if I comment the image line. the only problem I am facing is the described above of not being able to upload the image and create the relation because bufferize is not longer a function on the strapi codebase.

Refactored a little bit your upload function.

const path = require("path");
const fs = require('fs');
const mime = require('mime-types'); //used to detect file's mime type

module.exports = async (imgPath) => {
  // name of the file like image01.jpg
  const name = path.basename(imgPath);
  // read contents of file
  const buffer = await fs.statSync(imgPath);
  return strapi.plugins.upload.services.upload.upload({
    data: {}, //mandatory declare the data(can be empty), otherwise it will give you an undefined error.
    files: {
		path: imgPath, 
		name: name,
		type: mime.lookup(imgPath), 
		size: buffer.size,
	},
   });
};

1 Like