I am trying to capture, and upload an image to a server from react native, however I get the following error when I make the http request:
[TypeError: Network request failed]
Here is my code, I have followed this tutorial:
import React from 'react';
import {View, Image, Button} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
state = {
photo: null,
};
createFormData = (photo) => {
const data = new FormData();
data.append('photo', {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === 'android'
? photo.uri
: photo.uri.replace('file://', ''),
});
data.append('id', 1);
return data;
};
handleChoosePhoto = () => {
const options = {
noData: true,
};
ImagePicker.launchImageLibrary(options, (response) => {
if (response.uri) {
this.setState({photo: response});
}
});
};
handleUploadPhoto = () => {
fetch('http://192.168.1.104:3000/', {
method: 'POST',
body: this.createFormData(this.state.photo),
})
.then((response) => response.text())
.then((response) => {
console.log('upload success', response);
})
.catch((error) => {
console.log('upload error', error);
});
};
render() {
const {photo} = this.state;
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
{photo && (
<React.Fragment>
<Image
source={{uri: photo.uri}}
style={{width: 300, height: 300}}
/>
<Button title="Upload" onPress={this.handleUploadPhoto} />
</React.Fragment>
)}
<Button title="Choose Photo" onPress={this.handleChoosePhoto} />
</View>
);
}
}
I've tried:
- Add "Content: multipart/form-data" to http request headers
- Add Accept: Accept: application/json" to http request headers
I have noticed that the request fails, only when I add the photo object to the "FormData", that is, the http request runs correctly when I remove the following code:
data.append('photo', {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === 'android'
? photo.uri
: photo.uri.replace('file://', ''),
});
Edit 02-07-2020
I finally found the solution here:
I am trying to capture, and upload an image to a server from react native, however I get the following error when I make the http request:
[TypeError: Network request failed]
Here is my code, I have followed this tutorial:
https://heartbeat.fritz.ai/how-to-upload-images-in-a-react-native-app-4cca03ded855
import React from 'react';
import {View, Image, Button} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
state = {
photo: null,
};
createFormData = (photo) => {
const data = new FormData();
data.append('photo', {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === 'android'
? photo.uri
: photo.uri.replace('file://', ''),
});
data.append('id', 1);
return data;
};
handleChoosePhoto = () => {
const options = {
noData: true,
};
ImagePicker.launchImageLibrary(options, (response) => {
if (response.uri) {
this.setState({photo: response});
}
});
};
handleUploadPhoto = () => {
fetch('http://192.168.1.104:3000/', {
method: 'POST',
body: this.createFormData(this.state.photo),
})
.then((response) => response.text())
.then((response) => {
console.log('upload success', response);
})
.catch((error) => {
console.log('upload error', error);
});
};
render() {
const {photo} = this.state;
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
{photo && (
<React.Fragment>
<Image
source={{uri: photo.uri}}
style={{width: 300, height: 300}}
/>
<Button title="Upload" onPress={this.handleUploadPhoto} />
</React.Fragment>
)}
<Button title="Choose Photo" onPress={this.handleChoosePhoto} />
</View>
);
}
}
I've tried:
- Add "Content: multipart/form-data" to http request headers
- Add Accept: Accept: application/json" to http request headers
I have noticed that the request fails, only when I add the photo object to the "FormData", that is, the http request runs correctly when I remove the following code:
data.append('photo', {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === 'android'
? photo.uri
: photo.uri.replace('file://', ''),
});
Edit 02-07-2020
I finally found the solution here:
https://github.com/facebook/react-native/issues/28551#issuecomment-610652110
Share Improve this question edited Jul 2, 2020 at 16:08 Juan Diego Cardona Marin asked Jun 18, 2020 at 13:22 Juan Diego Cardona MarinJuan Diego Cardona Marin 1611 gold badge1 silver badge5 bronze badges 3- I'm usign the follow packages "react": "16.11.0", "react-native": "0.62.2", "react-native-image-picker": "^2.3.1" The phone I'm developing is a Xiaomi Redmi Note 5 – Juan Diego Cardona Marin Commented Jun 18, 2020 at 13:56
- Have you tried adding 'file://' + photo.path as androird's uri? – Chathurika Senani Commented Nov 21, 2020 at 6:54
- people arriving here due to the "network request failed" error might be interested in reading this – otaku Commented Nov 3, 2021 at 18:21
6 Answers
Reset to default 6The first issue is with the imageUri itself. If let’s say photo path is /user/.../path/to/file.jpg. Then file picker in android would give imageUri value as file:/user/.../path/to/file.jpg whereas file picker in iOS would give imageUri value as file:///user/.../path/to/file.jpg.
The solution for the first issue is to use file:// instead of file: in the formData in android.
The second issue is that we are not using proper mime-type. It is working fine on iOS but not on Android. What makes this worse is that the file-picker package gives the type of the file as “image” and it does not give proper mime-type.
The solution is to use proper mime-type in the formData in the field type. Ex: mime-type for .jpg file would be image/jpeg and for .png file would be image/png. We do not have to do this manually. Instead, you can use a very famous npm package called mime.
import mime from "mime";
const newImageUri = "file:///" + imageUri.split("file:/").join("");
const formData = new FormData();
formData.append('image', {
uri : newImageUri,
type: mime.getType(newImageUri),
name: newImageUri.split("/").pop()
});
This solution also works:
I had same this issue in my project with react-native version 0.62. I updated flipper to "0.41.0" and it worked.
In gradle.properities
FLIPPER_VERSION=0.41.0
gradle.properties
is located at PROJECT_ROOT/android
const URL = "ANY_SERVER/upload/image"
const xhr = new XMLHttpRequest();
xhr.open('POST', url); // the address really doesnt matter the error occures before the network request is even made.
const data = new FormData();
data.append('image', { uri: image.path, name: 'image.jpg', type: 'image/jpeg' });
xhr.send(data);
xhr.onreadystatechange = e => {
if (xhr.readyState !== 4) {
return;
}
if (xhr.status === 200) {
console.log('success', xhr.responseText);
} else {
console.log('error', xhr.responseText);
}
};
had a similar issue a few days ago. The problem for me was that photo.type return an incorrect type. So i just add it manually.
fd.append('documentImages', {
name: getImgId(img.uri) + '.jpg',
type: 'image/jpeg',
uri: Constants.platform.android
? img.uri
: img.uri.replace('file://', ''),
})
const launchCamera = () => {
let options = {
storageOptions: {
skipBackup: true,
path: "images",
},
};
ImagePicker.launchCamera(options, (response) => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("ImagePicker Error: ", response.error);
} else if (response.customButton) {
console.log("User tapped custom button: ", response.customButton);
alert(response.customButton);
} else {
const source = { uri: response.uri };
console.log(
"response in image pleae chec nd xcjn",
JSON.stringify(response)
);
this.setState({
filePath: response,
fileData: response.data,
fileUri: response.uri,
});
}
imageUpload(response);
});
};
const imageUpload = (imageUri) => {
console.log('imageuril',imageUri);
const newImageUri = "file:///" + imageUri.assets[0].uri.split("file:/").join("");
const imageData = new FormData()
imageData.append("file", {
uri: newImageUri,
type: mime.getType(newImageUri),
name: newImageUri.split("/").pop()
})
console.log("form data", imageData)
axios({
method: 'post',
url: 'https://example.com/admin/api/v1/upload_reminder/1',
data: imageData
})
.then(function (response) {
console.log("image upload successfully", response.data)
}).then((error) => {
console.log("error riased", error)
})
}
Use this code 100% working
After struggling for almost 2 days i got the solutions. Some Mobile devices doesn't add file:// before the image uri which is causing the issue. So you have to hardcode that before the image uri.
formData1.append('photo', {
uri: "file://"+formData.photo,
name: `photo.${fileType}`,
type: `image/${fileType}`,
});