I want to show an alert message when user login fails.But alert is not showing.Following is my code in react native.
login
onPressLogin(){
fetch('http://192.168.1.10:3000/users/login',{
method: 'POST',
headers:{
'Content-Type' : 'application/json',
'Accept':'application/json'
},
body: JSON.stringify({
contact:this.state.contact,
password: this.state.password,
})
})
.then(response => response.json())
.then((responseData) =>
{
this.setState({
userdetail: responseData,
})
if(responseData){
setTimeout(() => {
Actions.firstScreen();
}, 2300);
AsyncStorage.saveItem('userid', this.state.userData.phone_no);
} else {
console.log(responseData);
Alert(responseData);
}
});
}
What I'm getting now is it will redirect to firstScreen on successful login but it alert is not coming on unsuccessful login.When I consoled I'm getting unexpected end of json input error but I'm using node js as backend the error result is showing there following is my code in nodejs
else {
appData.error= 1;
appData["data"] = "Phone number and Password does not match";
res.status(204).json(appData);
console.log(appData);
}
}else{
appData.error=1;
appData["data"] ="Phone number does not exist";
res.status(204).json(appData);
console.log(appData);
}
the consoled result of appData is
{ error: 1, data: 'Phone number does not exist' }
I don't know the reason why this error message is not showing within responseData in react native.
onPressLogin(){
fetch('http://192.168.1.10:3000/users/login',{
method: 'POST',
headers:{
'Content-Type' : 'application/json',
'Accept':'application/json'
},
body: JSON.stringify({
contact:this.state.contact,
password: this.state.password,
})
})
.then(response => response.json())
.then((responseData) =>{
if(responseData.error !== 1){ // verify the success case, as you didn't provide the success case i am using the error code
this.setState({ // its recommended you verify the json before setting it to state.
userdetail: responseData,
})
setTimeout(() => {
Actions.firstScreen();
}, 2300);
AsyncStorage.setItem('userid', this.state.userData.phone_no); // its setItem not saveitem.
} else {
console.log(responseData);
Alert.alert(JSON.stringify(responseData)); // Alerts doesn't allow arrays or JSONs, so stringify them to view in Alerts
}
}).catch((error) => {
// handle catch
console.log("error:"+JSON.stringify(error));
});
}
Always use 'catch' at the end of promises and handle them.
Do let me know if you still face the issue.
Related
I have already define error initially, but now I don't know why show me error like this
fetch data from backend code:
auth.js file
import fetch from "isomorphic-fetch";
import { API } from "../config";
export const signup = (user) => {
return fetch(`${API}/signup`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(user),
})
.then((res) => {
return res.json();
})
.catch((err) => {
console.log(err);
});
};
I have link connection inside API I'm sure is it ok.
After that when i submit my signup from then show me error, signup handleSubmit code:
signupComponent.js file
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) => {
try {
if (data.error) {
setValues({ ...values, error: data.error, loading: false });
} else {
setValues({
...values,
name: "",
email: "",
password: "",
error: "",
loading: false,
message: data.message,
showForm: false,
});
}
} catch (err) {
console.log(err);
}
});
};
I'm sure my internet connection is ok.
I don't know where is problem.
Any suggestion please.
auth.js file updated:
Return the err from catch
import fetch from "isomorphic-fetch";
import { API } from "../config";
export const signup = (user) => {
return fetch(`${API}/signup`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(user),
})
.then((res) => {
return res.json();
})
.catch((err) => {
return err;
});
};
You have a chain of callbacks
fetch().then().catch()
in your .then() you return the data but in your .catch() you return nothing.
Therefore your outer chain will try to process undefined incase the fetching failed.
signup().then(
(data) => ... data.error // data is undefined
)
I have solve my problem by this way:
used try catch block for find problem
In the catch block used .catch((err) => { return err; });
And make sure API connected succesfully
After that run my backend server
Then run my frontend.
I am having problems using 'nested' Fetch calls within a React Native function. It seems the first Fetch works correctly, however an error is thrown on the second. Here is the code:
//****CALL TWO FETCH REQUESTS...
const data = { passkey: '12345', callup: 'name' };
const secondary = { passkey: '12345', callup: 'name' };
fetch('https://myremoteserveraddress', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(function(response) {
if (response.ok) {
return response.json();
} else {
return Promise.reject(response);
}
})
.then(data => {
// Store the post data to a variable
_post = data;
console.log('Success on FIRST FETCH:', data);
console.log('answer is:', data.answer);
console.log('answer is:', _post.answer);
// Fetch another API
fetch('https://myremoteserveraddress', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(secondary),
})
})
.then(function (response) {
if (response.ok) {
return response.json();
} else {
return Promise.reject(response);
}
})
.then(function (userData) {
console.log('Returned from BOTH fetch calls'); //does not write to console
console.log(_post, userData); //does not write to console
this.vb.start();
})
.catch((error) => {
console.error('Error in onPressPublishBtn:', error);
});
//****
It seems the second Fetch call returns 'undefined', despite being identical to the first Fetch call which seems to work successfully. The error returned is "TypeError: undefined is not an object (evaluating 'response.ok')". If anybody can advise on what the problem may be I would be greatly appreciative. Thank you in advance.
You should return a Promise from the second then(...) block so that the response is passed to the third then(...) block. You might want to try something like this:
// Fetch another API
return fetch('https://myremoteserveraddress', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(secondary),
})
is a bit of a situation
after simple login
i'v tried to properly handle the server error response but at first i thought it will be simple. i was wrong.
the press login function rely on the login function to pass the login status to check if the user is or not logged.
in a way the code works but it will be great if can get the server response and display.
i've tried to use catch or get a response from the login function. either way still not getting the responde. please someone could spare a hint related to this of problem?
login handler on login.jsx
pressLogin() {
return auth
.login(this.state.email, this.state.password)
.then(response => {
this.props.updateAuth();
let res = response.text();
if (response.login_status == false) {
let errors = res;
throw response.json();
//this.setState({ error: errors });
} else {
// console.log('asdasd')
// this.forceUpdate();
this.setState({ redirectToHome: true });
}
})
.catch(errors => {
return errors;
console.log("Error");
});
}
}
if i set a state in catch just setting a string works but it will be great if can get the server side errors
the login on auth.js
login(email, password) {
return fetch("/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
email: email,
password: password
})
})
.then(resp => {
if (resp.status >= 200 && resp.status < 300) {
return resp.text();
} else {
throw resp.json();
}
})
.then(response => {
if (!response.status) {
window.localStorage.setItem("auth_token", response);
return {
login_status: true
};
} else {
return {
login_status: false
};
}
})
.catch(error => {
console.log("Error" + error);
return {
login_status: false
};
});
},
I want to display error message from my API, problem is that I can't reach that error if I check for response.ok, it returns Fetch error, not the one from API..
If I don't use if(response.ok)... it returns the error from API but it dispatches the success action.
Here is the example, login action:
export const signIn = data => dispatch => {
dispatch({
type: SIGN_IN
})
fetch(API_URL+'/login', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(data),
})
.then( response => {
if (!response.ok) { throw response }
return response.json() //we only get here if there is no error
})
.then( json => {
dispatch({
type: SIGN_IN_SUCCESS, payload: json
}),
localStorage.setItem("token", 'Bearer '+json.token)
localStorage.setItem("user", JSON.stringify(json.user))
})
.catch( err => {
dispatch({
type: SIGN_IN_FAILED, payload: err
})
})
}
This is the code for action that dispatches the right message but as success action, not as failed one..
export const signIn = data => dispatch => {
dispatch({
type: SIGN_IN
})
fetch(API_URL+'/login', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(data),
})
.then( response => response.json())
.then( json => {
dispatch({
type: SIGN_IN_SUCCESS, payload: json
}),
localStorage.setItem("token", 'Bearer '+json.token)
localStorage.setItem("user", JSON.stringify(json.user))
})
.catch( err => {
dispatch({
type: SIGN_IN_FAILED, payload: err
})
})
}
With the following solution one can handle JSON API error, Generic API error and Generic fetch error
fetch("api/v1/demo", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"data": "demo"
})
})
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return response.json();
})
.then(data => {
console.log("Success");
console.log(data);
})
.catch(error => {
if (typeof error.json === "function") {
error.json().then(jsonError => {
console.log("Json error from API");
console.log(jsonError);
}).catch(genericError => {
console.log("Generic error from API");
console.log(error.statusText);
});
} else {
console.log("Fetch error");
console.log(error);
}
});
according to This Article :
Per MDN, the fetch() API only rejects a promise when
“a network
error is encountered, although this usually means permissions issues
or similar.”
Basically fetch() will only reject a promise if the user
is offline, or some unlikely networking error occurs, such a DNS
lookup failure.
then, you can use this part of code to use non-network error handlings and make your code more readable
function handleErrors(response) {
if (!response.ok) throw new Error(response.status);
return response;
}
fetch("API URL")
// handle network err/success
.then(handleErrors)
// use response of network on fetch Promise resolve
.then(response => console.log("ok") )
// handle fetch Promise error
.catch(error => console.log(error) );
In order to extract API message from server in case of some error, you have to use the following idiom (which doesn't lie on the surface though), see link
fetch("http://localhost:8090/test/error", {
method: 'GET',
headers: {
'Accept': 'application/json'
}
})
.then(result => {
//Here body is not ready yet, throw promise
if (!result.ok) throw result;
return result.json();
})
.then(result => {
//Successful request processing
console.log(result);
}).catch(error => {
//Here is still promise
console.log(error);
error.json().then((body) => {
//Here is already the payload from API
console.log(body);
});
})
Verbose - yes!, but does exactly what is needed.
I am trying to fetch data, set state and change route in componentDidMount, but it can not be done(only after clicking on the screen ). I guess there something has to do with asynchronous nature of fetch but how can it be fixed?
componentDidMount(){
AsyncStorage.multiGet([USER_TOKEN, USER_REFRESH_TOKEN,USER_REMEMBERED]).then((data) => {
const userRemembered = JSON.parse(data[2][1])
const userAccessToken = data[0][1]
const userRefreshToken = data[1][1]
if (userRemembered) {
fetch("SOME_URL", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
refreshToken: userRefreshToken
})
})
.then(response => response.json())
.then(responseData => {
console.log(responseData); // only after clicking on the screen it is logged
if (responseData.success) {
AsyncStorage.multiSet([[USER_TOKEN,responseData.response.accessToken],[USER_REFRESH_TOKEN,responseData.response.refreshToken],[USER_REMEMBERED,JSON.stringify(true)]])
this.setState({
token:responseData.response.accessToken,
refreshToken: responseData.response.refreshToken,
isLoggedIn: true
}) //only after clicking on the screen state is changed
this.changeRoute(this.state) //only after clicking on the clicking on the screen route is changed
}
else {
console.log("API is not responding");
}
})
.catch((error) => {
console.log(error)
})
}
else{
console.log('user has not checked Remember Me');
}
})
}
I finally figured it out. I had Remote JS Debugging turned on and it was messing things up. I turned it off and everything works fine.