2

I am trying to send a from from my local system to the backend server via POST request but I am unable to do that every-time it goes with a --binary-data instead of going with a --form.

Here is the sample curl which I want to construct using Node.js:

curl --location --request POST 'some-endpoint' \
--form 'file=@"/Users/name/Desktop/sample.csv"'

Here is the component.html:

<form (ngSubmit)="handleCsvClick()" encrypt="multipart/form-data">
 <input
  type="file"
  name="file-input"
  #fileInput
  [disabled]="requestInProgess"
  (change)="handleFilePick()"
/>
<button
class="upload-btn btn-reset"
type="submit"
>
Upload CSV File
</button>
</form>

Here is the component.ts:

 handleCsvClick(){
    const file = this.fileInputRef.nativeElement.files[0];
    const form = new FormData();
    form.append("file", file);
    const endpoint = `/api/upload-csv`;
    this.http.post(endpoint,form).subscribe((data) => {
      console.log(data);
    });
  }

Node.js

Router file:

const path = require('path');
const express = require("express");
const cookieParser = require("cookie-parser");
const multer = require('multer');
const router = express.Router();
const uuidv4 = require('uuid/v4');
const advisoryController = require("../controllers/advisoryController");
const { UPLOADS_PATH } = require('../config/environment');
const storage = multer.diskStorage({
  destination: UPLOADS_PATH,
  filename: function(_, file, cb) {
    const fileExt = path.extname(file.originalname);
    cb(null, `_csvUploadFile_${uuidv4()}${fileExt}`);
  },
});
const upload = multer({ storage });

router.post("/upload-csv", upload.single("file"), (req, res) => {
  advisoryController
    .uploadCSV(req.file)
    .then(response => res.send(response.data))
    .catch(error => {
      res.status(error.status || 500).send("Something went wrong");
      console.log(error);
    });
});

Controller:

const axios = require("axios");
const { advisoryList } = require("../config/apiConfig");
const fs = require('fs');
const request = require('request');
const FormData = require('form-data');

function uploadCSV(file) {
  let requestUrl = advisoryList.uploadCSV.url;
  const { path } = file;
  const fileUpload = fs.createReadStream(path);
  return new Promise((resolve, reject) => {
    axios
    .post(requestUrl, fileUpload, {headers: {
      'Content-Type': 'multipart/form-data'
    }})
    .then(response => {
      resolve(response.data);
    })
    .catch(error => {
      reject(error)
      console.log("CURL: ", error.request.toCurl());
    });
  })
}

The curl which is getting constructed after all this is coming as --data-binary instead of --form:

curl 'someendpoint' -H 'accept: application/json, text/plain, */*' -H 'content-type: multipart/form-data' -H 'user-agent: axios/0.18.0' --data-binary $'userId,name,age,city\n29298914,vish,30,Bangalore\r\n0\r\n\r\n' --compressed

Instead of:

curl --location --request POST 'some-endpoint' \
--form 'file=@"/Users/name/Desktop/sample.csv"'

Any help would be appreciated. Thanks in advance.

1 Answer 1

2

To send a file with axios in Node.js you need to:

  1. Create a form using form-data library
  2. Set the request headers from the form with getHeaders()

Change your code to this:

const form = new FormData();
form.append('file', fileUpload, path); // 3rd argument is the file name

// Send other fields along with the file
form.append('title', 'Q1 2021');
form.append('description', 'An utterly interesting report');

// Get form headers to pass on to axios
const formHeaders = form.getHeaders();

// Sending a file with axios
axios.post(requestUrl, form, { headers: { ...formHeaders } });

Your question inspired me to turn this answer into an article — Send a File With Axios in Node.js. It covers a few common pitfalls and you'll learn how to send files that are stored as a Buffer or coming from a Stream.

Sign up to request clarification or add additional context in comments.

4 Comments

You are a saviour man, thanks a lot. Just one last question, If I want to send multiple fields along with the file what should be the ideal way of doing that?
You're welcome! I've edited the answer to show you how you can send additional fields.
@Vish your question inspired me to write an article on this — Sending a File With Axios in Node.js. It covers a few common pitfalls and sending files as Buffers or Streams. Thank you for the inspiration!
Great work, Thanks for contributing to the community. It will surely help someone one day.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.