1

I have a component inside a modal where I can upload multiple files, It has to be closed when all files are already uploaded or give me a message if one of them failed to upload .eg(file too large)

Component - ModalUploadFile.jsx

this.state = { files: [file1, file2, file2] }

Following codes will be called when submit button clicked

uploadFile = () => {
    this.refs.btn.setAttribute("disabled", "disabled");
    this.state.files.map( function(file) {
        this.props.saveFile(this.props.selected_candidate.id, file)
      }, this
    ) 
}

Sagas.js

function* saveFile(action) {
  try {

    let file = action.file
    let formData = new FormData()
    formData.append("file", file)

    let result = yield fetch(URL, {
      method: "POST",
      credentials: "same-origin",
      body: formData
    }).then(response => response.json()).then(data => {
      return data
    })
    yield put({
      type: actionTypes.FILE_UPLOADED,
      ci: result
    })
    yield put({
      type: actionTypes.CLOSE_MODAL
    })
  } catch (ex) {
    console.log(ex)
  }
}

Currently, The Upload Modal will be closed when one of the files successfully uploaded.

Carl V.
  • 73
  • 1
  • 7

1 Answers1

1

Right now from your component you are mapping through the array and passing down one file to saga to upload. And your saga will dispatches FILE_UPLOADED action once that is complete and so your modal is closed. Update your saga to accept the array of files. And from saga you can dispatch an action only when all the files in array are uploaded.

Here is an example:

function* saveFiles() {
   const results = yield all(action.payload.files.map(id => call(saveFile, file)));
   yield put({ type: FILES_UPLOADED, payload: { results } })
}

function saveFile(file) {// make your fetch call for each file and return result}
Vinod Kolla
  • 184
  • 4
  • 15
  • If you are familiar with saga could you please provide an example of how `saveFiles` would look like? If it receives files then I would think something like `Promise.all(action.files.map(file=>fetch....` I'm not that familiar with saga so not sure where to yield but would think `put` in the `then` and `catch` and yield the Promise.all – HMR May 16 '18 at 13:27
  • @HMR what would happen if one of the files failed to upload? – Carl V. May 16 '18 at 14:31
  • @CarlV. If one fails then the [whole thing is rejected](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) There is a way around it by catching any rejecting promises in the `map` and returning a [special Fail object](https://stackoverflow.com/a/47678417/1641941) (last code block) in the catch. Then you can inspect the result after and see what files have been successful and what files failed. – HMR May 16 '18 at 14:38
  • @CarlV. I have added an example saga on how to handle multiple file uploads. check it out. – Vinod Kolla May 16 '18 at 14:39