Upload Image to server with React-Native - react-native

My name is Leo. I'm trying to upload avatar to server. I find that everyone always use Formdata to upload. But in my case i need 2 key in form-data (avt, email), so how can i deal with that. Thank you very much!
Here are my testing in Postman

For your use-case, you can build the formData like:
let data = new FormData();
data.append('avt', {
name: '<file_name>',
type: '<file_type>', // e.g. 'image/png'
uri: '<file_uri>',
});
data.append('email', 'test#email.com');
If you are using fetch to make the API request, then your request can be like:
fetch('<api_url>', {
method: '<api request method>',
body: data,
headers: {
'Content-Type': 'multipart/form-data',
// ...other headers
}
})
.then((response) => response.json())
.then((response) => {
console.log('upload file response: ', response)
})
.catch(() => {
console.log('upload file error: ', error);
});
If you are using axios to make the API request, then your request can be like:
axios({
url: '<api_url>',
method: '<api request method>',
data: data,
})
.then((response) => {
console.log('upload file response: ', response)
})
.catch(() => {
console.log('upload file error: ', error);
});

Related

Axios formData with image is sending empty array

I have a put method to my profile route in the backend, I need a token authentication so in order to be authorized I have to pass the token through a header, I get an error because for some reason it's sending an empty formData when I log the request in my backend.
I tested the backend with postman and everything works as intended so it's not a backend issue, it's totally something wrong in the request I'm doing from the frontend, but I don't know how to handle this, any clue?
profile_update() {
let params = {
email: this.profile.email,
password: this.profile.password,
coin: this.profile.coin,
phone_country: this.profile.phone_country,
phone_area: this.profile.area_code,
phone_number: this.profile.number,
first_name: this.profile.first_name,
last_name: this.profile.last_name,
date_of_birth: this.profile.date_of_birth,
gender: this.profile.gender,
city_id: this.profile.city,
wants_to_change_password: this.profile.wants_to_change_password,
state_id: this.profile.state,
city_id: this.profile.city
}
let headers = {
'Authorization': 'Bearer' + this.token
}
let formData = new FormData();
formData.append('profile-picture', this.profile.profile_picture)
formData.append('data', params)
formData.append('headers', headers)
formData.append('_method', 'PUT')
axios.put(`http://127.0.0.1:8000/api/profile`, formData, headers).then(res => {
console.log(res)
}).catch(e => {
console.log(e)
})
}
Try this way
axios.put(`http://127.0.0.1:8000/api/profile`, {'profile-picture':this.profile.profile_picture}, {
headers: {
Authorization: 'Bearer ' + this.token,
'content-type': 'multipart/form-data'
}
}).then(res => {
console.log(res)
}).catch(e => {
console.log(e)
})
Hope this may solve your problem. For more info read docs

How can I upload a file in react-native using rn-fetch-blob?

I am new to react-native. I wanted to upload a file with another parameter 'comment' using rn-fetch-blob. I am able to pick a file and got path, name, type and size of file using react-native-document-picker package. The log for the details of file is:
console.log(res.uri, res.type, res.name, res.size);
Output:
'content://com.android.providers.downloads.documents/document/1445', 'text/html', 'hello.webp', 21476
I simply used fetch function with method 'POST' , not sure on this.
var file = {
name: this.type,
filename : this.name,
data: RNFetchBlob.wrap(this.uri)
};
Log of var file:
{ name: 'text/html',
│ filename: 'hello.webp',
└ data: 'RNFetchBlob-content://content://com.android.providers.downloads.documents/document/1445' }
method:
fetch('https://beta.hellonepal.io/api/v1/comments',
{
method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type' : 'multipart/form-data',
'Authorization': 'Bearer '+ global.apiToken,
},
body: JSON.stringify(
{
comment: this.state.newComment,
comment_file : file
})
})
.then(response => {
return response.json()
})
.then(RetrivedData => {
console.log(RetrivedData);
})
.catch(err => {
// Do something for an error here
console.log('Error in adding a comment');
});
});
I tried using RNFetchBlob method but no idea how can I pass others parameters:
const url = "https://beta.hellonepal.io/api/v1/comments";
RNFetchBlob
.config({
trusty : true
})
.fetch(
'POST',
url, {
'Content-Type' : 'multipart/form-data',
}, file)
.then((res) => {
console.log(res);
callback(res);
})
.catch((errorMessage, statusCode) => {
console.log("Error: "+ errorMessage + " - " + statusCode);
})
Per documentation https://github.com/joltup/rn-fetch-blob#regular-request the Content-Type is automatically picked based on what you're trying to POST.
Here's an example on how to upload a file https://github.com/joltup/rn-fetch-blob#upload-a-file-from-storage
You can change the upload as follows:
Content-Type should be json because your body type is json
let formdata = new FormData();
formdata.append("comment", this.state.newComment);
formdata.append("comment_file", file);
RNFetchBlob.fetch('POST', 'https://beta.hellonepal.io/api/v1/comments', {
Authorization : 'Bearer '+ global.apiToken,
body: formdata,
'Content-Type' : "multipart/form-data",
})
.then((response) => response.json())
.then((RetrivedData) => {
console.log(RetrivedData);
})
.catch((err) => {
console.log('Error in adding a comment');
})

React Native - Axios POST with urlencoded params

I successfully triggered POST request via Postman to retrieve mobileSession key. But when I tried the same from React Native app (via Axios), I get error that some params are missing. Can someone tell me what is wrong in Axios according to Postman request which is working?
Postman:
And Axios code:
export function getMobileSession() {
let requestOptions = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
let body = {
username: 'myusername',
password: 'mypw',
api_key: 'apikey',
api_sig: 'signature',
method: 'auth.getMobileSession',
format: 'json'
};
return axios.post('Lastfm_API_URL', JSON.stringify(body), requestOptions)
.then(response => {
return response;
})
.catch(err => {
throw err;
});
}
Try this,
return axios.post(`https://ws/audioscrobbler.com/2.0/`, JSON.stringify(body), requestOptions)
.then(response => {
return response;
})
.catch(err => {
throw err;
});
For more refer here to know about back tick.

Fetch is not working

I am waiting for successful JSON from server:
{"...."}
Actual Behavior
I get
SyntaxError: Unexpected token b in JSON at position 0
b is the first letter of word "badlogin". It responds server when sent wrong combination of userName and password. But when I use Postman with the same key values combination on the same address I get correct rosponse from the server.
Steps to Reproduce
fetch('http://....', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
userName: "react",
password: "123",
})
}).then((response) => response.json())
.then((responseJson) => {
console.log(responseJson.message);
if(responseJson.success === true) {
alert('successufuly loged');
}
else{
console.log(responseJson.message);
alert(responseJson.message);
}
})
}
}
You are trying to parse a string. This is the error. Instead of always parse the json, just add a clausule to check if the request was made with success
}).then((response) => {
if(!response.ok) {
// handle your error here and return to avoid to parse the string
return
}
return response.json()
})
.then()
Look like the response you got is not json
Try to check what is the response you are getting first:
.then((response) => response.text())
.then((responseJson) => {
console.log(responseJson);
}
I solved this issue by using FormData to prepare data for sending:
......
login = () => {
var formData = new FormData();
formData.append('username', 'react');
formData.append('password', '123');
fetch('http://......', {
method: 'POST',
body: formData
........

Fetch with devise_token_auth in react-native

I'm new with react-native. I'm trying to satisfy the devise_token_auth requirement of send in every request the authetication headers. To do so, I'm trying something like this:
export const scheduleFetch = (auth) => {
return (dispatch) => {
fetch(URL, {
method: 'GET',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'access-token': auth['acessToken'],
'token-type': auth['tokenType'],
'client': auth['client'],
'uid': auth['uid']
}
})
.then((response) => {
console.log(response)
response.json()
})
.catch((error) => console.log(error))
}
}
My back-end is receiving the request, all headers are fill. However, I still receiving the message "_bodyText":"{\"errors\":[\"You need to sign in or sign up before continuing.\"]}".
How can I make that work? Am I jumping any step?