How to upload image in react-native using axios? - react-native

I am trying to upload Image with Axios but getting: Request failed with status code 500.I don't have backend problem because I can upload image with postman and everything is fine.
This is my addDocument() in FileUpload.js.
addDocument(){
let { title, description, imgUri } = this.state;
console.log(this.state.imgUri);
const body = new FormData();
body.append('image', {
uri: imgUri,
type: 'image',
name : `${new Date().getTime()}.jpg`,
});
addDocument(title, description, body).then((response) => {
if (response.isSuccess == true) {
this.setState({ loading: false });
this.props.navigation.navigate('FileList',{isUpdate:'true'});
}
});
};
This is my addDocument() in document.service.js.
export const addDocument = async (title, description, imageFile) => {
const trekkerId = await AsyncStorage.getItem("trekker_id");
const model = {
profileDocumentId: '',
title: title,
description: description
}
console.log(model);
console.log(imageFile);
if (trekkerId) {
return axios({
method: 'post',
url: baseUrl + "/api/Document/Document",
data: {
file: imageFile,
model: model
},
headers: {
'profileId': trekkerId,
'Authorization': 'Bearer ' + await AsyncStorage.getItem("id_token"),
'Content-Type': 'multipart/form-data'
},
}).then((response) => {
// console.log(response);
return {
isSuccess: true
};
}).catch((error) => {
console.log(error);
return {
isSuccess: false,
}
});

Related

How to upload a file in react-native iOS?

While trying to upload a file I ran into an issue on iOS, the code works fine on android. After a bit of googling, I found that it is a known issue in react-native iOS and has a bug report submitted. This is the issue. I want to know if there is any other way to upload files on iOS. Below is the snippet of code I'm using. Please let me know if there is something that can be done.
const resp = await fetch(uploadUrl, {
method: 'POST',
headers: {
'content-type': 'multipart/form-data',
},
body: file, // file is File type
});
You can something like below code snippet
function uploadProfileImage(image, token) {
const url = ServiceUrls.UPLOAD_PROFILE_IMAGE
return uploadResourceWithPost({
url,
authToken: token,
formData: createFormData(image),
})
}
const createFormData = (data) => {
const form = new FormData()
form.append('file', {
uri: Platform.OS === 'android' ? data.uri : data.uri.replace('file://', ''),
type: 'image/jpeg',
name: 'image.jpg',
})
return form
}
const uploadResourceWithPost = ({ url, authToken, formData }) => {
return handleResponse(axios.post(url, formData, defaultUploadOptions(authToken)))
}
const defaultUploadOptions = (authToken) => ({
timeout,
headers: {
'X-Auth-Token': authToken,
'Content-Type': 'multipart/form-data',
},
})
const handleResponse = (responsePromise) => {
return NetInfo.fetch().then((state) => {
if (state.isConnected) {
return responsePromise
.then((response) => {
return ResponseService.parseSuccess(response)
})
.catch((error) => {
return ResponseService.parseError(error)
})
}
return {
ok: false,
message: 'Check your network connection and try again.',
status: 408,
}
})
}
const parseSuccess = ({ data, headers }) => ({ ...data, headers, ok: true })
const parseError = ({ response }) => {
let message = 'Check your network connection and try again.'
let status = 408
if (response && response.data) {
const { data } = response
message = data.message
status = data.code
}
return { status, message }
}

React native camera image upload

I have some problems with image upload in react native :) please help!!!
Here Is my example:
async function uploadFirstPicture(uri) {
const photo = {
name: 'first-selfie',
type: 'image/jpeg/jpg',
uri: Platform.OS === 'android' ? uri : uri.replace('file://', ''),
};
const formData = new FormData();
formData.append('file', photo);
const response = await axios({
method: 'POST',
url: `${API_ROOT}/Session/Upload`,
data: {
SessionId: sessionId,
File: formData,
DataType: 3,
},
headers: {'Content-Type': 'multipart/form-data;'},
});
(await response.data.success) && updateState({uploadFirstPicture: true});
}
Request Headers:
accept application/json, text/plain, */* content-type
multipart/form-data;
Request body:
{
"SessionId":"0198a8c6-e250-485d-82c3-8ce9190a4d20",
"File":{
"_parts":[
[
"file",
{
"name":"first-selfie",
"type":"image/jpeg/jpg",
"uri":"/var/mobile/Containers/Data/Application/BBAFA325-BE23-45C5-B81F-255BBC4856B8/Library/Caches/Camera/D6D7839A-E1B1-425E-8488-BC8FDA0DE092.jpg"
}
]
]
},
"DataType":3
}
Request Error 400
Failed to read the request form. Missing content-type boundary.
request Url:
https://bio.dev.cdigital.am/api/Session/Upload
Swager:
https://bio.dev.cdigital.am/swagger/index.html
For select image, you can use following.
ImagePicker.launchImageLibrary(options, response => {
console.log("My repoinse data --- > ", response)
if (response.didCancel) {
} else if (response.error) {
} else if (response.customButton) {
} else {
let searchString = response.fileName
? response.fileName.toString().toLowerCase()
: '';
if (!searchString) {
return;
}
this.setState(
{
profileImage: response.uri,
cropperVisible: true,
AmazingCropper: true,
imageType: response.type,
imageFileName: response.fileName,
imgLat: response.latitude,
imgLong: response.longitude
},
() => {
this.uploadOriginalImage(Platform.OS);
},
);
}
});
Upload image to the server:-
uploadOriginalImage = type => {
this.setState({ loading: true, responseMessage: "" });
let passData = new FormData();
passData.append('original_image', {
uri:
type === 'android'
? this.state.profileImage
: this.state.profileImage.replace('file://', ''),
type: this.state.imageType,
name: this.state.imageFileName,
});
Dating.uploadimage(passData, true)
.then(res => {
this.setState({ loading: false, });
if (res.Status === 200) {
} else if (res.Status === 401) {
} else {
}
})
.catch(err => {
this.setState({ loading: false });
});
};

How to use axios to upload image from imagePicker

I trying to upload a file image to API in postman thats work fine but when a i try file image from ImagePicker didnot work.
I think doing something wrong when create formdata
Handler
ImagePicker.showImagePicker(optionsImagePicker, (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);
} else {
// const source = { image: response.data };
let photo = { uri: response.uri}
let formdata = new FormData();
formdata.append("product[name]", 'test')
formdata.append("product[price]", 10)
formdata.append("product[category_ids][]", 2)
formdata.append("product[description]", '12dsadadsa')
formdata.append("product[images_attributes[0][file]]", {uri: photo.uri, name: 'image.jpg', type: 'image/jpeg'})
updateProfilePic(formdata)
// You can also display the image using data:
// const source = { uri: 'data:image/jpeg;base64,' + response.data };
// this.setState({
// avatarSource: source,
// });
}
});
Service
export function uploadImageProfile(data: any): Promise<any> {
const config = {
headers: {
'Content-Type': 'multipart/form-data',
},
};
return api.post('/users/profilepic', {image: data}, config).then((res) => {
console.log(res.data);
return res.data;
});
}
Your form data must be like that.
formdata.append('file',{
uri: Platform.OS === 'android' ? photo.uri : 'file://' + photo.uri,
name: 'test',
type: 'image/jpeg' // or your mime type what you want
});
Then
axios.post('/users/profilepic', formdata, config).then((res) => {
console.log(res.data);
return res.data;
});
let formdata = new FormData();
formdata.append('file',{
uri: Platform.OS === 'android' ? photo.uri : 'file://' + photo.uri,
name: 'test',
type: 'image/jpeg'
});
use method:"POST" and spread formdata.getHeaders() into header
let reqObj = {
method: "POST",
url: 'http://example.com/upload/image',
headers: {
'x-sh-auth': token,
...formdata.getHeaders()
},
maxContentLength: Infinity,
maxBodyLength: Infinity
};
axios(reqObj).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
});
I changed how I send image to the server. Now send im base64 and in server convert to file with fs.
const uploadImage = {
imageBase64: 'data:' + response.type + ';base64,' + response.data,
};
updateProfilePic(uploadImage);
server side
async saveImageProfile(imageBase64, logedUserData) {
let base64Image = imageBase64.imageBase64.split(';base64,').pop();
let type = imageBase64.imageBase64.split('image/').pop().split(';')[0];
let newFileName = `${logedUserData.id}.${type}`;
if (imageFileFilter(type)) {
const file = await fs.writeFile('./files/' + newFileName, base64Image, { encoding: 'base64' }, function (err) {
console.log('File created');
});
const url = `${baseUrl}/users/files/${newFileName}`;
this.updateRefProfilePic(url, logedUserData);
}
else {
throw new BadRequestException("Tipo de arquivo não suportado");
}
}

How to upload image to server in React Native

I'm trying to upload image by using React Native axios. But I get this response. I tried every solutions but it didn't work. I'm using react-native-image-picker to get image
{ result: null,
message: 'Wrong access',
error: true,
type: 'command_not_found' }
Here is my code
ImagePicker.showImagePicker(options, (response) => {
let formData = new FormData();
formData.append('image', { uri: response.uri, name: response.fileName, type:response.type });
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
axios({
url: "URL",
method: 'POST',
data: formData,
config
})
.then(result => console.log(result))
.catch(error => console.log(error))
}
Try with raw fetch api.
const 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://", "")
});
return data;
};
and then try to upload it again
fetch("http://localhost:3000/api/upload", {
method: "POST",
body: createFormData(photo)
});

React Native: setState doesn't work when calling try-catch function

I tried to call APP with this code imported from another file and it worked fine:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
let formData = new FormData();
formData.append('userId', '1'); // < this is what I want to change
formData.append('key', '***'); //my key
export function getScoreFromAPI () {
return fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
}
but now I want to change my userId from 1 to an constante from Asyncstorage, so I decide to change my code to this:
constructor(props) {
super(props)
this.state = { infos: [], userId: '' }
}
componentWillMount() {
this.getScoreFromAPI().then(data => {
this.setState({ infos: data })
});
console.log(this.state.infos);
AsyncStorage.getItem(USERID_STORED)
.then((data) => {
if (data) {
this.setState({userId:data})
}
});
}
async getScoreFromAPI() {
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
try {
let response = await fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
let res = await response.json();
} catch(error) {
console.warn("errors are " + error);
}
};
with a try-catch function but when I call getScoreFromAPI() in ComponentWillMount() I can't setState with received data, I still have an empty array in info:[]
my questions:
how can I replace '1' in userId by a value in asyncstorage in the first file ?
if it isn't possible, what I have do to setState info: [] with my data reveived
I've simplified your code into a promise chain in which calling getScoreFromAPI will execute after getting the userId from AsyncStorage, then storing the response into the infos state, while returning null if there was an error, and logging the error to the console. The data was not previously returned from getScoreFromAPI, so the value would always become null. I have not tested this code, but this should give you a good base to work from:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
export default class Test {
constructor() {
this.state = {
infos: null,
userId: ''
};
}
componentDidMount() {
AsyncStorage.getItem(this.state.userId)
.then(userID => {
this.setState({ userId: userID || '' });
})
.then(() => {
return this.getScoreFromAPI();
})
.then(data => {
this.setState({ infos: data });
})
.catch(console.error);
}
getScoreFromAPI = () => {
const formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(response => {
// use response data here
return response.json();
})
.catch(e => {
console.error(e);
return null;
});
};
}
You're doing your API call before fetching your value from AsyncStorage (I know this is async but it's not very readable if you do it that way).
getScoreFromAPI doesn't return anything, that's why your setState isn't working.
You don't need to use try and catch here, promises have their own error handling mechanism (the .catch() method).
I think callbacks are more readable and lead to less bugs than using .then() in code.
This is how I would do it:
constructor(props)
{
super(props);
this.state = { infos: [], userId: '' };
this.onSuccess = this.onSuccess.bind(this);
this.onFailure = this.onFailure.bind(this);
}
componentWillMount()
{
// Get userID from local storage, then call your API
AsyncStorage.getItem(YOUR_KEY)
.then(userID=> {
if (userID)
{
this.setState({ userId : userID }, () => {
this.getScoreFromAPI(this.onSuccess, this.onFailure);
});
}
});
}
onSuccess(data)
{
this.setState({
infos : data
});
}
onFailure(err)
{
console.warn('Error ' + err);
}
getScoreFromAPI(onSuccess, onFailure)
{
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //your key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(res => res.json())
.then(json => {
onSuccess(json);
})
.catch(err => {
onFailure(err);
});
}
It's finally done. I tried this and it worked. Thank you to all of you
this is what I have done:
...
const USERID_STORED = "userid_stored";
const GSM_STORED = "gsm_stored";
...
class ScoreList extends React.Component {
constructor(props) {
super(props)
this.state = { infos: [], userId: '', gsmStored: '', }
}
componentWillMount() {
AsyncStorage.getItem(USERID_STORED)
.then(userId => {
this.setState({ userId: userId});
this.getScoreFromAPI(this.state.userId).then(data => {
this.setState({ infos: data });
});
});
AsyncStorage.getItem(GSM_STORED)
.then(gsmStore => {
this.setState({ gsmStored: gsmStore});
});
}
getScoreFromAPI (userId) {
let formData = new FormData();
formData.append('userId', userId);
formData.append('key', '***');
return fetch('https://***',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
};