0

How can I send an image along with a text in VueJs to my backend ExpressJs?

Right now, what I did was create two http post request

NOTE this.albumName and this.albumDesc are just text and the formData is an image.

createAlbum() {
      const formData = new FormData();
      for (let file of Array.from(this.myAlbumImages)) {
        formData.append("files", file);
      }

      if (this.albumName) {
        axios
          .post("http://localhost:9001/image/album", {
            ALBUM: this.albumName,
            DESCRIPTION: this.albumDesc
          })
          .then(resp => console.log(resp))
          .catch(err => console.log(err));
        setTimeout(function() {
          axios
            .post("http://localhost:9001/image/album", formData)
            .then(resp => console.log(resp))
            .catch(err => console.log(err));
        }, 3000);

        this.albumName = "";
        this.albumDesc = "";
      } else {
        alert("Please fill the above form.");
      }
    },

and here is my Backend.

This creates the folder based on the passed data and it also creates a named undefined folder

router.post('/album', (req, res) => {
let sql = "INSERT INTO GALLERY SET ALBUM = ?, DESCRIPTION = ?";
let body = [req.body.ALBUM, req.body.DESCRIPTION]
myDB.query(sql, body, (error, results) => {
    if (error) {
        console.log(error);
    } else {
        let directory = `C:/Users/user/Desktop/project/adminbackend/public/${req.body.ALBUM}`;
        fse.mkdirp(directory, err => {
            if (err) {
                console.log(err);
            } else {
                console.log(directory);
            }
        })
    }
})

I think this is because of NodeJS is Asynchronous that's why it creates the undefined folder.

2 Answers2

0

for the first part the client may can help you this link How to post image with fetch?

const fileInput = document.querySelector('#your-file-input') ;
const formData = new FormData();

formData.append('file', fileInput.files[0]);

    const options = {
      method: 'POST',
      body: formData,
      // If you add this, upload won't work
      // headers: {
      //   'Content-Type': 'multipart/form-data',
      // }
    };

    fetch('your-upload-url', options);

and for the seerver part cant help you this link Node Express sending image files as API response

app.get('/report/:chart_id/:user_id', function (req, res) {
    res.sendFile(filepath);
});

and oficial documentation about this http://expressjs.com/en/api.html#res.sendFile

0

Reason for behavior you see is you are sending two different requests to the same route. 1st includes ALBUM and DESCRIPTION form field values, but not the files. Second (inside setTimeout) will contain just files and no other fields, so referencing them like req.body.ALBUM will return undefined

You can send all data (text fields and files) in one request. Just do this:

const formData = new FormData();
for (let file of Array.from(this.myAlbumImages)) {
  formData.append("files", file);
}
formData.append("ALBUM", this.albumName);
formData.append("DESCRIPTION", this.albumDesc);
axios.post("http://localhost:9001/image/album", formData)
     .then(resp => console.log(resp))
     .catch(err => console.log(err));

FormData always uses content type multipart/form-data. To parse it on server side you need Express middleware that parses multipart forms, and gives you access to both fields and image/s. For example multer...

Michal Levý
  • 33,064
  • 4
  • 68
  • 86