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.
Related
got the title error and can't fix it :(. I'm triying to get the data from a signup page, here is my javascript code:
const SignupComponent = () => {
const [values, setValues] = useState({
name: 'ryan',
email: 'ryan#gmail.com',
password: 'rrrrrr',
error: '',
loading: false,
message: '',
showForm: true
});
const { name, email, password, error, loading, message, showForm } = values;
const handleSubmit = e => {
e.preventDefault();
// console.table({ name, email, password, error, loading, message, showForm });
setValues({ ...values, loading: true, error: false });
const user = { name, email, password };
signup(user).then(data => {
if(data.error) {
setValues({ ...values, error: data.error, loading: false });
} else {
setValues ({ ...values, name: '', email: '', password: '', error: '', loading: false, message: data.message, showForm: false});
}
});
};
const handleChange = name => e => {
setValues({ ...values, error: false, [name]: e.target.value })
, so when i try to register in the page, its says TypeError: can't access property "error", data is undefined.
signup(user).then(data => {
> 25 | if(data.error) {
| ^
26 | setValues({ ...values, error: data.error, loading: false });
27 | } else {
Signup Function
export const signup = (user) => {
return
fetch(${API}/signup, { method: 'POST',
headers: { Accept: 'application/json',
'Content-Type': 'application/json' },
body: JSON.stringify(user) })
.then(response => { return response.json(); })
.catch(err => console.log(err));
i'm kinda nooby in programming but i already look in the internet for a solution, nothing works u.U
I guess you are not quite familiar with the concept of Asynchronous programming. Fetch is an Async function and if you want to wait for it's output you have to you use the Await keyword which also requires signup to be Async. So your code will look some what like this:
export const signup = async (user) => {
let fetchResponse = fetch(${API}/signup, { method: 'POST',
headers: { Accept: 'application/json',
'Content-Type': 'application/json' },
body: JSON.stringify(user) });
return (await fetchResponse.json())
To Learn more about Asynchronous programming, I recommend reading this article https://blog.risingstack.com/node-hero-async-programming-in-node-js/
When you called json() method in fetch response a Promise is returned since reading a stream object will happen aysnchronously. So what you is to chain another then function to get that data like this.
export const signup = user => {
return fetch(`${API}/signup`, {
method: "POST",
headers: { Accept: "application/json", "Content-Type": "application/json" },
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.then(data => {
return data;
})
.catch(err => console.log(err));
};
PS: neither you need to use async/ await since you are using Promises with .then(), nor there is any need for chaining with one more .then() inside signup() since you are already doing that in handleSubmit() where you've called signup().
Try re-writing your signup() function as below. I guess you've missed back-ticks because I've implemented the SignUp in a similar way and it works for me. Let me know if it helps:
export const signup = (user) => {
return fetch(`${API}/signup`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
PS: neither you need to use async/await since you are using Promises with .then(), nor there is any need for chaining with one more .then() inside signup() since you are already doing that in handleSubmit() where you've called signup().
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);
})
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);
});
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
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
})
})
}