Search code examples
reactjspostspring-bootreactjs-flux

POST a file with React.js


The end user is supposed to upload through a file browser an excel file:

<FloatingActionButton title="Upload excel" primary className="import-vendor"
                      containerElement="label"
                      label="Browse file">
      <input onChange={(e) => Actions.uploadXLS(e.target.files[0])} 
             type="file" 
             name="xls" 
             accept="application/vnd.ms-excel" 
             style={{ display: 'none' }}/>
      <UploadIcon/>
</FloatingActionButton>

Action :

uploadXLS(file) {
    this.getInstance().callUploadXLS( file );
}

Service :

callUploadXLS: {
    remote( state, data ) {
        const url = `${base}/vendor/form`;
        return $http.instance.api.post( url, data );
    },
    success: Actions.XLSUploaded,
    error: Actions.fail
}

This file should be sent to a POST REST endpoint built with Spring boot accepting a multipart file. The endpoint does not recognize sending the file like this

error: "Internal Server Error"
exception :"org.springframework.web.multipart.MultipartException"
message : "Current request is not a multipart request"
path : "/vendor/form"
status : 500
timestamp : 1501747384079

How can I post the the excel file?

Edit: I am trying now to post a list of file:

const arrayOfFile = [];
let i = 0;
for ( i = 0; i < files.length; i++ ) {
  const data = new FormData();
  arrayOfFile[i] = data.append( 'file', files[i] );
}
this.getInstance().callUploadXLS( arrayOfFile );

but data.append( 'file', files[i] ); is always returnin undifined


Solution

  • Passing a file to the backend is done via multipart/form-data forms.

    If you inspect the request that you send to the backend right now, you will see that your request does not send ( probably ) a multipart/form-data.

    You can check for reference What does enctype='multipart/form-data' mean? question.

    Your code should look something like :

    callUploadXLS: {
        remote( state, file ) {
                    // ^ make sure that `file` here is the same target.files[0]. It should be `File` Object
    
          // Will turn your form to `multipart/form-data`
          var data = new FormData();
          data.append('file', file);
    
          const url = `${base}/vendor/form`;
          return $http.instance.api.post( url, data );
    
        },
        success: Actions.XLSUploaded,
        error: Actions.fail
    }