3
votes

Challenge is to catch network offline status error during POST request using AXIOS library in React-Native.

axios.post(Constants.API.LOGIN, {
  username: email,
  password: password
})
.then(function (response) {
  console.log('SUCCESS!');
  loginUserSuccess(dispatch, user);
})
.catch(function (error) {
  if(!error.response){
    networkError(dispatch);
  } else {
    loginUserFail(dispatch);
  }    
});

but when I switch off WiFi getting error

Possible Unhandled Promise Rejection (id:0)

What is the way to handle network statuses with AXIOS?

Thanks!

1

1 Answers

2
votes

Check out NetInfo:

import { NetInfo } from 'react-native'

https://facebook.github.io/react-native/docs/netinfo.html

isConnected

Available on all platforms. Asynchronously fetch a boolean to determine internet connectivity.

NetInfo.isConnected.fetch().then(isConnected => {
  console.log('First, is ' + (isConnected ? 'online' : 'offline'));
});
function handleFirstConnectivityChange(isConnected) {
  console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
  NetInfo.isConnected.removeEventListener(
    'change',
    handleFirstConnectivityChange
  );
}
NetInfo.isConnected.addEventListener(
  'change',
  handleFirstConnectivityChange
);

You may have a bit of extra issue there with your handling. I can't see exactly what is triggering the unhandled rejection in your code, but I can assume it is making it into the catch block.

If so, that currently means that either networkError() or loginUserFail() are failing, which is what is actually generating the unhandled rejection.

Take a look at those functions and make sure they have catch blocks inside them if they are asynchronous. Ask yourself where exactly is that error coming from, and answer that first, then look at NetInfo. Otherwise, the unhandled rejection may still be able to occur. Make sure you test all the different ways the code could fail :)

With NetInfo, you could set up something near the root-level in your app architecture, by way of that event listener. This could allow you to manage a setting in something like Redux. If the app detects offline, you could set the value to false and the entire app would know it is offline. You could probably make a middleware.

The code might look something like:

middleware:

`store.dispatch(changeConnectivityState())`

or you could have an action creator (shown with redux-thunk):

export function onAppConnectivityChange(newState) {
    return (dispatch) {
        dispatch({
            type: APP_CONNECTIVITY_CHANGE,
            payload: newState
        })
    }
}

Redux reducer:

case APP_CONNECTIVITY_CHANGE:
    return {
        ...state,
        isConnected: action.payload
    }

In your components:

render() {
    if (this.props.isConnected === true) {
        return <View><Text>We are connected.</Text></View>
    }
}

const mapStateToProps = (state) => {
    const isConnected = state.someReducer.isConnected
    return {
        isConnected
    }
}

export default connect(mapStateToProps, null)(SomeComponent)

Hopefully that gives you some ideas. Axios shouldn't be responsible for checking if the app is online or offline (except for quickly checking against a boolean). Your app should always know if it online or offline, and your components should be able to detect the state. You will find that much more scalable and easier to work with.

If I saw where you were calling Axios from, I could give you a more specific answer.