Bob
Bob

Reputation: 482

How to save a FormData image file locally with "fs" in Node

I have a React front-end that allows user to send an image using FormData() to the node backend.

In the Express backend's controller, I am using multer as a middleware to grab the image into the files variable:

  private initializeRoutes() {
    this.router.post(`${this.path}/image`, multerUpload.array("filesToUpload[]"), this.saveImage);
  }

In the backend's service, I am trying to save files[0] into the uploads folder:

  public saveImage(files: any) {
    console.log("OtherServiceLocal saveImage - files :");
    console.log(files[0]); // see screenshot at bottom for output

    let localPath = fs.createWriteStream("./uploads/image.png");

    files[0].buffer.pipe(localPath);
  }

But I am getting the error: enter image description here

I tried piping file[0] and file[0].buffer to no avail, and I had difficulty understanding how to transform it into a stream even after some research.

This is the outputs for console.log(files[0]);

{
  fieldname: 'filesToUpload[]',
  originalname: 'Screen Shot 2021-09-08 at 3.42.48 PM.png',
  encoding: '7bit',
  mimetype: 'image/png',
  buffer: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 03 85 00 00 02 c5 08 06 00 00 00 74 ff 46 78 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 00 62 ... 249405 more bytes>,
  size: 249455
}

Please note that I am aware that you can use multer's upload method to save the image as a middleware directly in the router, but I can't to do this due to some requirement of my app.

Thanks,

Upvotes: 5

Views: 5849

Answers (2)

Kartik Chandra
Kartik Chandra

Reputation: 430

In Node JS with TypeScript

I am using the below package for the UPLOAD process. We can also use the MULTER npm package as well.

npm i formidable

import * as path from "path";
const fs = require("fs");
const formidable = require('formidable');



    async saveMediaFileInMachineStorage(req: ReqInterface, res: ResInterface, next: NextFunction) {
      const form = new formidable.IncomingForm();

        form.parse(req, async function (err, fields, files) {

        if (err) {
            console.log("Error", err)
        }
        if(files?.profilePic){
                    let writer = fs.createWriteStream(files?.profilePic[0]?.originalFilename, { flags: 'w' } ); 
                    let reader = fs.createReadStream(files?.profilePic[0].filepath).pipe(writer);
       }
    })

// return res.status(200).json({ status: 200, statusText: 'SUCCESS', message: "File in storage.", data: {status: true} })

}
    

Below is API Request over POSTMAN which we have to send for testing upload file process. enter image description here

Upvotes: 0

lx1412
lx1412

Reputation: 1200

file[0].buffer is an instance of Buffer. So you can use fs.writeFile directly

fs.writeFile("./uploads/image.png", file[0].buffer, (err) => {
    console.error(error)
})

Upvotes: 1

Related Questions