Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance

Viewed 41

This is my first Apollo Project, but I have been working with it for awhile, and things had been pretty smooth in terms of Apollo, until recently. While I understand how Apollo works, I obviously do not know all the minutae involved with it, and I am unclear I suppose on exactly how the project is supposed to be wrapped. Below is my App.js, when it worked as anticipated...

// Auth for token
const authLink = setContext((_, { headers }) => {
    const token = state
    return {
        headers: {
            ...headers,
            authorization: token ? `${token}` : ''
        }
    }
})

// Initialize Apollo Client
const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
});

const Stack = createNativeStackNavigator();

export default function App() {

// Other irrelevant things like fonts...

const ErrorPrompt = (props) => {
    return(
      <View>
        <View style={{height: 50, width: '100%', backgroundColor: "#534FFF"}}/>
        <Text style={{...Template.title, fontSize: 30}}>Something happened!</Text>
        <Text style={{...Template.subTitle, fontSize: 20}}>We apologize for the inconvenience</Text>
        <Text style={{...Template.title, fontSize: 20, color: '#534FFF'}}>{props.error.toString()}</Text>
        <View style={{marginLeft: 30}}>
          <Text style={{...Template.subTitle, fontSize: 15, marginRight: 30, marginLeft: 0}}>An email has been sent to the Support Team to attempt to prevent this error from occurring again. We thank you for your support and patience</Text>
        </View>
        <View style={{marginTop: 50}}>
          <Button onPress={props.resetError} title={'Reload Application'} />
        </View>
      </View>
    )
  }

   if(!loaded){
    return null
  }
  try{
    return (
      
      <ErrorBoundary 
        FallbackComponent={ErrorPrompt}
      > 
      <NavigationContainer>
        <ApolloProvider client={client}>
          <RecoilRoot>
            <IconRegistry icons={EvaIconsPack} />
            <ApplicationProvider {...eva} theme={{...eva.light, ...theme}}>
              <PaperProvider>
              <KeyboardAvoidingView
                behavior="padding"
                enabled
                style={{flexGrow:1,height:'110%'}}
                >
                <View style={AppStyles.container}>
                  <Stack.Navigator screenOptions={{headerShown: false}}>
              
                    {/* {loggedIn === false ? ( */}
                    <Stack.Screen name="/">
                      {props => <LandingPage {...props} handleLoggedIn={handleLoggedIn} rememberMe={rememberMe} setRememberMe={setRememberMe} />}
                    </Stack.Screen>
                     {/* ) : null}  */}
                
                    <Stack.Screen name="home">
                      {props => <Home {...props} handleLoggedIn={handleLoggedIn} />}
                    </Stack.Screen>
       
                   {/*  About 40 more Stack Screens   */}
                
                  </Stack.Navigator>
                </View>
                </KeyboardAvoidingView>
              </PaperProvider>
            </ApplicationProvider>
          </RecoilRoot>
        </ApolloProvider>
      </NavigationContainer>
      </ErrorBoundary>
    )
  }
 catch(error){
    return(<ErrorPrompt code={error} />)
  }

I apologize for the amount of code, but my primary question is, does the order of the wrapping components matter? I know I need my NavContainer, ErrorBoundary, and RecoilRoot wrapping all of the pages, but do the orders of these matter? Because the code I have about was working perfectly until I added a mutation to the ErrorPrompt Component. The new ErrorPrompt looked like this...

const ErrorPrompt = (props) => {

    useEffect(() => {
      sendErrorEmail({
        variables: {
          errorCode: props.error.toString()
        }
      })
    }, [])

    return(
      // The same return as before
    )
  }

After this addition, I was given the Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance error. The message isn't particularly helpful, as both everything is wrapped in AND I have a client passed in. Does anyone know the solution / if order of these wrappings matters, and it it does, what order it should be in?

1 Answers

I found the issue. It was not a matter of the order in which things were wrapped but rather that I had the declaration for the sendErrorEmail mutation OUTSIDE of a component that was wrapped with the Apollo Provider. I had it out floating in App.js, but when I moved the line to under ErrorPrompt = () => { the error was removed

Related