Strapi Upload Plugin - How to place a file generated from strapi backend js code

System Information
  • Strapi Version: 3.2.3 Community
  • Operating System: Ubuntu
  • Database: SQLite
  • Node Version: 12.16.0
  • NPM Version: 6.14.11
  • Yarn Version:

Hi guys!

I need to generate an export CSV file and place it on the Media Library.

Building the code to generate de CSV was an easy task so I will show only the function call:

var csvContent = await strapi.api.product.services.product.export();

Ths issue strated when trying to place it on the media library. Until now, the only solution I founded was to use a post to /upload endpoint but as this is not a professional solution so I’m looking for alternatives.

My Code:

var csvContent = await strapi.api.product.services.product.export(); //trus me, it works
const rootDir = process.cwd();
const fileName = 'ExportedProducts' + new Date().toDateString();
fs.writeFileSync(rootDir + '/public/uploads/' + fileName + '.csv', csvContent);
const form = new FormData();
form.append('files', 'textodeprueba', rootDir + '/public/uploads/' + fileName + '.csv');
axios.defaults.headers.common['Authorization'] = 'Bearer  SAMPLE_TOKEN';
axios.post(`http://localhost:1337/upload`, form, {
    headers: form.getHeaders(),
})
.then(res => {
    strapi.log.info("Building Products CSV File - Status: Finished - Date: " + new Date());
    result.status= "Finished";
})
.catch(err => {
    strapi.log.info("Building Products CSV File - Status: Failed - Date: " + new Date());
    result.status = "Failed";
    result.err = res;
});

I need to generate an export CSV file and place it on the Media Library.

Building the code to generate de CSV was an easy task so I will show only the function call:

var csvContent = await strapi.api.product.services.product.export();

Ths issue strated when trying to place it on the media library. Until now, the only solution I founded was to use a post to /upload endpoint but as this is not a professional solution so I’m looking for alternatives.

My code:

var csvContent = await strapi.api.product.services.product.export(); //trus me, it works
const rootDir = process.cwd();
const fileName = 'ExportedProducts' + new Date().toDateString();
fs.writeFileSync(rootDir + '/public/uploads/' + fileName + '.csv', csvContent);
const form = new FormData();
form.append('files', 'textodeprueba', rootDir + '/public/uploads/' + fileName + '.csv');
axios.defaults.headers.common['Authorization'] = 'Bearer  SAMPLE_TOKEN';
axios.post(`http://localhost:1337/upload`, form, {
    headers: form.getHeaders(),
})
.then(res => {
    strapi.log.info("Building Products CSV File - Status: Finished - Date: " + new Date());
    result.status= "Finished";
})
.catch(err => {
    strapi.log.info("Building Products CSV File - Status: Failed - Date: " + new Date());
    result.status = "Failed";
    result.err = res;
});

This code works but as I’m new with node and strapi, there are many mistakes:

  1. I’m placing the file in the folder to generate the file and then y post it to the API.
  2. I’m hardcoding a token in orden to grant access to the API.

Following this topic I tried to query a save method but it still fails because the collection does not exists

var csvContent = await strapi.api.product.services.product.export();
const rootDir = process.cwd();
const fileName = 'ExportedProducts' + new Date().toDateString() + '.csv';
fs.writeFileSync(rootDir + '/public/uploads/' + fileName, csvContent);
var stats = fs.statSync(rootDir + '/public/uploads/' + fileName);
strapi.query('upload_file').create({
  name: fileName,
  alternativeText: "",
  caption: "",
  hash: uuid.v4(),//random hash
  ext: ".csv",
  mime: "text/csv",
  size: stats.size,
  url: "/uploads/" + fileName,
  provider: "local",
  width: null,
  heught: null

});

Any tidy Ideas to solve it?

@larizzatem

To upload a file from your machine/server and to avoid REST requests, please take a look at the following example:

const mime = require('mime-types'); //used to detect file's mime type
const fs = require('fs');
const rootDir = process.cwd();
const fileName = 'test.csv';
const filePath = `${rootDir}/public/uploads/${fileName}`
const stats = fs.statSync(filePath);

//uploading it directly to upload services.
await strapi.plugins.upload.services.upload.upload({
    data:{}, //mandatory declare the data(can be empty), otherwise it will give you an undefined error.
    files: {
		path: filePath, 
		name: fileName,
		type: mime.lookup(filePath), // mime type of the file
		size: stats.size,
	},
});

Take a look that I uses a third party library called mime-types. That one is already installed in your project as it is used by Strapi.

8 Likes

@sunnyson
Thanks for helping!
Do you know where can i get documentation related to the upload service?
Google links looks broken from last week and cannot find nothing related to this.

Solution proposed by @sunnyson resolved the issue but need to add some notes:

  1. mime-types is not included and when I installed it, getType() function was not recognized. Solved installing just “mime” library.

  2. The next place was to relate my own collection with the placed file, refering to THIS REPLY I could easily found the way.

Unfortunately, the documentation is really poor ubt thanks to the community for helping!

You sir, are a hero