Fetch Post of formData with images works in iOS but on android returns 400 BAD REQUEST - react-native

`I am using fetch on react native to send a post request with a form data object on the body.
This code works on iOS but on android it returns a 400 BAD REQUEST and I get ERROR [SyntaxError: JSON Parse error: Unexpected EOF].
const buildFormData = () => {
const data = new FormData();
for (let i = 0; i < photoForm.photosToUpload.length; i++) {
console.log(photoForm.photosToUpload[i].uri)
data.append('photosToUpload', {
uri: photoForm.photosToUpload[i].uri,
name: photoForm.photosToUpload[i].fileName,
type: 'image/jpeg'
});
data.append("userForm", JSON.stringify(userForm));
console.log(data)
return data;
}
This is how I am building my form data.
export const createUser = (formData) => async (dispatch) => {
try {
const headers = {
'Content-Type': 'multipart/form-data'
};
const response = await fetch('https://c66d-2a02-a03f-a5a1-e400-1573-78c6-e019-e601.eu.ngrok.io' + '/create_user', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
body: formData,
})
.then(response => response.json())
.then(responseJson => {
console.log(responseJson);
})
.catch(error => {
console.error(error);
});
Handle successful response
catch (error) {
Handle error
}
This is how I am sending the form data to my django server. I know the problem is in the form data because if I dont send files the request goes through.
I have read almost every github issue on this matter, switched to axios, tried multiple solutions and no luck. Does anyone know what the problem can be?
I tried to make a post request using fetch and it works on iOS but not on android.
I was expecting to work on both OS.`

Related

Why Axios is not providing response header when app is opening second time?

Here is my API request
const getData= async () => {
const cookie='workid_token=eyJra4rgrtF7SnlSETjIGrFYQy-P2SFmlE6A.Tw_rx0Ut_Kj9zLWRQ9X23w';
const qs = require('qs')
let body = qs.stringify({
gid: '1196'
})
await axios.post(
'https://www.google.com', body,
{
headers: {
'Cookie': cookie,
'Content-Type': 'application/x-www-form-urlencoded',
},
},
).then(response => {
console.log('data', response);
if (response.data.status === '1') {
const PHPSESSID = response.headers['set-cookie'];
var separatedvalue = PHPSESSID[0];
var sessid = separatedvalue.split('; path=/')[0];
}
}).catch(error => {
console.log(error);
});
};
I am implementing Axios API post request in my React Native application. When I run the application first time I am getting set-cookie value in response headers. If I kill the application and I open it second time I am not getting value in set-cookie. Also not receiving response from the API.
Note: I want to receive value from set-cookie all the times.

Network Error when sending file in react native with axios

I am trying to send a file to a nodejs server from react native using axios, this is my code:
const createFormData = (file) => {
const data = new FormData();
data.append('message', text);
data.append('receiver',doctorid);
if(file !== ''){
data.append('file', {
type: file.type,
uri: file.uri,
name: file.name.replace(/\s/g,'')
})
}
return data;
}
const onSend = async() => {
const newMessages = [...messages]
newMessages.push({"sender": currentuserID, "id": 339, "message": 'sending...', "attachment": '', "receiver": doctorid, "type": 0},)
setMessages(newMessages)
const token = await AsyncStorage.getItem('token');
const data = createFormData(singleFile)
await appApi.post('/chats', data, {
headers: { 'Authorization': 'Bearer ' + token }
}).then(()=>{
socket.emit('sendmessage', text, (err) => {
messageInit()
});
})
.catch(err => console.log(err.message))
}
This code works perfectly if there's no image attached, but ones there's an image attached, I get the network error message immediately.
For a little bit of troubleshooting, I tried sending request to my local machine, using ngrok. From ngrok, I realized the request wasn't sent at all to the url. So it just fails immediately, without the request been made to the url.
Anyone with solution to this.
I'm testing on an android emulator
send using formdata
try this
let formData = new FormData();
let imagefile = document.querySelector('#file');
formData.append("image", imagefile.files[0]);
axios.post('upload_file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})

Is there a limit in the body of a request to an api in React native?Because i cant send large base64 to server

It says me syntax error: JSON Parse error. unrecognized token '<'
Iam using Fetch to do the request.It let me send short base64 strings i tried so what can i do?
This is my call to the api:
export function uploadPost(post) {
let data = {
body: post.body,
picture: post.picture,
type: post.type,
user: {
_id: post.user._id,
name: post.user.name,
picture: post.user.picture
}
}
var headers = {
'Content-Type': 'application/json',
'Access-Control-Origin': '*'
}
return fetch(URL + "/uploadPost", {
method: "post",
headers: headers,
body: JSON.stringify(data)
})
.then(response => Promise.resolve(response.json()))
.catch(err => {
return Promise.reject(err);
})
}
I finally solved it. The problem was that the response was returning a 413 status and I found out that means payload too large. So I added to my node js express server this lines:
var app = express();
//after
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));

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.

handle network request failed in react native

I'm facing an issue while using react native fetch api. many times request got failure . I have a high speed connection. but many times it got failed.
that issue is happening In android,ios both.
const shoppingApi = 'myserverlink';
async function Sendshoppinapi(data) {
try {
let response = await fetch(shoppingApi, {
method: 'POST',
headers: {
'Accept': 'application/json',
'content-type':'multipart/form-data'
},
body: data
});
let responseJson = await response.json();
return responseJson;
}
catch (error) {
Alert.alert(error.toString())
}
}
export {Sendshoppinapi};
data that I sending server as post request
add_to_wishlist = (item,index) => {
{
let data = new FormData();
data.append('methodName', 'add_to_wishlist');
data.append('user_id', global.userid)
data.append('item_id', this.props.navigation.state.params.itemid.toString())
Sendshoppinapi(data).then((responseJson)=>{
console.warn(responseJson);
if(responseJson.responseCode == '200'){
this.setState({fav:false})
Alert.alert('SHOPPING','Item added to wishlist successfully.',[{text: 'OK',},],{ cancelable: false })
}
else{
this.setState({fav:false})
Alert.alert('SHOPPING','Item already .',[{text: 'OK',},],{ cancelable: false })
}
})}
}
Error that when request got failed
I've quoted an answer I used for another post - however I have added await.
You can check the status of the call, to determine perhaps why the network call failed. Try using fetch's ok to check whether the response was valid, for example:
.then(function(response) {
if (!response.ok) {
//throw error
} else {
//valid response
}
})
Using await:
let response = await fetch(url)
if (response.ok) return await response.json()
You can also access the response's status like:
response.status;
or also, statusText such as:
response.statusText;
checkout the below:
https://developer.mozilla.org/en-US/docs/Web/API/Response/statusText
https://developer.mozilla.org/en-US/docs/Web/API/Response/status
https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
Use then() function with promises. (Requested code snippet)
fetch(shoppingApi, {
method: 'POST',
headers: {
'Accept': 'application/json',
'content-type':'multipart/form-data'
},
body: data
})
.then((resp) => {
return resp.json()
})
.then((resp) => {
//resp contains your json data
});
You also can make your function returns a Promise, and use it with then():
function sendShoppingApi(data) {
return new Promise((resolve, reject) => {
fetch(shoppingApi, {
method: 'POST',
headers: {
'Accept': 'application/json',
'content-type':'multipart/form-data'
},
body: data
})
.then((resp) => {
return resp.json();
})
.then((resp) => {
resolve(resp);
/*
you should also check if data is valid, if something went wrong
you can reject the promise:
if(!dataOK)
reject("error message");
*/
});
});
}
So now you can do something like this:
sendShoppingApi(data)
.then((resp) => {
//do stuff with your data
})
.catch((err) => {
//handle error
});
UPDATE
could be a duplicate of this: React Native fetch() Network Request Failed
For the case when you are running the app on the android device, the API is on a computer and both of them are on the same network I have added some possible things to check. I haven't detailed specific solutions since there are many answers on each topic.
Do a quick check with ngrok https://ngrok.com/ on the free plan to see if that works. If yes:
Make sure the API is accessible by trying to access it on the device browser (most important is to check if you allow the port at inbound rules, firewall).
If you are using HTTPS, you might get an error if your react native env is not properly configured to accept not trusted certificates, assuming you are using a non trusted one. Do a check without HTTPS, only with HTTP, to see if it's the case. https://github.com/facebook/react-native/issues/20488