pots API [object object ] in react native - javascript

I had a problem sending data to the server.
when I try to submit data via postman successfully with the response below
and if I activate
'Content-Type': 'application / json'
i have a problem that is
JSON Parse error: Unrecognized token '<'
{
"status": 200,
"message": "success login",
"id_kurir": "3",
"username": "tester",
}
When I try with code, I get an error that is [object object]
this my code :
constructor(props) {
super(props);
this.state = {
Uname : '',
Upass : ''
}
}
login= ()=>{
const {Uname,Upass} = this.state;
fetch('https://example.com/login', {
method: 'POST',
// headers: {
// 'Accept' : 'application/json',
// 'Content-Type': 'application/json'
//},
body: JSON.stringify({
username: Uname,
password: Upass
})
})
.then((response) => response.json())
.then((responseJson) => {
alert(responseJson);
console.log(JSON.stringify(responseJson));
}).catch((error)=>{
console.log(error);
})
Keyboard.dismiss();
}
<Form style={styles.mainForm}>
<Item style={styles.formItems}>
<Input placeholder="Username" style={styles.Input} onChangeText={Uname => this.setState({Uname})}/>
</Item>
<Item style={styles.formItems}>
<Input style={styles.Input} secureTextEntry={true} onChangeText={(Upass) => this.setState({Upass})}/>
</Item>
<View style={styles.Button}>
{/* <Button block style={styles.mainBtn} onPress={() => this.props.navigation.navigate('home')}> */}
<Button block info style={styles.mainBtn} onPress={this.login}>
<Text style={styles.btnText}>Submit</Text>
</Button>
</View>
</Form>
where is the fault?

The server probably a 404 or 500 error. Instead of response.json() use response.text() you will get the html in text.
I assume Your server is not taking JSON formatted body
Try using below code.
Option 1:
fetch('https://example.com/login', {
method: 'POST',
body: JSON.stringify({
username: Uname,
password: Upass
})
}).then(response => response.text()).then((text) => {
if (Platform.OS === 'android') {
text = text.replace(/\r?\n/g, '').replace(/[\u0080-\uFFFF]/g, '');
// If android, remove unwanted chars.
}
return text;
}).then(response => JSON.parse(response));
Option 2:
fetch('https://example.com/login', {
method: 'POST',
body: JSON.stringify({
username: Uname,
password: Upass
})
}).then((response) => response.text()).then((responseJson) => {
alert(JSON.stringify(responseJson));
console.log(JSON.stringify(responseJson));
}).catch((error) => {
alert(JSON.stringify(error));
console.log(error);
})

Related

Can't Get Error Message From Axios Response in React Native

I am writing a mobile application with using React Native. At some part, I need to send a post request and get response including the error part. So, for some certain input, API(my own) returns 409 with a message. Example return:
{
"status": 409,
"message": "E-mail is already exists!"
}
Here, I want to take that message and show to the user. This is what I tried:
UserService.signup({ fullName, email, username, password })
.then(response => {
this.setState({ signUp: true });
if (response.result) {
Toast.show(messages.successfulSignUp, {
backgroundColor: "green",
duration: Toast.durations.LONG,
position: Toast.positions.TOP
});
this.props.navigation.navigate("SignIn");
} else {
}
})
.catch(error => {
Toast.show(error.message, {
backgroundColor: "red",
duration: Toast.durations.LONG,
position: Toast.positions.TOP
});
this.setState({ signUp: false });
});
I tried error.message, error.response, error, error.data keys, but it always says TypeError: undefined is not an object (evaluating 'error.message'). So, how can I get the message from error object?
Edit: This is how I send the request:
import { post } from "./api";
export default {
signup: ({ fullName, email, username, password }) => {
return post("/user/register", { fullName, email, username, password });
}
};
export const request = config => {
return new Promise((resolve, reject) => {
axiosInstance
.request({
url: config.url,
method: config.method || "get",
data: config.body,
headers: {
"Content-Type": "application/json",
"X-Auth-Token": store.getState().auth.token
}
})
.then(response => {
resolve(response.data);
})
.catch(error => {
reject(error.data);
});
});
};
export const post = (url, body = {}) => {
return request({
url,
body,
method: "post"
});
};
Finally I solved this issue. I had to change my request method and the way I reach out to the error:
export const request = (config) => {
return new Promise((resolve, reject) => {
axiosInstance.request({
url: config.url,
method: config.method || 'get',
data: config.body,
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': store.getState().auth.token,
}
}).then(response => {
resolve(response.data)
}).catch(error => {
reject(error.response)
})
})
}
// This is how reach out to the error message:
console.log(error.data.message);
Depending on what the backend returns, the error message in axios is in response.data of the error object.
.catch(error => {
const errResponse = (error && error.response && error.response.data)
|| (error && error.message);
reject(errResponse);
});

Json.stringify cannot serialize cyclic structure while taking values from state

Error is coming while hitting api
createUserProfile=async()=>{
try {
let response = await fetch(baseUrl + 'edituserprofilesave', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
hash: this.state.hash,
timestamp:this.state.timestamp,
id:this.state.id,
firstName:this.state.textFirstName,
lastName:this.state.textLastName,
picture: this.state.avatarSource.uri
}),
});
let responseJson = await response.json();
// alert("my response" + JSON.stringify(responseJson))
alert("success")
} catch (error) {
alert(error);
}
}
I know where error is coming..It is not taking textFirstName and textLastName which i am getting from here..
<FloatingLabelInput
label="First Name*"
onChange={value => {
this.setState({ textFirstName: value });
}}
style={[
styles.FloatingLabelInputStyle,
{ borderBottomColor: this.state.firstNameBorder }
]}
/>
and similarly textLast name ..I am updating state value but i don't know why it is throwing this error ..
Than you in advance

Possible unhandled promise rejection, network error when using axios

I'm trying to send JSON data using react-native, axios and Expo, but when I press "Send" on my application, I get this warning:
Possible unhandled promise rejection, Error: Network Error
My API is correctly receiving the notification (JSON) when I try to send it via POSTman, but when I try to send it using axios, I get the above warning message, so maybe react is not sending the data correctly.
export default class NotificationsInput extends React.Component {
state = {
token: '',
title: '',
body: ''
}
handleToken = event => {
this.setState({ token: event.target.value })
}
handleTitle = event => {
this.setState({ title: event.target.value })
}
handleBody = event => {
this.setState({ body: event.target.value })
}
handleSubmit = event => {
event.preventDefault();
let notification = JSON.stringify({
token: this.state.token,
title: this.state.title,
body: this.state.body
})
let headers = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
axios.post(`http://127.0.0.1:8000/send_push_message/`, notification, headers)
.then(res => {
console.log(res);
console.log(res.data)
})
.then(error => console.log(error));
}
render() {
return (
<View>
<TextInput onChange={this.handleToken}
style={{ height: 25, width: 200, borderColor: 'black', borderWidth: 1 }}
/>
<TextInput onChange={this.handleTitle}
style={{ height: 40, width: 200, borderColor: 'black', borderWidth: 1 }}
/>
<TextInput onChange={this.handleBody}
style={{ height: 40, width: 200, borderColor: 'black', borderWidth: 1 }}
/>
<Button onPress={this.handleSubmit} title="Send">Send</Button>
</View>
)
}
}
Edit :
I added the catch() function, but the error now is only Network Error in the console.
handleSubmit = event => {
event.preventDefault();
let notification = JSON.stringify({
token: this.state.token,
title: this.state.title,
body: this.state.body
})
let headers = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
axios.post(`http://127.0.0.1:8000/send_push_message/`, notification, headers)
.then(res => {
console.log(res);
console.log(res.data)
})
.catch(error => console.log(error));
}
I can see you have chained two, .then which is not correct. You need a catch block to catch network errors. Take a look below
axios.post(`http://127.0.0.1:8000/send_push_message/`, notification, headers)
.then(res => {
console.log(res);
console.log(res.data)
})
.catch(error => console.log(error));
Use catch instead of then for error handling.
.catch(error => console.log(error));
If you have cors enabled in your backend stack,
then try replacing 127.0.0.1 with 10.0.2.2
Hope this helps.

How to send form data from React to express

i'm fairly new in React. I'm trying to send register data to my backend from a from submit. I've tried the traditional method like setting post method and route in the form but that doesn't seem to work. Is there a way to send the data to back end then receive that data on the front end?
back end route: route is localhost:4000/api/users/register
router.post("/register", (req, res) => {
console.log(req.body)
console.log('Hit')
knex.select('*')
.from('users')
.where('email', req.body.email)
.then(function(results) {
knex('users')
.insert([{
first_name: req.body.first_name,
last_name: req.body.last_name,
phone: req.body.phone,
email: req.body.email,
password: bcrypt.hashSync(req.body.password, 15)
}])
.returning('id')
.then(function(id) {
req.session.user_id = id;
})
.catch(function(error) {
console.error(error)
});
}
})
.catch(function(error) {
console.error(error)
});
// }
});
React form code:
class Register extends Component {
constructor(props) {
super(props)
this.state = {
first_name: '',
last_name: '',
email: '',
password: '',
phone: ''
}
}
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit = (e) => {
e.preventDefault();
// get form data out of state
const { first_name, last_name, password, email, phone } = this.state;
fetch('http://localhost:4000/api/users/register' , {
method: "POST",
headers: {
'Content-type': 'application/json'
}
.then((result) => {
console.log(result)
})
})
}
render() {
const { classes } = this.props;
const { first_name, last_name, password, email, phone } = this.state;
return (
<div className="session">
<h1>Create your Account</h1>
<div className="register-form">
<form method='POST' action='http://localhost:4000/api/users/register'>
<TextField label="First Name" name="first_name" />
<br/>
<TextField label="Last Name" name="last_name" />
<br/>
<TextField label="Email" name="email" />
<br/>
<TextField label="Password" name="password" />
<br/>
<TextField label="Phone #" name="phone" />
<Button type='Submit' variant="contained" color="primary">
Register
</Button>
</form>
</div>
</div>
);
}
}
export default Register;
You have to send the data in your state to the server, and you have to use the json method on the response from fetch in order to access it.
fetch('http://localhost:4000/api/users/register', {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(this.state)
})
.then((response) => response.json())
.then((result) => {
console.log(result)
})
You have not posted the data to the api. Also there are few coding errors. You need update code from
fetch('http://localhost:4000/api/users/register' , {
method: "POST",
headers: {
'Content-type': 'application/json'
}
.then((result) => {
console.log(result)
})
To
fetch('http://localhost:4000/api/users/register' , {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(this.state)
})
.then((result) => result.json())
.then((info) => { console.log(info); })
Try using a cool library called axios. this would be the tone down explanation.
On the frontend, you would use axios to post data to your backend:
const reactData = [{ id: 1, name:' Tom'}, { id: 2, name:' Sarah'}];
const url = localhost:4000/api/users/register;
let sendData = () => {
axios.post(url, reactData)
.then(res => console.log('Data send'))
.catch(err => console.log(err.data))
}
On the backend side, you'll receive that data, simply by doing something like:
const url = localhost:4000/api/users/register;
const usersData= [];
let getData = () => {
axios.get(url)
.then(res => usersData.push(res.data))
.catch(err => console.log(err.data))
}

Strange Response Interpretation From Server using React Native

I am using "React Native" in order to create an application for that acts as a web server that currently exist (can't disclose for privacy reasons). I am trying to create a Login Page, everything is set up to start a request using the in build "fetch(url)" command.
type Props = {};
export default class App extends Component<Props> {
constructor (Props) {
super(Props);
this.state={
username:'',
password:'',
Response:''
}
// bindings to state
this.Login = this.Login.bind(this); // you need this to be able to access state from login
this.HttpRequest = this.HttpRequest.bind(this);
this.ValidateResponse = this.ValidateResponse.bind(this);
}
Login(){
requestURL = sURL + "usr=" + this.state.username + "&" + "pwd=" + this.state.password;
var response = this.HttpRequest(requestURL);
this.setState({Response: "Response: " + JSON.stringify(response)});
}
HttpRequest(url){
return fetch(url)
.catch((error) => {
this.setState({Response: "Error: " + error});
});
}
ValidateResponse(response){
this.setState({Response: "Validating Login...\n" + response});
}
render() {
return (
// The Container for the Activity
<View style={styles.container}>
{/* The Image of The MiBase Logo */}
<View style={styles.MiBaseLogo}>
<Image resizeMode="contain" style={styles.MiBaseLogoImage} source={require("./mibaselogo.png")}/>
</View>
{/* The Text Input for the username and password*/}
<TextInput style={styles.Username} placeholder="Username" placeholderTextColor="rgb(200,200,200)"
onChangeText={(username) => {this.setState({username})}}/>
<TextInput style={styles.Password} placeholder="Password" placeholderTextColor="rgb(200,200,200)"
onChangeText={(password) => {this.setState({password})}} secureTextEntry={true}/>
{/* The Button to Command the Login Functionality */}
<TouchableOpacity style={styles.LoginButton} onPress={this.Login}>
<Text style={styles.LoginButtonText}>Login</Text>
</TouchableOpacity>
{/* The Text To Output Success or Report Failure */}
<View style={styles.TextOutput}>
<Text style={styles.TextOutputText}>{this.state.Response}</Text>
</View>
</View>
);
}
}
This is the code for my Page/Activity. I am new at this so i'm not sure if this is typically how it is done, but in order to send a request a global variable "sURL" (Assigned the name of the server) has the varaibles (usr & pwd) appended to it and sent off using fetch. when i json.stringify the response and return it to my debugging test the response is thus
Image of Page
The response when using a Http Get Request (through chrome) is
{"member": {"username":"","password":"","key":"b54d42c276a76283013589a7c285eebf","status":"No"}}
Can anyone explain this or work out what i did wrong?
Not sure why you are getting that error, I just made a form yesterday using https://github.com/gcanti/tcomb-form-native and it was very easy and worked straight away.
I get the impression though that your problem lies with your fetch, do you have access to the api backend? Also are you sending passwords in the url???
What kind of response are you expecting? When creating a login page you should really only need to know if the server accepted the login or not
EDIT:
Here is an example of my login fetch posting the login details to my API as a POST request:
onLoginPress = () => {
const value = this._form.getValue();
if(value != null){
this.setState({
fetching: true
})
var AdminLoginBindingModel = {
AdminID: 0,
AdminName: value.Username,
AdminPassword: value.Password,
}
fetch(YOUR API END POINT',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(AdminLoginBindingModel)
})
.then((res) => res.json())
.then((json) => {
console.log(json);
this.setState({
isLoggedIn: true
})
})
.catch((error) => {
this.setState({
error: 'Something went wrong!' + error,
isLoggedIn: false,
fetching: false
})
})
}
}
Thats how I would do it but you are sending you login details as a part of the url and from your code it looks fine.
EDIT 2:
constructor(props){super(props);
this.state = {
API_Response_Status: false,
JSON_Response: {}
}
}
Then:
fetch(YOUR API END POINT',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(AdminLoginBindingModel)
})
.then((res) => res.json())
.then((json) => {
console.log(json);
this.setState({
API_Response_Status: true,
JSON_Response: json
})
console.log(this.state.JSON_Response);
console.log(this.state.API_Response_Status);
})
.catch((error) => {
this.setState({
error: 'Something went wrong!' + error,
API_Response_Status: false,
fetching: false
})
})
}

Categories

Resources