Search code examples
node.jsreactjspostmanmulter

How to add item with image with react-redux-saga with nodejs/multer


I am trying to save an item that has images in the form. I was able to save the items using postman, but getting issue when trying from react-redux-saga. I am using ant design for the form.

Front-end code:

 handleSubmit = e => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        const { fileList } = this.state;
        const formData = new FormData();
        fileList.forEach(file => {
          formData.append("files[]", file);
        });

        const postItemData = { ...values, images: formData };
        this.props.createItem(postItemData);
      }
    });
  };

saga:

When I try to console, I can get the item details with the image field as a formdata

{
    let itemData = yield select(makeSelectPostItemData());
    const token = yield select(makeSelectToken());
    console.log(itemData, "itemData");
    const response = yield call(request, `/item`, {
      method: "POST",
      headers: {
        Authorization: `${token}`
      },
      body: JSON.stringify(itemData)
    });
    const successMessage = "Item saved successfully!";
    yield put(postItemSuccess(response, successMessage));
  }

nodejs:

const upload = multer({
  storage: storage,
  limits: { fileSize: 1000000 },
  fileFilter: function(req, file, cb) {
    checkFileType(file, cb);
  }
}).array("images");
upload(req, res, err => {
    if (err) {
      console.log(err, "error");
      res.send({ msg: err });
    } else {
      console.log(req, "req");
      if (req.files === undefined) {
        res.send({ msg: "Error: No file selected!" });
      } else {
        const { errors, isValid } = validatePostItem(req.body);
        // check validation
        if (!isValid) {
          return res.status(400).json(errors);
        }

        const files = req.files;
      }
    }
  });

On the last line const files = req.files. When I try from postman, I get file details, but when I try to request it from react, I have no req.files. How can I get the req.files from the react as I am getting from postman?


Solution

  • I have found the solution for this. In the handleSubmit, I have following code:

     fileList.forEach(file => {
              formData.append("files[]", file);
            });
    
            const postItemData = { ...values, images: formData };
            this.props.createItem(postItemData);
    

    Instead of spreading values and inserting the formData in images, what I did was put the all of them into formData.

     fileList.forEach(file => {
              formData.append("files[]", images);
            });
    
     formData.append("name", values.name);
     formData.append("price", values.price);
     formData.append("detail", values.detail);
    
     this.props.createItem(formData);
    

    With this, I could get req.files and req.body.name, req.body.price, req.body.detail in the node side. Quite different from the postman, but this worked for me.