How do I upload files from mobile to the API in React Native?

113 views Asked by At

The react native app (Android in this case) is supposed to upload files selected using the react-native-document-picker and POST it to the backend api. The backend is a Spring Boot app and uses Apache Commons Fileupload and therefore multipart=false. Now in Angular, I am able to append the files to a formData, which would be passed in the request body where as other "@RequestParams" would be sent via HttpParams.

I tried the similar approach but didn't work, not sure what I am missing. The following solutions also didn't help:

Note: I cannot modify the backend api to enable multipart. Axio is used for api calls

This is what I have right now:

UploadButton import { uploadDocuments } from '../../services/ApiService';

const result = await DocumentPicker.pick({
   type: [DocumentPicker.types.allFiles]
});

const uploadData = {
    parentId: 1,
    userId: 1
}

const data = new FormData();
data.append("file", files[0]);

uploadFiles(data, uploadData).then(res => {
   console.log('files uploaded');
}).catch((err) => {
   console.log('errr uploading files: ' + JSON.stringify(err));
})

uploadFiles - API Service

return axios.post(`${API_URL}/api/uploadFiles`, formData, {
        params: {
            parentId: parentId,
            userId: userId
        }, 
        responseType: 'text', 
        headers: { 'Content-Type': 'multipart/form-data' }
    });

Spring Boot API

@PostMapping(value = "/uploadFiles", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
  public ResponseEntity<String> addDocuments(@RequestParam Long parentId,
                                             @RequestParam Long userId,
                                             HttpServletRequest request) {
//
DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setRepository(new File(UPLOAD_DIR));

    factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
    factory.setFileCleaningTracker(null);

    ServletFileUpload upload = new ServletFileUpload(factory);

    List<FileItem> items = upload.parseRequest(request);
// rest of the code
}

Logs - All I get is 400 Bad Request - No errors in backend

 LOG  uploading files: 1
 LOG  file data => name: sample.pdf uri: content://com.android.externalstorage.documents/document/primary%3Asample.pdf
 LOG  dots: [{"guid":"170560870473535714196193642705","displayName":"sample.pdf"}]
 LOG  errr uploading files: {"message":"Request failed with status code 400","name":"AxiosError","stack":"AxiosError: Request failed with status code 400\n    at settle (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.dvsapp&modulesOnly=false&runModule=true:174577:37)\n    at onloadend (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.dv***Trimmed to clear spam filter***,"config":{"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false},"adapter":["xhr","http"],"transformResponse":[null],"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"env":{},"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"multipart/form-data","Authorization":"Bearer eyJhbGciOiJ},"params":{"parentId":2,"userId":22,"responseType":"text","method":"post","url":"https://apigone.virtual-datarooms.uk/api/buploadFiles","data":{"_parts":[["file",{"fileCopyUri":null,"size":861148,"name":"sample.pdf","type":"application/pdf","uri":"content://com.android.externalstorage.documents/document/primary%3Asample.pdf"}]]}},"code":"ERR_BAD_REQUEST","status":400}
0

There are 0 answers