send an excel file as a blob in the post api - reactjs

I want to use the post API to send an excel file as a blob file. Below is my code.
const Csvsubmit = (event) => {
console.log("csv", excelFile);
setLoadingcsv(true);
const requestOption = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
file_upload: excelFile,
created_by: user.id,
}),
};
const response = fetch(
process.env.REACT_APP_BACKEND + subdomain + "/staff/csvupload/",
requestOption
).then(
(res) => {
if (res.status === 201) {
res.json().then((json) => {
setLoadingcsv(false);
console.log(json);
setopenid(0);
});
} else if (res.status === 406) {
console.log("file format is not supported");
setLoadingcsv(false);
} else {
setLoadingcsv(false);
res.json().then((json) => {
setLoadingcsv(false);
});
}
},
(error) => {
console.log(error);
}
);
console.log("Answer", requestOption.body);
};
The "csv" cansole blob data is printed, but the body is empty.how to send this file(.xls,.xslx,.csv)

Json doesn't support binary data.
You need to encode the blob into something else, (base64 is recomended),
Good Luck!
See also this answer,
Convert blob to base64

Related

react native base64 image upload fail with status code 400

I want to upload my image as base 64 to the server, after user pick image it stores as base64 in state and then I call upload function but it give me this error: request failed with status code 400.
I need to first call an API and it takes user id and respond with an upload name id, then I call upload image API
here is my implementation:
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
base64: true
});
setImage(result)
};
const uploadImagetoServer = async (userId) => {
let uploadId;
try {
const response = await axios
.post('URL', {
"id": userId
});
console.log('id res', response.data);
uploadId = response.data;
} catch (error) {
console.log(error.message);
}
try {
const response = await axios
.post('ANOTHER_URL', {
headers: {
'Content-Type': 'application/json'
},
"fileName": uploadId,
"fileBase64String": image.base64,
"folderName": "Users",
"fileExtension": ".jpg"
});
console.log('upload res', response.data);
} catch (error) {
console.log(error.message);
}
}
const allowAccess = async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
} else {
pickImage()
.then(() => {
uploadImagetoServer(userData.id)
})
}
}
}
anyone can help me with this? ty
you need to add contentType in headers
'Content-Type': `multipart/form-data;`,
here is an example
npm install --save form-data
import FormData from 'form-data'
let data = new FormData();
data.append('file', file, file.name);
return (dispatch) => {
axios.post(URL, data, {
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
}
})
.then((response) => {
//handle success
}).catch((error) => {
//handle error
});
};}

Expo Download file. FileSystem Download Async method POST with body

I need a way to make a request with method Post passing a body but I didnt find a way to do it. The documentation: https://docs.expo.io/versions/latest/sdk/filesystem/ only show the GET method, I need a way to make a post request passing the body.
FileSystem.downloadAsync(${baseUrl}/v1/paycheck/pdf, FileSystem.documentDirectory + ‘file.pdf’,
{
headers: {
‘Authorization’: localToken
},
httpMethod: ‘POST’,
body: {
type: 'monthy',
year: '2021',
month: 2,
employer: {
name: "Pink",
}
}
}
)
.then(({uri}) => {
Sharing.shareAsync(uri, {dialogTitle: 'Salvar ou Compartilhar'})
})
.catch(error => {
console.error(error);
});
}
As far as I understand your problem
My Approach for Downloading and Sharing the PDF would be
Writing these two functions
// Execute this function when you to share the file...
const GetPDF = async () => {
try {
const response = await fetch(`${baseUrl}/v1/paycheck/pdf`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "localToken",
},
body: JSON.stringify({
type: "monthy",
year: "2021",
month: 2,
employer: {
name: "Pink",
},
}),
});
const content = await response.json();
DownloadThenShare(content); // Some URI
} catch (error) {
console.error(error);
}
};
Now DownloadAndShare function
// This function will execute after Download has been completed successfully
const DownloadThenShare = async (uri) => {
const downloadInstance = FileSystem.createDownloadResumable(
uri,
FileSystem.documentDirectory + "file.pdf"
);
const result = await FileSystem.downloadInstance.downloadAsync();
if (result.status === 200) {
Sharing.shareAsync(result.uri, { dialogTitle: "Salvar ou Compartilhar" });
} else {
console.log("Failed to Download");
}
};
I finally managed to make it work using axios e FileReader();
const response = await axios.post(`${baseUrl}/v1/paycheck/pdf`, data, {responseType: 'blob'});
const fr = new FileReader();
fr.onload = async () => {
const fileUri = `${FileSystem.documentDirectory}/document.pdf`;
const result = await FileSystem.writeAsStringAsync(fileUri, fr.result.split(',')[1], {encoding: FileSystem.EncodingType.Base64});
saveFile(fileUri);
};
fr.readAsDataURL(response.data);

How to upload image as binary in react native

this is from post man
in react native how can i convert image and upload it to server as binary
this is my code i try to use form data insted of header but still not working
the upload work but the image not showing
ImagePicker.showImagePicker(options, async (response) => {
if (response.didCancel) {
setIsLoading(false);
} else if (response.error) {
setIsLoading(false);
} else if (response.customButton) {
} else {
setIsLoading(true);
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type: mime});
}
var file = dataURLtoFile(
'data:image/png;base64,' + response.data,
'hello2.png',
);
var myHeaders = new Headers();
myHeaders.append('type', '1');
myHeaders.append('uploadPath', 'xxx');
myHeaders.append('Content-Type', 'image/png');
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: file,
processData: false,
contentType: false,
};
fetch(
'xxx',
requestOptions,
)
.then((response) => response.json())
.then((result) => {
after i upload the image this is how it show
I don't know why you convert your file to data:String, and try to upload as image/png content-type. Do you want data:string or as the file itself? if you want to use data:String then your content type should be plain/text.
This is what I normally do to upload image.
const uploadImage = async (response) => {
const put = await fetch(url, { method: 'post', body: response, headers: { "Content-type": response.type } });
}
Where response is the response returned by ImagePicker.showImagePicker
Depending on your server, you may require form data, which then you need to do the formData way.
const uploadImage = async (response) => {
let formData = new FormData();
formData.append('file', response);
//in most case you do not need to create custom header object.
const put = await fetch(url, { method: 'post', body: formData });
}
blob method.
const uploadImage = async (response) => {
var blob = new Blob(response);
//in most case you do not need to create custom header object.
const put = await fetch(url, { method: 'post', body: blob, header: { 'Content-type": response.type });
}
Above example is base on a single file selected, if you select multiple file then response will of course be an array instead.

Send images to backend using ReactJS

I want to make a post request to backend with all form data.
Uploading the images i get an array with data:
const normFile = e => {
const getFileList = e.fileList.map( i => i.originFileObj);
console.log('Upload event:', getFileList);
fetch('https:///uploadapi', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ images: getFileList })
})
.then(async response => {
const data = await response.json();
console.log(data, 'res data')
})
.catch(error => {
console.error('There was an error!', error);
});
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
};
Above is my code where i use Ant Design uploader.
But how to delete the File text before each object?
You have to use multipart/form-data header
Let's say you have an input
<input type="file" onChange={uploadFile}/>
And logical part:
uploadFile = (e) => {
const formData = new FormData();
formData.append('name_your_file', e.target.files[0])
fetch('https:///uploadapi', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
body: formData
})
}

Sending Multipart file and #RequestBody in single request

In the React web app I'm developing,there is a file upload part with some user data.However, when I'm trying to upload files, server throws the following error.
org.apache.tomcat.util.http.fileupload.FileUploadException: the
request was rejected because no multipart boundary was found
React side
function fileChangedHandler(event) {
let formData = new FormData();
formData.append("file", event.target.files[0]);
formData.append("name", event.target.files[0].name);
SENDER.post(
"/api/task_resources",{
addedBy: parseInt(localStorage.getItem('id')),
taskId: parseInt(props.taskId)
},{
params: {
file: formData
}
}
)
.then(res => {
if (res.status === 200) {
alert("upload suc");
window.location.reload()
}
})
.catch(err => alert("err"));
}
My Spring Boot controller is as follows.
#PostMapping("/task_resources")
public void addResourceToTask(#RequestParam("file") MultipartFile file,#RequestBody AddTaskResourceRequest addResReq) {
String fileName = fileService.storeFile(file);
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/api/downloadFile/")
.path(fileName)
.toUriString();
UploadFileResponse response = new UploadFileResponse(fileName, fileDownloadUri,
file.getContentType(), file.getSize());
taskResourceService.addResource(addResReq, fileDownloadUri);
}
You need to send the request using multipart/form-data if your server is especting that. Here is my example implemented using Axios.
const postGalleryImageRequest = async (sessionToken, userLogged, image) => {
const data = new FormData();
data.append('newImage', image);
const result = await api.post('business/' + userLogged.businessId + '/gallery', data, {
headers: {
Authorization: sessionToken,
'Content-Type': 'multipart/form-data',
}
}) .then((response) => {
return response.data
})
.catch(error => {
....
})
return result;
}

Resources