2

How can I access the files in the API?

I read the other solutions and all of them require npm packages to solve this. I want to understand why I can't do it vanilla. Also, the answers are old and recommend using body-parser, which now comes bundled with Express.

I would like the solution to be vanilla JS in order to understand the process better.

client

async function uploadFile(file) {
    let formData = new FormData();
    formData.append("file", file);

    let res = await fetchPostFile("/api/files", formData);
}

fetch

export async function fetchPostFile(url, formData) {
    try {
        let result = await (
            await fetch(url, {
                method: "POST",
                withCredentials: true,
                credentials: "include",
                headers: {
                    Authorization: localStorage.getItem("token"),
                    Accept: "application/json",
                    "Content-type": "multipart/form-data",
                },
                body: formData,
            })
        ).json();

        return result;
    } catch (err) {
        return err;
    }
}

api

router.post("/api/files", async function (req, res, next) {
    try {
        console.log(req.file);          // undefined
        console.log(req.files);         // undefined
        console.log(req.body);          // {}

    } catch (err) {
        next(err);
    } finally {
        req.connection.release();
    }
});

Why is the req.body empty? Please help me understand what I'm doing wrong.

Ivan
  • 1,434
  • 2
  • 26
  • 49
  • Does this answer your question? [Express js form data](https://stackoverflow.com/questions/24800511/express-js-form-data) – peteb Jan 10 '21 at 18:09
  • No, as body parser is built-in in Express, and the `req.body` is empty in my case. I asked this question after researching everything. – Ivan Jan 11 '21 at 05:08
  • [`body-parser`](https://www.npmjs.com/package/body-parser) is not built-in. However, since you're using `multipart/form-data` you'll need to use [`multer`](https://www.npmjs.com/package/multer) instead. Both of these points are made in the answer I linked. – peteb Jan 11 '21 at 07:01

1 Answers1

5

First you need to use multer package to handle multipart/form-data in express. You must use it as a middleware to set the field name for the file. The name passed as an argument to the single() function must match to the appended name on client side.

const multer = require('multer')

router.post("/api/files", multer().single('file'), async function (req, res, next) {
  try {
      console.log(req.file)
  } catch (err) {
      next(err)
  } finally {
      req.connection.release()
  }
});
Ara Galstyan
  • 370
  • 2
  • 10
  • 2
    Why do I need a package for this? I specifically asked for a vanilla way to do this. – Ivan Jan 11 '21 at 05:06
  • I get that, but why is Multer required? – Ivan Jan 11 '21 at 07:32
  • 1
    You tried to send form-data, but you didn't tell the express that it should expect form-data. Multer gives ability to handle the form-data that the client sends. – Ara Galstyan Jan 11 '21 at 08:36
  • So you're saying that you MUST use a library, i.e. Express doesn't support it as is. – Ivan Jan 11 '21 at 08:40
  • Why do you want do it with vanilla js, if there are tools that makes your work easier? – Ara Galstyan Jan 13 '21 at 11:06
  • 1
    Just to understand the process. Is it bad to learn? I don't want to just blindly add dependencies. – Ivan Jan 13 '21 at 13:36
  • It works the vanilla way with Python flask for example, I assume it should be possible with express too. – bsrdjan Dec 21 '21 at 23:27
  • 2
    Just to add here, Multer is a recommended way to access the file by Express. Refer: https://expressjs.com/en/resources/middleware/multer.html – Saarang Tiwari Feb 14 '22 at 12:08