Get all contacts from phonebook and upload to server but got following error.
While append image in request body FormData
Tried code
pass file url contact thumbnailPath
const path = con.thumbnailPath
body.append('image', {
uri: path,
type: 'image/jpeg',
name: 'photo.jpg',
type: 'multipart/form-data'
})
Tried code
pass file url contact thumbnailPath without "file://"
const path = con.thumbnailPath.replace('file://', '')
body.append('image', {
uri: path,
type: 'image/jpeg',
name: 'photo.jpg',
type: 'multipart/form-data'
})
Tried code
check file exist on path or not with using react-native-fs
if (con.thumbnailPath != '') {
let isExist = RNFS.exists(con.thumbnailPath)
if (isExist) {
const path = con.thumbnailPath.replace('file://', '')
console.log("Exist", path)
body.append('image', {
uri: path,
type: 'image/jpeg',
name: 'photo.jpg',
type: 'multipart/form-data'
})
}
}
Request
fetch(url, {
method: 'POST',
headers: {
'Authorization': token,
'token': token
},
body: params
})
.then((res) => res.json())
.then((json) => {
console.log("RESPONSE:- ", json)
if (json.response[0].status == 'false') {
let msg = json.response[0].response_msg
callback(new Error(msg), json.response[0])
}
else {
callback(null, json.response[0])
}
})
.catch((err) => {
console.log(err)
callback(err, null)
})
The issues comes from react-native#0.63.2's internal bug.
A quick solution is to revert this commit: https://github.com/facebook/react-native/commit/31980094107ed37f8de70972dbcc319cc9a26339#diff-9a034658197479288c4d346a0eb4d98c
After manually revert this commit in node_modules, recompile the app and the image uploading will be working without any issues.
Replace the function loadImageForURL in /Libraries/Image/RCTLocalAssetImageLoader.mm with the following:
- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
__block auto cancelled = std::make_shared<std::atomic<bool>>(false);
RCTExecuteOnMainQueue(^{
if (cancelled->load()) {
return;
}
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
completionHandler(nil, image);
} else {
NSString *message = [NSString stringWithFormat:#"Could not find image %#", imageURL];
RCTLogWarn(#"%#", message);
completionHandler(RCTErrorWithMessage(message), nil);
}
});
return ^{
cancelled->store(true);
};
}
This problem is fixed in 0.63.3 ✅
**For IOS** in
node_modules/react-native/Libraries/Image/RCTLocalAssetImageLoader.mm file
**Replace Below**
- -(RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
completionHandler(nil, image);
} else {
NSString *message = [NSString stringWithFormat:#"Could not find image %#", imageURL];
RCTLogWarn(#"%#", message);
completionHandler(RCTErrorWithMessage(message), nil);
}
return nil;
}
**With**
- -(RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
__block auto cancelled = std::make_shared<std::atomic<bool>>(false);
RCTExecuteOnMainQueue(^{
if (cancelled->load()) {
return;
}
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
completionHandler(nil, image);
} else {
NSString *message = [NSString stringWithFormat:#"Could not find image %#", imageURL];
RCTLogWarn(#"%#", message);
completionHandler(RCTErrorWithMessage(message), nil);
}
});
return ^{
cancelled->store(true);
};
}
This..
Like and Love , if it work
I have the same issue which perfectly reproducible on one of the iPhone 7 on my react-native project. It's strange but another iPhone 7's works perfectly as well as all Android devices.
My code:
formdata.append("file", {uri: photo.uri, name: name_img, type: 'image/jpeg' });
axios({
url: `${API}${'/upload'}`,
method: 'post',
headers: {
'Authorization': 'Basic ' + auth_token,
'Content-Type':'application/x-www-form-urlencoded'
},
data: formdata
}).then(response => this.saveRoute())
.catch(err => {
this.props.errorMessage({message: err})
}
})
Few things that I investigate:
I was not able to catch it in debug mode (seams smth wrong in async calls?)
I was not able to catch it with try-catch statement but seams it happened in Axios call.
So, I tried to play with Timeout and was able to make it totally unreproducible with 300ms timeout before Axios call.
formdata.append("file", {uri: photo.uri, name: name_img, type: 'image/jpeg' });
setTimeout(() =>
axios({
url: `${API}${'/upload'}`,
method: 'post',
headers: {
'Authorization': 'Basic ' + auth_token,
'Content-Type':'application/x-www-form-urlencoded'
},
data: formdata
}).then(response => this.saveRoute())
.catch(err => {
this.props.errorMessage({message: err})
}
})
, 300);
I know that it's a workaround but may help others to understand the issue for more deep research.
I temporary fixed using rn-fetch-blob, but the issue is present in 0.63.2 version and I didn't want to patch node_modules react-native images library.
To send file, you have to create a FormData and append your file into it. See EX: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Uploading_a_file
I found solution. Just put delay when you post request.
let options = {}
options.headers = headers
options.method = 'POST'
let url = {SERVER_URL}
options.body = new FormData();
for (let key in data) {
options.body.append(key, data[key]);
}
setTimeout(() => {
fetch(url, options)
.then((response) => response.json())
.then((responseJson) => {
resolve(responseJson);
})
.catch((error) => {
let errParam = {}
errParam.errMsg = error.toString()
console.log(errParam)
resolve(errParam);
})
}, 1000);
Error fixed when updating React Native to version 0.63.3
Related
i have an issue with POST request inside my app.
part of code :
if (imagesResults !== undefined) {
imagesResults.forEach((el) => {
let localUri = el.uri;
let filename = localUri.split("/").pop();
let match = /\.(\w+)$/.exec(filename);
let type = match ? `image/${match[1]}` : `image`;
formData.append("saleImages[]", {
uri: localUri,
name: filename,
type: type,
});
});
}
console.log("FORMDATA", formData);
const axiosConfig = {
headers: {
Authorization: "Bearer " + user.token,
"content-type": "application/x-www-form-urlencoded",
Accept: "application/json",
},
};
try {
axios
.post(`${API}/sales/${saleId}/edit`, formData, axiosConfig)
.then((res) => {
// console.log("RES", JSON.stringify(res.data));
bottomSheetRef.current.snapToIndex(0);
setTimeout(() => {
bottomSheetRef.current.close();
dispatch(setLoadingApiAction(false));
navigation.navigate("My Ads");
}, 3000);
})
.catch((err) => {
console.log("error", err);
// setErrors(err.response.data.errors);
navigation.navigate("My Ads");
alert("SOMETHING IS WRONG!");
dispatch(setLoadingApiAction(false));
});
} catch (error) {
console.log("ERROR CATCH", error);
dispatch(setLoadingApiAction(false));
}
};
so what is happening, i fire my API, and i get 200 but just after i get 200 it return me also a network error and goes into .catch part.
This is only happening in ANDROID DEVICE , IOS working totally fine.
I am using a HTTPS , also i tried to set type of the image hardcoded into "image/jpeg" but i got the same problem.
I am working with digital ocean spaces and I have uploaded the images on it in a temporary folder. Now I want to move that image from temporary folder to permanent folder. I have searched the things from all over but got nothing much satisfying. Is it possible to do so ?
and if yes please help me with the javascript code.
First I generated the signed url and with the help of that signed url I uploaded the image on digitalocean spaces. Following is the code for generating signed url and uploading images.
const getSignedUrl = async () => {
const body = {
fileName: 'temp/' + file.name,
fileType: file.type,
}
const response = await fetch(`${API_URL}/presigned_url`, {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' }
})
const { signedUrl } = await response.json()
return signedUrl
}
const uploadFile = async signedUrl => {
const res = await fetch(signedUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type,
'x-amz-acl': 'public-read',
}
})
return res
}
please help me how can I move my image from temporary folder to permanent folder.
So finally after searching I got the answer,
From the front end side I call an API to copy my image
const copyFile = async (file) => {
try {
const body = {
fileName: file.name
}
const res = await fetch(`${API_URL}/copy_file`, {
method: 'PUT',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' }
})
return res
} catch (error) {
console.log(error);
}
}
And in the backend side the API I made is
app.put('/copy_file', (req, res) => {
const fileName = req.body.fileName
console.log("body", fileName);
const params = {
Bucket: config.spaces.spaceName,
CopySource: `/bucketName/temp/${fileName}`,
Key: `original/${fileName}`,
}
spaces.copyObject(params, function (err, data) {
if (err) {
console.log("Error", err)
// console.log(err, err.stack); // an error occurred
} else {
res.json({ data })
}
});
});
This will copy you image in original folder
I have tried doing
var photo = {
uri: uriFromCameraRoll,
type: 'image/jpeg',
name: 'photo.jpg',
};
and using
axios
var body = new FormData();
body.append('authToken', 'secret');
body.append('photo', photo);
body.append('title', 'A beautiful photo!');
const config = {
headers: {
'content-Type': 'multipart/form-data'
}
}
MY_API().then(instance => {
// it is axios instance
instance.post("/api/v1/upload",
{ body }
, config).then(res => {
console.log(JSON.stringify(res));
}).catch(err => {
console.log(err);
})
}
)
On removing config I get
Error 503
and with config it gives
Error: Multipart: Boundary not found
and works fine with POSTMAN also... Along with headers
I have also tried to upload File (blob) , but same error of
Error: Multipart: Boundary not found
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});
}
//Usage example:
var file = dataURLtoFile('data:text/plain;base64,aGVsbG8gd29ybGQ=', 'hello.txt');
console.log(file);
API works well in ReactJS with code
EDIT : I have solved the problem by using React-native-fetch-blob, but looking to solve using axios ,
here is the code :
RNFetchBlob.fetch('POST', 'https://helloapp.herokuapp.com/api/v1/upload', {
'authorization': jwtToken,
'Content-Type': 'multipart/form-data',
},
[
{ name: 'image', filename: 'avatar-png.png', type: 'image/png', data: base64logo },
{ name: 'name', data: name }
]
).then((resp) => {
console.log(resp);
}).catch((err) => {
console.log(err);
});
I have solved the problem by using React-native-fetch-blob, but looking to solve using axios ,
here is the code :
RNFetchBlob.fetch('POST', 'https://helloapp.herokuapp.com/api/v1/upload', {
'authorization': jwtToken,
'Content-Type': 'multipart/form-data',
},
[
{ name: 'image', filename: 'avatar-png.png', type: 'image/png', data: base64logo },
{ name: 'name', data: name }
]
).then((resp) => {
console.log(resp);
}).catch((err) => {
console.log(err);
});
Never Ever define content-type header while sending a file.
Browser/Postman will add it automatically which looks like this.
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7BojnnMEteO0aHWP
Form boundary is the delimiter for the form data. Boundary is calculated when request is sent so you cannot hardcode it.
Thats why you were getting error boundary not found.
Now you can use fetch , axios anything, it will work.
This is very important info which is not captured in the MDN Fetch docs
Is there a way to upload video to a server in react native?
I've looked into the react-native-uploader plugin on github, but it doesn't give any guidance on video uploads if it's even possible with that plugin.
Just use fetch for uploading
let formData = new FormData();
formData.append("videoFile", {
name: name.mp4,
uri: video.uri,
type: 'video/mp4'
});
formData.append("id", "1234567");
try {
let response = await fetch(url, {
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData
});
return await response.json();
}
catch (error) {
console.log('error : ' + error);
return error;
}
Here is another answer, using rn-fetch-blob in RN 0.57.8.
postVideo = (video,url) => {
RNFetchBlob.fetch('POST',url, {
'content-type': 'multipart/form-data',
"Accept":"multipart/form-data",
'access-token': AuthToken.token, //token from server
},[
//the value of name depends on the key from server
{name: 'video', filename: 'vid.mp4', data: RNFetchBlob.wrap(video.uri) },
]).then(response => response.json())
.then(response => {
if (response.status === 'success') {
alert("Upload success");
this.props.navigation.navigate('publish');
} else {
alert(response.msg);
}})
.catch((err) => {
alert(err);
})
}
Yes, it is possible.
you have to be running React Native 0.45.0 or higher, which do support accessing videos from camera roll.
you have to receive reference to image/video access from camera roll by calling CameraRoll.getPhotos(params) (more on this in docs)
then, use RNUploader.upload(...) to send assets to your serve (you need to link lib before!)
I am trying to send a file to my back-end through an axios post request.
This is the error I currently have:
cherrypy._cperror.HTTPError: (415, 'Expected an entity of content
type application/json, text/javascript')
From what I have read I need to change the Content-Type in my post request, I looked around I am currently attempting to do so like this:
handleUploadButton(e){
const upload_file = this.state.file;
const formData = new FormData();
formData.append('file', upload_file);
const request = axios.post(someUrl, formData, {headers: {
"Content-Type": "application/json"}
})
.then(function (response) {
console.log('successfully uploaded', upload_file);
});
}
Not sure if relevant, but all this is happening through a reactjs form.
This is my current Content-Type: Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryBwjjjGuJEySeXdRU
I have no idea where to go from here. Any help would be greatly appreciated.
SignIn = () => {
console.log('login clicked')
let data = JSON.stringify({
password: this.state.password,
username: this.state.email
})
axios.post('url', data, {
headers: {
'Content-Type': 'application/json',
}
}
)
}
This worked for me:
const formData = new FormData();
formData.append('data', new Blob([JSON.stringify(data)], { type: 'application/json'}));
formData.append('file', file);
return axios.put(`${url}`, formData)
.then((response) => { console.log(response) })
.catch((error) => { console.log(error) })
I took this from another answer of a similar issue. You can check the original answer here.
You can fix different types catch() error by
.catch((error)=> {
if (error.response){
this.errors(error.response.message);
} else if (error.request) {
console.log('error.request');
} else {
console.log('Error', error);
}
console.log("rejected");
});
read more >>
In order to make axios include Content-Type: application-json you need to do that:
javascript
window.axios = require('axios')
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'