Search code examples
javascriptreactjsreduxfetcharray-map

React Redux Array.Map Fetch - return success when all files succeeded


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.


Solution

  • 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}