SSuhat SSuhat - 3 months ago 95
React JSX Question

React Native Get Async Storage return Unhandled Promise

Right now I want to save user token after the user login successful.

Here is my code:

onPress(){
return axios.post('https://api.example.net/v1/user/auth/login', {
email: this.state.email,
password: this.state.password,
}, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then((response) => {
AsyncStorage.setItem('token', response.data.login._cxz, () => {
console.log('success');
});
this.props.navigator.immediatelyResetRouteStack([{name: 'tweets'}]);
})
.catch((error) => {
this.setState({errorMessage: error.response.data.message});
});
}


I already make sure that
response.data.login._cxz
has a value.
Right until here is working. the login will redirect me to
tweets
route.

On my tweets.js:

constructor(props){
super(props);
this.state({token : ''});
}
componentWillMount() {
AsyncStorage.getItem('token', (err, value) => {

console.log(value);
})
}


I just simple
console.log
it to view if the token is saved or not.
But everytime login is done (the success log is appear). I always got this error when enter my tweets:

error

Any solution?

Thanks.

Answer

What is most likely happening is that the then callback is throwing an error at navigator.immediatelyResetRouteStack:

.then((response) => {
  AsyncStorage.setItem('token', response.data.login._cxz, () => {
    console.log('success');
  });
  this.props.navigator.immediatelyResetRouteStack([{name: 'tweets'}]);
})
.catch((error) => {
  this.setState({errorMessage: error.response.data.message});
});

The error is then caught in the catch block, but because the error is a normal JavaScript Error and not an axios error, it does not have response property, and therefore trying to access error.response.data causes the undefined error.

The easy way to detect the kind of error is to duck-type it: If the error has a response, then it's an axios error, otherwise another error:

.catch((error) => {
  if (error.response && error.response.data) {
    this.setState({errorMessage: error.response.data.message});
  } else {
    this.setState({errorMessage: error.message});
  }
});

The error caused by immediatelyResetRouteStack is probably coming from the React render pass that is synchronously executed on the same call stack. Once you fix the broken .catch you'll see what the error message is, but a good guess for a culprit in your limited code sample is:

this.state({token : ''});

Which should be an property assignment, instead of a method call:

this.state = {token : ''};