When I tried to post data from react-native to PHP API, react-native show the error:
Json Parse error: Unrecognized token '<'
I tested PHP API by postman with the header type 'application/json', it works fine, here is the react-native code, can anyone help me on this? Thanks in advance!
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ActivityIndicatorIOS,
TextInput,
TouchableOpacity,
} from 'react-native';
const REQUEST_URL = 'http://localhost:8000/user';
export default class extends Component {
constructor(props) {
super(props);
}
_submit() {
fetch(REQUEST_URL, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstname: "Justin", lastname: "Robot"
})
})
.then((response) => response.json())
.then((responseData) => {
console.log(responseData.body);
})
.done();
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.submitButton}
onPress={() => this._submit()}
>
<Text>http post</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
submitButton: {
backgroundColor: 'lightskyblue',
borderRadius: 5,
paddingTop: 5,
paddingBottom: 5,
paddingLeft: 20,
paddingRight: 20,
}
});
We just ran into this in React Native because our server was returning an error response via HTML.
<html>
<head><title>413 Request Entity Too Large</title></head>
<body bgcolor="white">
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx</center>
</body>
</html>
The fixes could be any of the following:
1) Prevent the error from happening in your server side code.
2) Do better error handling on your server to return JSON errors instead of HTML errors.
3) Write some client side code to detect that HTML was returned and show a more useful error message.
Related
I want to display data from the MySQL table that is processed with PHP and react native but does not provide a response and does not display any error messages. If the PHP script I run with my browser will appear as follows:
[
{"group":"1","name":"Soy Souce A"},
{"group":"2","name":"Soy Souce B"},
{"group":"3","name":"Chili Tomato Souce"},
{"group":"4","name":"Vinegar"},
{"group":"5","name":"Syrup"}
]
This is the screen capture display:
My question :
Why the data can not be displayed
As in screen capture, why 3 headers can appear, header 2 is for navigation, how to eliminate headers 1 and 3
please help me overcome it, thank you
This is the react native script
import React, { Component } from 'react';
import DatePicker from 'react-native-datepicker'
import { View, Text, TouchableOpacity, FlatList } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack'
import { createAppContainer } from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons';
import { Item, } from 'native-base';
class DataSearch extends React.Component {
constructor(props){
super(props)
this.state = {
date:"",
isLoading: false
}
}
componentDidMount() {
var that = this;
var date = new Date().getDate();
var month = new Date().getMonth() + 1;
var year = new Date().getFullYear();
that.setState({
date: date + '-' + month + '-' + year,
});
}
DataShowProcess = () =>{
const { date } = this.state ;
this.setState({
dataSource: [],
isLoading: true
});
fetch('https://example.com/item_group.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
dateSearch: date,
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
});
this.props.navigation.navigate('Second', this.state.dataSource);
})
.catch((error) => {
console.error(error);
});
}
render(){
return (
<View>
<DatePicker
style={{width: 200}}
date={this.state.date}
mode="date"
placeholder="select date"
format="DD-MM-YYYY"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: 'absolute',
left: 200,
top: 0,
marginLeft: 0
},
dateInput: {
marginLeft: 100
},
}}
onDateChange={(date) => {this.setState({date: date})}}
/>
<TouchableOpacity
style={{ alignItems: 'center'}}
onPress={this.DataShowProcess}
>
<Icon name='search' size={35} color='black'/>
</TouchableOpacity>
</View>
)
}
}
class DataShow extends React.Component {
render(){
const { navigation } = this.props;
return (
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.responseJson}
renderItem={({item}) => <Text>{item.group}, {item.name}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
)};
}
const RootStack = createStackNavigator({
First: DataSearch,
Second: DataShow,
});
export default createAppContainer(RootStack);
can't upload images from react-native code to PHP server, however images are uploaded without any problem using postman, i suppose the problem isn't related with the server or the back end, but I'll provide the front end and back end code
I tried different libraries like react-native-document-picker and react-native-image-crop-picker but with no hope, so please could you tell me where exactly the problem is
PHP code
public function createApiImage(Request $request)
{
$attachment = [];
if ($request->attachments != null) {
$attachment = $request->attachments ;
$photo_name = 'ads';
$imgPath = $attachment->store("{$photo_name}", 'public');
$attachment1 =[
'type' => $attachment->getMimeType(),
'path' => $attachment->store("{$photo_name}", 'public'),
'name' => $attachment->getClientOriginalName(),
'created_at' => \Carbon\Carbon::now()
];
$imgPathUrl = 'http://dejara.net/storage/app/public/'.$imgPath;
$Mediadate = ['name' => "$imgPathUrl",'linked_id' => 0];
$media = Media::create($Mediadate);
}
return response()->json([
'success' => 'true',
'info' => [
'Media' => $media,
]
]
, 200
);
}
react-native code
import React, { Component } from 'react';
import ImagePicker from 'react-native-image-picker'
import { Text, View, TouchableOpacity, BackHandler, Image, ScrollView, Platform, ActivityIndicator, StatusBar, Dimensions } from 'react-native'
import { RFValue } from 'react-native-responsive-fontsize';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'
class PlaceAd extends Component {
state = {
pickedImages: []
}
pickImage = async () => {
ImagePicker.showImagePicker({ title: "choose your image" }, res => {
if (res.didCancel)
console.log('User cancelled')
else if (res.error)
console.log(res.error)
else {
// console.log(res)
let temp = this.state.pickedImages
temp.push({ uri: res.uri, name: res.fileName, type: res.type, path: res.path })
this.setState({ pickedImages: temp })
}
})
}
createAdv = () => {
var data = new FormData();
this.state.pickedImages.map((image, i) => {
data.append('my_photo', {
uri: image.uri,
path: image.uri,
name: image.name,
type: image.type,
})
})
fetch('http://dejara.net/public/api/createAdsImage', {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: data
})
.then(response => response.json())
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
}
render() {
return (
<View style={{width:'100%', alignItems:'center'}}>
<TouchableOpacity style={{ marginBottom: RFValue(20), marginTop: RFValue(10), width: RFValue(150), height: RFValue(150), justifyContent: 'center', alignItems: 'center', borderWidth: 1 }} onPress={this.pickImage}>
<FontAwesomeIcon name="photo" size={RFValue(20)} color="#000" />
<Text style={{ color: "#000" }}>choose photo</Text>
</TouchableOpacity>
<TouchableOpacity style={[{ width: '60%', height: RFValue(50), marginBottom: RFValue(15) }]} onPress={this.createAdv} >
<Text>Publish</Text>
</TouchableOpacity>
</View>
)
}
}
export default PlaceAd
I guess I found the problem do step by step and it may fix :
1- npm install form-data
2- import formData from 'from-data';
3- change var to const ===> const data = new FormData();
the most important thing is to install the form-data package to fix this issue
before that test your backend with postman to make sure it works properly and the problem is just about the fronend and follow that steps and i hope you fix it.
I got it, the server just waits for attachments
if ($request->attachments != null)
while i send my_photo instead
data.append('my_photo',
just changing my_photo to attachments solved my issue
I am unable to post data to the PHP server. I am using Axios.
I can post successfully using Postman, but I can't from my React Native application.
What am I doing wrong?
<TouchableOpacity
style={{ fontSize: 18, color: 'white' }}
containerStyle={{
padding: 8,
marginLeft: 70,
marginRight: 70,
height: 40,
borderRadius: 6,
backgroundColor: 'mediumseagreen'
}}
onPress={() => {
axios.post('url', {
"Reason": this.state.newTodo,
"BranchRef": this.props.branch,
"AppointmentDate": this.props.date,
"ToSeeRef": 369,
"PatientRef": 63,
"AppointmentTimeID": this.props.appointmentTime,
"AppointmentPlatform": 2,
"Completed": 0
}, {
"headers": {
"Accept": 'application/json',
'Content-Type': 'application/json',
}
}).then((response) => {
console.log("reactNativeDemo", "response get
details:" + response.data);
})
.catch((error) => {
console.log("axios error:", error);
});
}}
>
See error message below
axios error: [Error: Request failed with status code 500]
https://postman-echo.com/ - use postman echo to check if there is problem with your client or with the server. It might be a server problem, not from you :-/
Do not enter the Axios function in the render, separate it in different functions and the 'url' variable do you define it as global or inside render?
try :
postData = async () => {
axios.post ('your url', {
"Reason": this.state.newTodo,
"BranchRef": this.props.branch,
"AppointmentDate": this.props.date,
"ToSeeRef": 369,
"PatientRef": 63,
"AppointmentTimeID": this.props.appointmentTime,
"AppointmentPlatform": 2,
"Completed": 0
}, {
"headers": {
"Accept": 'application / json',
'Content-Type': 'application / json',
}
}). then ((response) => {
console.log ("reactNativeDemo", "response get
details: "+ response.data);
})
.catch ((error) => {
console.log ("axios error:", error);
});
}
then
on
onPress = {this.postData}
After checking my php/webserver logs, I was able to resolve this by changing the date format on my app.
I am using react-native-datepicker and the date format was different from what the server was expecting.
<DatePicker
date={this.state.date}
mode="date"
format="YYYY-MM-DD"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: 'absolute',
left: 0,
top: 4,
marginLeft: 0
},
dateInput: {
marginLeft: 36,
borderWidth: 0,
right: 0,
color: "grey"
}
}}
onDateChange={(date) => { this.setState({ date:
date }); }}
/>
I tried a ReactJS fetch call to a REST-API and want to handle the response. The call works, i get a response, which i can see in Chrome Dev Tools:
function getAllCourses() {
fetch('http://localhost:8080/course', {
method: 'POST',
mode: 'no-cors',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
objectClass: 'course',
crud: '2'
})
}).then(function (response) {
console.log(response);
return response.json();
}).catch(function (err) {
console.log(err)
});
}
When i try to handle the response, i got a "SyntaxError: Unexpected end of input" at
return response.json();
The console.log looks like this:
My Response JSON looks like this, it is valid, i checked it with jsonlint:
[
{
"0x1": {
"users": [],
"lectures": [],
"owner": "0x2",
"title": "WWI 14 SEA",
"description": null,
"objectClass": "course",
"id": "course_00001"
},
"0x2": {
"username": "system",
"lectures": [],
"course": null,
"solutions": [],
"exercises": [],
"roles": [
"0x3",
"0x4",
"0x5"
],
"objectClass": "user",
"id": "user_00001"
},
"0x3": {
"roleName": "ROLE_ADMIN",
"objectClass": "role",
"id": "role_00001"
},
"0x4": {
"roleName": "ROLE_STUDENT",
"objectClass": "role",
"id": "role_00002"
},
"0x5": {
"roleName": "ROLE_DOCENT",
"objectClass": "role",
"id": "role_00003"
}
}
]
You need to remove the mode: 'no-cors' setting from your request. Setting no-cors mode is exactly the cause of the problem you’re having.
A no-cors request makes the response type opaque. The log snippet in the question shows that. Opaque means your frontend JavaScript code can’t see the response body or headers.
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode explains:
no-cors — JavaScript may not access any properties of the resulting Response
So the effect of setting no-cors mode is essentially to tell browsers, “Don’t let frontend JavaScript code access the response body or headers under any circumstances.”
People sometimes try setting no-cors mode when a response doesn’t include the Access-Control-Allow-Origin response header or else because the request is one that triggers a CORS preflight, and so your browser does an OPTIONS preflight.
But using no-cors mode isn’t a solution to those problems. The solution is either to:
configure the server to which you’re making the request such that it sends the Access-Control-Allow-Origin response header, and such that it handles OPTIONS requests
or set up a CORS proxy using code from https://github.com/Rob--W/cors-anywhere/ or such; see the How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems section of the answer at No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
In your then you should check if the response is OK before returning response.json:
.then(function (response) {
if (!response.ok) {
return Promise.reject('some reason');
}
return response.json();
})
If you want to have the error message in your rejected promise, you can do something like:
.then(function (response) {
if (!response.ok) {
return response.text().then(result => Promise.reject(new Error(result)));
}
return response.json();
})
I know this answer might be super late and might have been resolved but i just had the same issue today and I just needed to add a ',' at the end of the headers hash and i stopped getting the error
export function addContacts(formData) {
return(dispatch) => {
dispatch({type: 'POSTING_CONTACTS'});
console.log(formData)
return fetch(uri, {
method: 'POST',
body: JSON.stringify({contact: {name: formData.name, phone_number: formData.phoneNumber}}),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
})
.then(response => {
return response.json()
}).then(responseJSON => {
console.log(responseJSON)
return dispatch({type: 'ADD_CONTACT', payload: responseJSON});
})
}
}
You can avoid the problem with CORS policy by adding in the header of php or another server endpoint the row:
<?php
header('Access-Control-Allow-Origin: *');
//or
header('Access-Control-Allow-Origin: http://example.com');
// Reading JSON POST using PHP
$json = file_get_contents('php://input');
$jsonObj = json_decode($json);
// Use $jsonObj
print_r($jsonObj->message);
...
// End php
?>
Model of working fetch code with POST request is:
const data = {
optPost: 'myAPI',
message: 'We make a research of fetch'
};
const endpoint = 'http://example.com/php/phpGetPost.php';
fetch(endpoint, {
method: 'POST',
body: JSON.stringify(data)
})
.then((resp) => resp.json())
.then(function(response) {
console.info('fetch()', response);
return response;
});
Simply copy the following code and paste it on your web.config file under <system.webServer> tag.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
I'm a beginner with react native. In my react native project, I have this front-end.
Here, all these CIS, PST and all other data are retrieved from the database by creating a JSON object in PHP file. They are listed as shown and I have added a delete button for each data of database table as you can see in the photo. But I couldn't add a functionality to the delete button yet because I couldn't specify the data to the button. What I want is, if I click the delete button in front of CIS, delete CIS row only. If I click the delete button in front of PST, delete PST row only. How to specify that data to the button and delete it.
This is my react native code.
import React, { Component } from 'react';
import { AppRegistry, Text, AsyncStorage, StyleSheet, TextInput, View, Alert, Button, FlatList, TouchableOpacity } from 'react-native';
class MainProject extends Component {
constructor(props) {
super(props)
this.state = {
name: ''
};
this.persistData = this.persistData.bind(this);
}
state = {
data: []
};
persistData() {
let name = this.state.name
AsyncStorage.setItem('name', name).done();
this.setState({ name: name, persistedName: name })
}
check() {
AsyncStorage.getItem('name').then((name) => {
this.setState({ name: name, persistedName: name })
})
}
componentWillMount() {
this.check();
//this.fetchData();
}
fetchData = async () => {
const response = await fetch('http:/192.168.182.131/test/select.php');
const json = await response.json();
this.setState({ data: json.results });
};
removeData = async () => {
const response = await fetch('http:/192.168.182.131/test/delete.php');
const json = await response.json();
this.setState({ data: json.results });
};
InsertDataToServer = () => {
const { name } = this.state;
fetch('http:/192.168.182.131/test/submit_user_info.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name
})
}).then((response) => response.json())
.then((responseJson) => {
// Showing response message coming from the server after inserting records.
Alert.alert(responseJson);
}).catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.MainContainer}>
<TextInput
// Adding hint in Text Input using Place holder.
placeholder="Enter Name"
onChangeText={name => this.setState({ name })}
// Making the Under line Transparent.
underlineColorAndroid='transparent'
style={styles.TextInputStyleClass}
/>
<Button title="SUBMIT" onPress={this.InsertDataToServer} color="#2196F3" />
<Button title="VIEW ALL" onPress={this.fetchData} color="green" style={styles.ViewAll} />
<View>
<Text>STATE:</Text>
<Text>Name: {this.state.name}</Text>
</View>
<View style={styles.container}>
<FlatList
data={this.state.data}
keyExtractor={(x, i) => i}
renderItem={({ item }) =>
<View>
<View>
<Text>
{`${item.name}`}
</Text>
</View>
<View>
<TouchableOpacity onPress={this.removeData}>
<Text style={styles.button}>
DELETE
</Text>
</TouchableOpacity>
</View>
</View>
}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer: {
justifyContent: 'center',
flex: 1,
margin: 10
},
TextInputStyleClass: {
textAlign: 'center',
marginBottom: 7,
height: 40,
borderWidth: 1,
// Set border Hex Color Code Here.
borderColor: '#FF5722',
},
container: {
marginTop: 15,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
ViewAll: {
marginTop: 50
},
button: {
borderColor: 'red',
backgroundColor: 'red',
width: 60,
textAlign: 'center',
borderRadius: 10,
color: 'white'
}
});
AppRegistry.registerComponent('albums', () => MainProject);
This is my PHP code to create the JSON object using database data.
<?php
include 'DBConfig.php';
$con = mysqli_connect($HostName, $HostUser, $HostPass, $DatabaseName);
$query = "SELECT * FROM Department ORDER BY id ASC";
$res = mysqli_query($con,$query) or die("Query Not Executed " . mysqli_error($con));
$data = array();
while($rows = mysqli_fetch_assoc($res)) {
$data[] = $rows;
}
$write = json_encode(array('results' => $data));
echo $write;
mysqli_close($con);
?>
You need to pass an identifier to PHP. I recommend you to use your id for that. This means, you have to send you id to the client, and if you press on delete, you explicitly tell te server to delete this one id.
Your removeData function would have something like that in it:
fetch('http://192.168.182.131/test/delete.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: id
})
})
This is not the best solution, but it should work. If you have some time, I also recommend you to take a look at CRUD.