React-Native + Apollo --> Where to handle situation where you can't connect to server?

I’m getting a “console.error unhandled in react-apollo” error when my RN can’t connect to the apollo server, is there somewhere I can test/catch this error and show a screen?

ApolloClient.js

import { AsyncStorage } from 'react-native';
import ApolloClient, { createNetworkInterface } from 'apollo-client';

const LIVE_URL = 'https://meteorapp.com/graphql';
const DEV_URL = 'http://localhost:3000/graphql';

const networkInterface = createNetworkInterface({ uri: LIVE_URL });

networkInterface.use([{
  async applyMiddleware(req, next) {
    if (!req.options.headers) {
      req.options.headers = {};  // Create the header object if needed.
    }
    
    let token = await getLoginToken()
    req.options.headers['meteor-login-token'] = token || null;
    next();
  }
}]);


const dataIdFromObject = (result) => {
    if (result._id && result.__typename) {
      const dataId = result.__typename + result._id;
      return dataId;
    }
    return null;
  }


const client = new ApolloClient({ 
  networkInterface,
  dataIdFromObject: o => o.id
});

Then main app in main.js:


import Expo from 'expo';
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import App from './routes'
import { store } from './store'
import client from './ApolloClient';

class App extends React.Component {
  render() {
    return (
      <ApolloProvider store={store} client={client}>
        <App />
      </ApolloProvider>
    );
  }
}

Expo.registerRootComponent(App);
1 Like

As an example I did it this way using HoC in Expo

const queryUser = graphql(
  rawUserQuery,
  {
    props: ({data: {error, networkStatus, loading, user}}) => {
    if (loading) return {dataLoading: true}
    if (error) return {hasErrors: true, networkStatus}
    return {
      user,
      networkStatus,
    }
  },
    options: { forceFetch: true, notifyOnNetworkStatusChange: true }
}
)

export default UI => queryUser(class EnsureLoggedInContainer extends React.Component {

  render() {
    // always pass navigator prop to this component
    const { dataLoading, user, hasErrors, networkStatus, navigator } = this.props
    const props = this.props
    if (!dataLoading && user) {
      return <UI {...props} />
    } else if (!dataLoading && !hasErrors) {
      return <RootNavigation {...props}/> // or return <LoginScreen navigator={navigator} /> depending on the logic in your root navigation
    } else if (networkStatus === 8) { // this one, at this point, means query is fine though no connection
      return <NoConnectionScreen navigator={navigator} />
    } else return null
  }
})

More about EnsureLoggedInContainer:

2 Likes