I have to send file as well as some json data to server using axios and decode it into express server to store json in mongodb and file using multer

Issue

I want to create an endpoint which should store file on server side as well as the some json data which should be received from same point is to be stored on mongodb.
I am using axios to send request from React App. Here is my Code.

  const [companyFile, setCompanyFile] = useState(null);
  const [company, setCompany] = useState({
    name: "",
    websiteUrl: "",
    email: "",
    companyLocation: "",
  });

  const AddCompany = async (e) => {
    if (companyFile) {
      e.preventDefault();
      let formData = new FormData();
      formData.append("company-file", companyFile);
      formData.append("company", JSON.stringify(company));

      axios({
        method: "post",
        url: `http://localhost:8080/company/add`,
        data: formData,
        withCredentials: true,
        header: {
          Accept: "application/json",
          "Content-Type": "multipart/form-data",
        },
      }).then((res) => console.log(res.data));
    } else {
      console.log("file not selected!!!!");
    }
  };

Now I don’t know how to check if it is coming to backend express server or not? Or if coming then how to retrive application/json data from request for further process.

My question is that if data is sent to backend express then how to process that data in backend (i.e. get json data to create an document in mongodb).
Here is my code for company/add

let upload = multer({
  storage: multer.diskStorage({
    destination: async (req, file, cb) => {
      if (!company) {
        throw Error("Company cannot be found!");
      }
      let companyName = req.company.name;
      let path = `./uploads/${companyName}/files`;
      if (!fs.existsSync(path)) {
        fs.mkdirSync(path, { recursive: true });
      }
      cb(null, path);
    },
    filename: async (req, file, cb) => {
      //  ** with student auth Code

      req.filename = req.company.name;
      cb(null, filename + path.extname(file.originalname));
    },
  }),
}).single("company-file");

// Add Company
module.exports.add_company = async (req, res) => {
  try {
    // Here I want to extract that company object to create new company
    console.log(req.file);
    try {
      const newcompany = await Company.create(company);
      req.company = newcompany;
      upload(req, res, async () => {
        try {
          const companyFile = await CompanyFile.create({
            companyId: req.company._id,
            path: `./uploads/${req.company.name}/file/${req.filename}.pdf`,
          });
          req.companyFile = companyFile;
        } catch (err) {
          res.status(400).json({ success: false, message: err.message });
          // ** code for resume-upload using student authentication middleware
          if (
            fs.existsSync(
              `./uploads/${req.company.name}/file/${req.filename}.pdf`
            )
          ) {
            fs.unlink(`./uploads/${req.company.name}/file/${req.filename}.pdf`);
          }
        }
      });
      res.status(201).json({
        success: true,
        message: "Company Drive Added Successfully.",
        company: req.company,
        companyFile: req.companyFile,
      });
    } catch (err) {
      res.status(400).json({
        success: false,
        errors: err,
        message: "Error while applying company drive.",
      });
    }
  } catch (err) {
    console.log(err);
  }
};

Solution

From the docs:

Multer adds a body object and a file or files object to the request
object. The body object contains the values of the text fields of the
form, the file or files object contains the files uploaded via the
form.

So in your case, you can access and parse the company field by doing:

const company = JSON.parse(req.body.company);

Also, you need to make sure to apply the multer middleware to your controller, e.g.

app.post('/company/add', upload.single('company-file'), function (req, res, next) {
  // req.file is the `company-file` file
  // req.body.company will hold the company text field
})

Answered By – eol

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published