.catch() in react-native's fetch - react-native

This is my code to handle signUp
handleSignUp(){
console.log('Clicked')
fetch('http://laptopIp:9999/signUp',{
method:'POST',
headers:{
Accept:'application/json',
'Content-Type':'application/json',
},
body:JSON.stringify(this.state),
})
.then((res)=>{
console.log("here")
console.log(res)
this.setState({error:false})
}).catch((e)=>{
console.log(e)
console.log("in error")
})
this is express server handling the requset
router.post('/signUp',function(reqs,resp){
MongoClient.connect(url,{ useNewUrlParser: true },function(err,database){
if(err){
console.log(err)
}else{
var dataBases = database.db("thaparApp")
dataBases.collection('userLogin').find({'email':reqs.body.email}).toArray(function(err,result){
if(err){
console.log(err)
}else if(result[0]){
resp.status(403).send({"error":"email is taken"})
}else{
if(validateEmail(reqs.body.email)){
dataBases.collection('userLogin').insertOne(reqs.body)
resp.send()
}else{
resp.status(403).send({"error":"Email is not correct"})
}
}
})
}
})
})
}
What i am doing is sending same username from react-native and express is sending me error 403 but React native is not handling that error in .catch() instead keeping that in .then()
as we can see in image That status code is 403 which is error and .catch() have console.log("in error") which is not getting print.

The call is coming back from the server, although it's status is not what you expected, it's not an error to catch.
Try using fetch's ok to check whether the response was valid, for example:
.then(function(response) {
if (!response.ok) {
//throw error
} else {
//valid response
}
})
You can also access the response's status like:
response.status;
or also, statusText such as:
response.statusText;
checkout the below:
https://developer.mozilla.org/en-US/docs/Web/API/Response/statusText
https://developer.mozilla.org/en-US/docs/Web/API/Response/status
https://www.tjvantoll.com/2015/09/13/fetch-and-errors/

Related

postman req not responding any data even not responding error

Login routes:
router.post("/login", async (req, res) => {
try {
const user = await User.findOne({
mobileNo: req.body.mobileNo,
});
if (!user) {
res.status(401).json("You are not registerd");
}
const password = res.body.password;
if (password === user.password) {
return res.status(200).json("You are logged in");
} else {
return res.status(501).json("Naah! wrong pass");
}
} catch {
(err) => {
res.status(500).json(err);
};
}
});
module.exports = router;
index.js:
app.use("/api/auth", authRoute);
import:
const authRoute = require("./routes/auth");
My postman image, I am not getting any result.
Your try-catch syntax is wrong, correct would be
try {
...
} catch(err) {
res.status(500).json(err);
}
With your syntax, when the catch block is reached, the res.status(500).json(err) statement is not executed, therefore the request never comes back.
In your try block, there are 3 responses available. If the first condition in the if block is also executed with another one of the responses in the below if-else condition this problem may occur. Because at a time, sending 2 responses is impossible. Therefore, you should return that response and terminate.
if (!user) {
return res.status(401).json("You are not registered");
}

facebook login working on development mode or server mod, when create a build, it's not working on any devices. react native app

feature unavailable facebook login in currently unavailable for this app, since we are updating additionl details for this app. please try again later
working only on my system and device, not working in others,
how to resolve this issue,please help
FacebookSignIn = async () => {
// Attempt login with permissions
try {
const result = await LoginManager.logInWithPermissions(['public_profile', 'email']);
console.log("fb login", result)
if (!result.isCancelled) {
await AccessToken.getCurrentAccessToken()
.then(async res => {
console.log("token", res);
// Create a Firebase credential with the AccessToken
const facebookCredential = auth.FacebookAuthProvider.credential(res.accessToken);
console.log("token", res);
// Sign-in the user with the credential
this.setState({ loder: true })
await auth().signInWithCredential(facebookCredential)
.then(response => {
console.log("Login Data", response);
const data = {
"name": response.additionalUserInfo.profile.first_name,
"email": response.additionalUserInfo.profile.email,
"user_type": 0
}
console.log(data);
fetchPostMethod('/facebook-sign-up', data)
.then(async response => {
this.setState({ loder: false })
if (response.status == 200) {
if (response.data.user_type == 0) {
try {
let user = JSON.stringify(response?.data?.user_type)
await AsyncStorage.setItem('SignINToken', response?.data?.token);
await AsyncStorage.setItem('UserType', user);
this.logmodl();
} catch (e) {
console.log("Login error", e)
}
} else {
this.user();
}
console.log("SignIn Successful", response);
} else {
this.field();
}
})
.catch(response => {
this.setState({ loder: false })
console.log("SignIn faild", response.message);
})
this.setState({ FacebookUserInfo: response });
})
.catch(error => {
console.log('Login Data Error', error);
})
})
.catch(error => {
console.log('Something went wrong obtaining access token ', error);
})
}
} catch (error) {
console.log("ERROR WHILE LOGIN! ", error);
}
}
feature unavailable facebook login in currently unavailable for this app, since we are updating additionl details for this app. please try again later
working only on my system and device, not working in others,
how to resolve this issue,please help
Pay attention! For enable Facebook login for other users you need visit the Facebook developer site
and enable work mode for application, moving this switch

Login With React Native using Asyncronous storage

I am implementing login in React Native using Asynchronous storage. Here, when users login successfully, i keep the user object in the Asynchronous storage then i access this information to get the Authentication Key for my API request anytime I want to do a request.
When I login and information is stored in the Asynchronous storage, the current app session fails to get the just stored information hence all my authenticated request fails in this session. When I close the app and restart, I can successfully get the information from the Async storage stored in the previous session and make successful authenticated request.
I do not know what I am missing out in my code as I believe I need to refresh or reload the app internally after a successful login but I do not know how to do this in React Native. Any information or help is needed. Here is my Login code.
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem(USER_DATA, JSON.stringify(data)).then(val => {
console.log('just before reload in login')
Actions.menu(); //this solves the after login problem as it goes to the next page only after a successful AsyncStorage save
this.setState({ procesing: false });
})
.catch(err => {
this.setState({ procesing: false, error: "Couldn't log you in! Please try again" });
//console.log("\nCouldn't save to AsyncStorage: " + err + "\n");
});
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
After I have login, my request looks like ;
//for making a post request
post: (url,body) => {
return fetch(url+'?access-token='+this.state.user.auth_key, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
//'Autorization': 'Bearer token2'
},
})
but the user object is gotten from the Async storage as
getUser(){
return AsyncStorage.getItem("USER_DATA").then(value => {
if(JSON.parse(value) == null) {
return false;
} else {
return JSON.parse(value)
}
});
},
Any Information, Ideas, proposed solutions are highly welcome
If you are receiving the information correctly, you can pass the information to the next screen or use the asynchronous repository as it is now.
If use navigation
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
this.setState({ procesing: false });
this.navigation.navigate("LoginScreen",{data: JSON.stringify(data) })
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
this.state={
data : this.props.navigation.state.params.data
}
If use AsyncStorge
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem("USER_DATA", JSON.stringify(data));
this.setState({ procesing: false });
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
async componentDidMount() {
let data = await AsyncStorage.getItem("USER_DATA")
}

react native AsyncStorage not working?

for setting the item i am using this first code.
console.log(ACCESS_TOKEN);
console.log(typeof(ACCESS_TOKEN));
async function setToken() {
try {
await AsyncStorage.setItem('access_token', ACCESS_TOKEN);
} catch (error) {
console.log("token not set")
}
}
setToken();
for getting the item , i am using this code
componentWillMount(){
async function getToken() {
try {
const value = await AsyncStorage.getItem('access_token');
if (value !== null){
console.log(value);
this.setState({ access_token: value });
}
} catch (error) {
console.log( "Error retrieving data")
}
}
getToken();
the result i am getting in first code is
1a61b72b-ee83-43de-9cf9-3fa270ce694d
string
but getting nothing at console at getting code . why ?
You can try this one:
set item using this
AsyncStorage.setItem('access_token', ACCESS_TOKEN);
get item using this
try {
AsyncStorage.getItem('access_token')
.then((value) => {
if (value) {
// you will get your access_token here
}
}).done();
} catch (error) {
console.log(error); // you will get error here
}
To set the item
AsyncStorage.setItem('access_token', ACCESS_TOKEN)
.then(() => {
//your success code
})
.catch((error) => {
//your failure code
})
To get the item
AsyncStorage.getItem('access_token')
.then(access_token=> {
//you will be getting the access token here
})
.catch(err => {
//handle the error
})
Maybe this is what you intended:
async function getToken() {
try {
const value = await AsyncStorage.getItem('access_token');
if (value !== null){
console.log(value);
this.setState({ access_token: value });
}
} catch (error) {
console.log( "Error retrieving data")
}
}
componentWillMount(){
getToken();
}
If instead your code is getting stuck while working with AsyncStorage, there's a well known bug reproducible only in development: https://github.com/facebook/react-native/issues/12830
They only way to bypass it, afaik, it is just to restart the debugger when you get stuck
Remember that setting state during componentWillMount is not the correct way to do it. You should use the constuctor for that
My answer might not directly apply to your case, But I had the same problem as you did with AsyncStorage and It was getting stuck, so this might help other people.
As stated in this answer:
AsyncStorage only takes string as a value and key.
But I was accidentally giving it null (which as you know is considered an object) so it got stuck. So check if you are passing a string value as both the first and second argument to setItem.

Catch React Native fetch error without halting the app with red screen

I am making a React Native function that pulls the HTML of a webpage. It works fine if the URL exists and I receive a 200 status code. However, when I put a wrong url in there (something that would receive a 404 error), it displays a red screen that says "Network request failed." I'd like to catch the error without the whole app halting and display an alert to the user. How can I go about doing that?
fetchEvents() {
fetch('http://www.wrongurl.com', {
method: 'GET',
redirect: 'follow'
})
.then(function(response) {
if (response.status == 200) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else throw new Error('HTTP response status not code 200 as expected.');
})
.catch(function(error) {
console.error(error);
return error;
});
}
This is how I solved this, making graceful errors that don't crash the app using promises:
In my API service class:
fetchEvents() {
let thisCurrentAPIService = this;
return new Promise(
function (resolve, reject) {
fetch('http://www.wrongurl.com');
.then(
function(response) {
if (response.ok) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else {
reject(new Error(`Unable to retrieve events.\nInvalid response received - (${response.status}).`));
}
}
)
.catch(
function(error) {
reject(new Error(`Unable to retrieve events.\n${error.message}`));
}
);
}
);
}
Then I call it from my React Component. If I receive an error, I create the alert there.
this.state.apiService.fetchEvents()
.then(
function (value) {
console.log('Contents: ' + value);
},
function (reason) {
Alert.alert(`${reason.message}`);
});
Hilarious, three years almost and no proper answer still.
However, console.error(error) is what actually causing the app to throw a red screen.
You can use Alert component from react-native.
fetchEvents() {
fetch('http://www.wrongurl.com', {
method: 'GET',
redirect: 'follow'
})
.then(function(response) {
if (response.status == 200) {
let responseText = JSON.stringify(response.text());
console.log(responseText);
}
else throw new Error('HTTP response status not code 200 as expected.');
})
.catch(function(error) {
Alert.alert(error); // Using this line
});
}
But I prefer using toast like on Android than alert.
console.warn('This is my error');
If this is simply for dev it might help. It explicitly uses the little warning toast to provide whatever feedback you need. Note: this is definitely not for production use.
Add following in app index.js file
console.reportErrorsAsExceptions = false;