Search code examples
reactjsgraphqlreact-apolloaws-amplifyaws-appsync

AWS AppSync + React-Apollo Query/useQuery raising exception this.currentObservable.query.getCurrentResult is not a function


I'm new to GraphQL/Apollo thing and I'm having a hard time to setup it with a React application.

I have a React component that loads a list from a GraphQL API built using Amplify/AppSync.

If I call manually to fetch the items, i.e:

    const videosData = await client.query({
      query: gql(queries.listVideos)
    });
    const videosItems = videosData.data.listVideos.items;
    setVideosData(videosItems);

Works like a charm. However, if I try to use Apollo Query component or useQuery hook, it raises the following error:

TypeError: this.currentObservable.query.getCurrentResult is not a function

If I just add the line to fetch the query using a hook it already gives me this error

the hook call:

const {loading, error, data, refetch} = useQuery(gql(queries.listVideos));

The called function raising the issue:

QueryData.getQueryResult
node_modules/@apollo/react-hooks/lib/react-hooks.esm.js:325
  322 |     called: true
  323 |   });
  324 | } else {
> 325 |   var currentResult = this.currentObservable.query.getCurrentResult();
      | ^  326 |   var loading = currentResult.loading,
  327 |       partial = currentResult.partial,
  328 |       networkStatus = currentResult.networkStatus,

The exact same problem happens if I use the <Query> component

Packages versions:

"aws-amplify": "^1.1.30",
"aws-amplify-react": "^2.3.10",
"aws-appsync": "^1.8.1",
"graphql-tag": "^2.10.1",
"react-apollo": "^3.0.1",

Any idea what I might be doing wrong and how to fix it?


Solution

  • As mentioned in other answer the problem is because aws-appsync is relying in an previous version apollo-client. Using resolutions is not the "cleaner" way to solve this problem as you're fixing a dependency version which is not fully compatible with this library.

    I strongly recommend you to create a custom apollo client for AWS AppSync this way:

    import { ApolloProvider } from '@apollo/react-hooks';
    import { ApolloLink } from 'apollo-link';
    import { createAuthLink } from 'aws-appsync-auth-link';
    import { createHttpLink } from 'apollo-link-http';
    import { AppSyncConfig } from '.aws-exports';
    import ApolloClient from 'apollo-client';
    import { InMemoryCache } from "apollo-cache-inmemory";
    
    const url = AppSyncConfig.graphqlEndpoint;
    const region = AppSyncConfig.region;
    const auth = {
      type: AppSyncConfig.authenticationType,
      apiKey: AppSyncConfig.apiKey
    };
    const link = ApolloLink.from([
       createAuthLink({ url, region, auth }), 
       createHttpLink({ uri: url })
    ]);
    const client = new ApolloClient({
      link,
      cache: new InMemoryCache()
    });
    
    const WithProvider = () => (
      <ApolloProvider client={client}>
        <App />
      </ApolloProvider>
    )
    
    export default WithProvider
    

    I also created a more detailed post on medium