Search code examples
javascriptnode.jsexpressfetchsweetalert2

Upload image file with Sweetalert2 and Expressjs


I want to upload image to my server with SweetAlert2 and Expressjs.

When I use HTML input with name attribute, it works fine. But I want to use with SweetAlert2 and it's not working.

I use SweetAlert2 document's example. And It seems that I can get image data console.log(result) but I cannot send it to my server. When I send request to my server, the console.log(req.file); still get undefined data.

I use 'Fetch API' because I don't want to use Ajax or jQuery.

I upload Client Part on JsFiddle you can check in here

[Client Part]

async function start() {
  await Swal.fire({
    title: "Please Select Image File",
    input: "file",
    inputAttributes: {
      accept: "image/*",
      "aria-label": "Select Image",
    },
    showLoaderOnConfirm: true,
    preConfirm: (result) => {
      console.log(result);
      const reader = new FileReader();
      console.log(file);
      reader.onload = (e) => {
        let timerInterval;
        Swal.fire({
          title: "Wait for Upload",
          imageUrl: e.target.result,
          iamgeHeight: 200,
          imageWidth: 200,
          imageAlt: "The uploaded picture",
          didOpen: () => {
            Swal.showLoading();
            return fetch(`${MY_SERVER_URL}`, {
                method: "POST",
                headers: {
                  Accept: "application/json",
                },
                body: reader,
              })
              .then((response) => {
                // console.log(response);
                if (!response.ok) {
                  throw new Error(response.statusText);
                }
                return response.json();
              })
              .catch((error) => {
                Swal.showValidationMessage(
                  `Request failed: ${error}`
                );
              });
          },
          willClose: () => {
            console.log('Nothing')
          },
        }).then((result) => {
          /* Read more about handling dismissals below */
          if (result.dismiss === Swal.DismissReason.timer) {
            console.log("I was closed by the timer");
          }
        });
      };
      reader.readAsDataURL(result);
    },
  });
}

start();
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>

<body>

</body>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>

</html>

[Server Part (Express.js)]

var express = require("express");
var router = express.Router();
const multer = require("multer");
var storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "./public/images");
  },
  filename: (req, file, cb) => {
    console.log(file);
    var filetype = "";
    if (file.mimetype === "image/gif") {
      filetype = "gif";
    }
    if (file.mimetype === "image/png") {
      filetype = "png";
    }
    if (file.mimetype === "image/jpeg") {
      filetype = "jpg";
    }
    cb(null, "image-" + Date.now() + "." + filetype);
  },
});
var upload = multer({
  storage: storage,
});

router.post("/uploadImage", upload.single("file"), async (req, res, next) => {
  console.log(req.file);
  console.log("good");
  let fileName = req.file.filename;
  res.redirect(
    `${MY_SERVER_URL_REDIRECT_URL}`
  );
});

Solution

  • Your backend expects an file named file

    You can use FormData

    let formdata = new FormData()
    formdata.append('file', file)
    

    Then you send it. Also to note here, your request isnt application/json.

    make sure not to set the Content-Type header. The browser will set it for you, including the boundary parameter.

    fetch(`${MY_SERVER_URL}`, {
       method: "POST",
       body: formdata,
    })