react native image picker send to spring boot error - reactjs

const loadLibrary = useCallback(async () => {
launchImageLibrary(
{
mediaType: 'photo',
},
response => {
if (response?.errorCode) {
console.log('LaunchImageLibrary Error: ', response.errorMessage);
} else {
console.log('response=', response.assets[0]);
const formData = new FormData();
formData.append('image', {
name: response.assets[0].fileName, // require, file name
uri: response.assets[0].uri, // require, file absoluete path
type: response.assets[0].type, // options, if none, will get mimetype from `filepath` extension
});
console.log('formData=', formData);
axios
.post('/users', formData)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
// );
}
},
);
}, [userInfo]);
spring code ---
#PostMapping(value="/api/v1/users")
public String createUser(
#RequestParam("image") MultipartFile image) {
System.out.println(image);
return "";
}
-error--
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
how to deal with?
Previously, this code worked well.

try this and let me know
const formData = new FormData();
formdata.append("image", {type: 'image/jpg', uri:response.assets[0], name:response.assets[0]});
console.log('formData=', formData);
axios
.post('/users', formData)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
// );
}
},
);

Related

Axios does not catch error even not enter in catch block

I am trying to get the error status code that would be 413 in Axios catch block. I have tried different solutions nothing worked for me. Could you please review what is going wrong.
uploadNewDatDocuments(datId, files = [], additionalInfo = {}) {
return new Promise((resolve, reject) => {
let url = new URL(this.baseUrl + this.uploadDocument.replace('{id}', datId));
Object.keys(additionalInfo).forEach(queryParam => url.searchParams.set(queryParam, additionalInfo[queryParam]));
let formData = new FormData();
files.forEach(file => formData.append('files', file));
axios
.post(url.toString(), formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
resolve(response.data);
})
.catch(error => {
console.log("error occurred")
reject(error);
}).finally(error=>{
console.log(error);
})
});
}
Here is my Action code.
export function uploadNewDocuments(datId, additionalInfo = {}, attachments = [], comment = {}) {
return dispatch => {
datService
.uploadNewDatDocuments(datId, attachments, additionalInfo)
.then(response => {
const attachmentsIds = response.map(attachment => attachment.id);
dispatch(
DatCommentActions.addDatNewComment(datId, {
...comment,
message: { ...comment.message, attachments: attachmentsIds }
})
);
})
.catch(error => {
dispatch(MessageActions.showMessage({ message: error.response.data.message }));
console.error(error);
});
};
}
413 Request Entity Too Large is not actually error, its a not successful response and catch wont fire unless there is actual error on response.
What you could do is check response.status and based on that and write own error handling.

Upload input form data and file/image Next js

I am trying to send form data life person name, email and image together using Next js. I used formdata for file upload and using react-hook-form for form input.
The problem is I couldn't receive the image/file in the Next api.
My codes are :
Onchange:
const handleImgChange = (e) => {
if (e.target.files && e.target.files[0]) {
const img = e.target.files[0];
setProfileImg(img);
}
};
to get form data from input.
const handleIChange = (e) => {
const value = e.target.value;
setContents((prevContnet) => {
return {
...prevContnet,
[e.target.name]: value,
};
});
};
On submit
const handleOnsubmlit = (e) => {
e.preventDefault();
if (profileImg.length > 0) {
const formData = { ...contents, profile_picture: profileImg };
updateUserSetting(formData);
} else {
updateUserSetting(contents);
}
};
updateUserSetting
async function updateUserSetting(formdata) {
try {
console.log("form datas", formdata);
dispatch({ type: "UPDATE_USER_SETTING_REQUEST" });
const { data } = await axios(
`${NEXT_URL}/api/updateusersetting`,
{
method: "PUT",
formdata,
"content-type": "multipart/form-data",
}
);
console.log("return data ", data[0]);
dispatch({ type: "UPDATE_USER_SETTING_SUCCESS", payload: data[0] });
} catch (error) {
dispatch({
type: "UPDATE_USER_SETTING_FAIL",
payload: error.response
});
}
}
API
import { IncomingForm } from "formidable";
export const config = {
api: {
bodyParser: false,
},
};
export default async (req, res) => {
if (req.method === "PUT") {
if (!req.headers.cookie) {
res.status(403).json({ message: "Not Authorized" });
return;
}
const { token } = cookie.parse(req.headers.cookie);
console.log("body is", req.body);
const formData = await new Promise((req, res) => {
const form = new IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
res.writeHead(200, { "content-type": "multipart/form-data" });
res.json({ fields, files });
});
});
};
how can I put data together and send it to the desired API? Thanks in advance.
You can use the FormData interface to send files and other fields as a single JSONified string, or individual strings. Formidable will separate your fields and files in the callback, and you can process them individually.
Here's a working Codesandbox.
Output:

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
});
};}

Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'uri.split')]on React Native Expo

I got a problem when upload image on react native
and here is my code
_pickImage = async () => {
await Permissions.askAsync(Permissions.CAMERA_ROLL);
const { cancelled, uri } = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 4],
base64: true
});
if (!cancelled) this.setState({ ImageKTP: uri });
this.createFormData();
};
and here is createFormData
createFormData = async (uri) => {
const {ImageKTP} = this.state;
let imageUri = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append('ImageKTP', {
imageUri,
name: `ImageKTP.${fileType}`,
type: `image/${fileType}`,
});
fetch('http://192.168.0.20/profile.php?ImageKTP=' + ImageKTP,{
method: 'POST',
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
body: formData
})
.then((response) => response.json())
.then((responseJson) =>{
alert(responseJson);
})
.catch((error)=>{
console.error(error);
});
};
Any Solution for this? I still dont get it how to get the uri
Thank you
You need to call createFromData only when you successfully have uri set
if (!cancelled) {
this.setState({ ImageKTP: uri }, () => {
this.createFormData();
});
}
createFormData = async uri => {
const { ImageKTP } = this.state;
if (!ImageKTP) return;
/** Your processing code... */
};

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