SyntaxError: JSON Parse error: Unrecognized token '<' for React Native - android

I'm trying to send a fetch request using post to an api, I'm doing a search using a keyword and it should return a JSON containing users, whenever I try this on Android using expo it doesn't work however it seems to work on iOS using expo. The error I get back is a JSON parse error, I get a status code of 308.
import User from '../../Model/User';
import { BearerToken } from '../../Constants/BearerToken';
export const GETRESULTS = 'GETRESULTS';
export const getResults = (item) => {
return async dispatch => {
const response = await fetch("https://example.com",
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': BearerToken
},
body: JSON.stringify({
query: item
}),
redirect: 'follow'
}
);
console.log(response.status);
if(!response.ok) {
console.log("fack off");
const errorResData = await response.json();
console.log(errorResData);
let message = 'Something went wrong';
throw new Error(message);
}
const resData = await response.json();
const searchResultsArray = [];
for(const searchResult in resData){
searchResultsArray.push(new User(
resData[searchResult].education,
resData[searchResult].email,
resData[searchResult].full_name,
resData[searchResult].gender,
resData[searchResult].job_title,
resData[searchResult].location,
resData[searchResult].password,
resData[searchResult].phone,
resData[searchResult].preferred_name,
resData[searchResult].profile_image,
resData[searchResult].profile_type,
resData[searchResult].score,
resData[searchResult].short_bio,
resData[searchResult].story
)
);
}
dispatch({type: GETRESULTS,usersArray:searchResultsArray});
};
};

What worked for me was putting 'https://example.com/search/' basically at a slash at the end fixed it for me

Related

Fetch DELETE method on Android (React Native)

I make several requests from a React Native app to an API. Every request works fine both on iOS and Android except the DELETE method that does not work on Android. The call is correctly made, it goes through the API and the objects are deleted. But instead of getting the response, the call falls under the catch statement with [TypeError: Network request failed]. This does not happen in iOS.
Some people with the same problem were missing 'Content-Type': 'application/json' on the request headers which is not my case.
This is happening both locally, in testing and production stages (using an ip instead of localhost will do nothing).
The request is also successfully performed in Postman.
What can it be?
React Native 0.63.5
export const deleteApi = async (api: string, body?: any) => {
const userResponse = await getUserCredentials();
const authState = await getAuthState();
let response = await fetch(api, {
method: 'DELETE',
headers: await getHeaders(userResponse, authState),
body: JSON.stringify(body)
});
if (response.status === UNAUTHENTICATED_CODE)
response = await interceptor(response, userResponse, {
api: api,
method: 'DELETE',
body: body
});
return response;
};
leaveClass = async (
uuid: string,
onSuccess: () => void,
onFailure: (error: string) => void,
) => {
this.setLoading(true);
try {
const api = LEAVE_CLASS_API_PREFIX + uuid + LEAVE_CLASS_API_SUFFIX;
const response = await deleteApi(api);
if (response.status === SUCCESS_STATUS_CODE) {
onSuccess();
}
else {
const jsonResponse = await response.json();
if (jsonResponse.detail) onFailure(jsonResponse.detail);
else onFailure(translations.SOMETHING_WENT_WRONG);
}
} catch (error) {
console.log('leaveClass error: ', error);
}
this.setLoading(false);
};
You can use a network plugin for Flipper (https://fbflipper.com/docs/setup/plugins/network/), copy your request from it as a curl, and try to perform it from your terminal or postman. If it has the same error, the problem is not in React Native.

React Native android FormData response goes to catch block after .json()

I'm trying to POST data with FormData to get a response, on iOS it works as expected, but on android, it always goes to the catch block, I found out the reason for that is response.json() with error: [SyntaxError: JSON Parse error: Unrecognized token '']
Here is my code:
const onAndroidSucks = () => {
setLoading(true);
let formData = new FormData();
formData.append("number", number.replace(/\s+/g, '').substring(4));
formData.append("id", userID);
formData.append("token", userToken);
fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body: formData
}).then(response => response.json()).then(response => {
if (response.res === 'no') {
Alert.alert('ჰეჰე');
} else {
setData(response);
}
setLoading(false);
}).catch(err => { Alert.alert(err.message); setLoading(false); } );
};
I don't understand what the actual problem is here.
It turned out that problem was okHttp on android. Looks like okHttp appends an empty string " " without a known reason.
Here is how I solved that issue with the workaround:
}).then(response => response.text())
.then((res) => JSON.parse(res.trim())).then(response => {

Error: Network Error Axios - Image React Native

Im trying to post an Image to server but axios throw an error saying
[Error: Network Error]
I created a bodyFormData and appended the following
bodyFormData.append('image', {
name: imgName,
type: 'image/jpeg',
uri: this.state.image,
});
where my imageName is just a string and the this.state.image is the file path file:///storage/emulated/0/Pictures/0cccb0f1-375b-44b8-b15b-4625536a8d63.jpg
Axios Call
const addProduct = async product => {
try {
var prod = await axios({
method: 'post',
url: baseURL + 'addProduct',
data: product,
headers: {
'content-type': `multipart/form-data; boundary=${product._boundary}`,
Accept: 'application/json',
},
},
});
return prod;
} catch (err) {
throw err;
}
};
after alot of trials i understand that in bodyFormData even i write any kind of json object
const oj = {
name: 'a',
c: 8,
}
bodyFormData.append('image', obj );
it throws me the same error
[Error: Network Error]
Kindly please drop the best possible solution for the problem
Thank you for your precious time.
I recently implemented this (working) code
const formData = new FormData();
formData.append('file', {
type: 'image/jpeg',
name: `myname.jpeg`,
uri: isAndroid() ? uri : uri.replace('file://', ''),
});
and with this header in the api call
'Content-Type': 'multipart/form-data'
It's very similar to your code - maybe the uri part then ?

React-Native multipart photo upload not working in android

I'm trying to send/upload image file to my back-end serve using fetch multipart upload in react-native, but fetch multipart form data upload is not working for android, however I tried different examples.
Image upload multipart form data API is based on php and its working for iOS react-native app.
I am using react-native-photo-upload library for taking image.
storePicture(PicturePath:string) {
console.warn(PicturePath);
if (PicturePath) {
const apiUrl = `${Constants.APIHOST}updateprofileimage.php`;
// Create the form data object
var data = new FormData();
data.append('profileimage', { uri:PicturePath, name: 'profileimage.jpg', type: 'image/jpg/jpeg' });
data.append('accesstoken', this.state.user.sAccessToken);
data.append('react-native', 1);
// Create the config object for the POST // You typically have an OAuth2 token that you use for authentication
const config = { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'multipart/form-data;' }, body: data };
fetch(apiUrl, config)
.then(responseData => { // Log the response form the server
// Here we get what we sent to Postman back
console.warn(`response:${responseData}`);
})
.catch(err => {
console.warn(err);
});
}}
Here is the example how I am calling storePicture() function.
<PhotoUpload onResizedImageUri={
avatar => {
if (avatar) {
this.storePicture(avatar.path);
}
}}
>
<Image source={{uri: this.state.user.sProfileImageUrl}} style={{resizeMode:"cover", marginTop:8.0, backgroundColor:'transparent', height:120.0, width:120, borderRadius:60.0, borderWidth:0.0, borderColor:'transparent'}}/>
</PhotoUpload>
uploadProfileImage = async (image:var) => {
this.setState({
loading: true
});
var RNFS = require('react-native-fs');
const path = Style.IS_IOS ? image.uri : image.path;
var fileName = path.split('/').pop();
var fileType = fileName.split('.').pop();
var filePath = Style.IS_IOS ? path : 'file://' + path;
const apiURL = `${Constants.APIHOST}updateprofileimage.php`;
const formData = new FormData();
formData.append('accesstoken', this.state.user.sAccessToken);
formData.append('reactnative', 1);
formData.append('profileimage', {
uri:filePath,
name: fileName,
type: `image/${fileType}`,
});
try {
const response = await fetch(apiURL, {
body: formData,
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json',
},
})
const json = await response.json()
this.handleUploadImageResponse(json);
} catch (err) {
this.setState({
loading: false
},console.log('catch Error: '+ err));
}
}
I am answering my own question as I haven't found any valid answer for the sake of other users, who are facing same issue.
Please let me know if I can improve my answer/post or in case any help is needed from me.
Image Upload to an API by Multipart FormData
uploadPicture = () => {
console.log(
"Image Upload urI = " + JSON.stringify(this.state.imageSourceUri.uri)
);
this.setState({ loading: true });
const form = new FormData();
form.append("fileToUpload", {
uri: this.state.imageSourceUri.uri,
type: "image/jpg",
name: "12334"
});
fetch("http://119.82.97.221/HPBSProjectApi2/api/HPBS/PostFormData", {
method: "post",
body: form
})
.then(response => response.json())
.then(response => {
console.log("response = " + response);
this.setState({
loading: false
});
});
};
the problem is the type field in the FormData, use mime to resolve it. Images must be image/jpeg.
const formData = new FormData();
formData.append("image",{..., name, uri, type: mime.getType(uri)}));

React Native Fetch API - can't access json or body of response [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Trying to call an API to my backend with Fetch, but I can't access the response body. There's a loot of different notation and syntax about this on the internet and I can't figure out how to do it properly.
I've tried response.json() and responseJson, and stringyfying both. I don't get what I want which is the actual body of the response. It's meant to have a key/token that I then save.
responseJson returns this: responseJson:
{"_40":0,"_65":0,"_55":null,"_72":null}
This is my function:
export function LogIn(em, pass) {
return (dispatch) => {
console.log('LogIn called');
dispatch(logInIsLoading(true));
//from phone
*fetch('http://192.168.1.18:8080/rest-auth/login/', {
method: 'POST',
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
'email': em,
'password': pass,
})
}).then((response) => {
console.log("response " + JSON.stringify(response));
if (!response.ok) {
console.log("ERROR: " + response.statusText);
throw Error(response.statusText);
}
dispatch(logInIsLoading(false));
return response;
})
.then((response) => {
responseJson = response.json();
console.log("responseJson: " + JSON.stringify(response.json()));
return responseJson
})
.then((responseJson) => {
AsyncStorage.multiSet([['key', responseJson.key], ['loggedIn', true]], () => {
console.log(responseJson.key);
dispatch(isLoggedIn(true));
dispatch(getKey(responseJson.key));
});
})*
.catch(() => dispatch(logInHasErrored(true)));
};
}
This is the response, but I can't get to the key in the body:
response {"type":"default","status":200,"ok":true,"headers":{"map":
{"allow":["POST, OPTIONS"],"set-cookie":
["csrftoken=DOMxD5IhNz5Vwm9a3niAR1tRyqBfNzUqnQMAEgk7AGwtwCgnRnZo9x0AMTM2IfK
q; expires=Fri, 22-Feb-2019 17:31:58 GMT; Max-Age=31449600; Path=/,
sessionid=er3fujv8ji96t41n1n8dlzb3zz1itwuj; expires=Fri, 09-Mar-2018
17:31:58 GMT; httponly; Max-Age=1209600; Path=/"],"content-type":
["application/json"],"content-length":["50"],"x-frame-options":
["SAMEORIGIN"],"vary":["Accept, Cookie"],"server":["WSGIServer/0.1
Python/2.7.14"],"date":["Fri, 23 Feb 2018 17:31:58
GMT"]}},"url":"http://192.168.1.18:8080/rest-auth/login/","_bodyInit":"
{\"key\":\"a9951fd6abff4fed35d9a8d1c275bf1212887513\"}","_bodyText":"
{\"key\":\"a9951fd6abff4fed35d9a8d1c275bf1212887513\"}"}
response.json() return Promise
AsyncStorage.multiSet - return Promise. Second parameter of multiSet is Function that will be called with an array of any key-specific errors found
export function LogIn(em, pass) {
return (dispatch) => {
console.log('LogIn called');
dispatch(logInIsLoading(true));
fetch('http://192.168.1.18:8080/rest-auth/login/', {
method: 'POST',
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
'email': em,
'password': pass,
})
}).then((response) => {
if (!response.ok) {
console.log("ERROR: " + response.statusText);
throw Error(response.statusText);
}
dispatch(logInIsLoading(false));
return response;
})
.then((response) => {
return response.json()
})
.then((responseJson) => {
console.log('responseJson', responseJson);
return AsyncStorage.multiSet([['key', responseJson.key],['loggedIn', true]], () => {
dispatch(logInHasErrored(true));
})
.then(() => {
dispatch(isLoggedIn(true));
dispatch(getKey(responseJson.key));
})
})
.catch(() => dispatch(logInHasErrored(true)));
};
}
This is pretty straight forward with axios.
First install axios by doing npm install --save axios
Then inside your Component do this:
handleInput = async() => {
const res = await axios.post('http://192.168.1.18:8080/rest-auth/login/', {
email: this.state.email,
password: this.state.password
});
const data = await res.json();
console.log(data);
}
Make sure you've stored email and password in this.state.email and this.state.password respectively and call handleInput when user presses the Submit button.
Don't forget to import axios import axios from 'axios'

Categories

Resources