Proper way to setup AWSAppSyncClient, Apollo & React
Asked Answered
Z

3

5

I've been having issues getting started with React, Apollo, and AWS-AppSync. I can't resolve this error message:

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

I'm using the updated packages of @apollo/react-hooks and aws-appsync.

My current setup looks like this.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import config from './aws-exports';
import AWSAppSyncClient from 'aws-appsync';
import { ApolloProvider } from '@apollo/react-hooks';

const client = new AWSAppSyncClient({
    url: config.aws_appsync_graphqlEndpoint,
    region: config.aws_appsync_region,
    auth: {
        type: config.aws_appsync_authenticationType,
        apiKey: config.aws_appsync_apiKey
    }
});

ReactDOM.render(
    <ApolloProvider client={client}>
        <React.StrictMode>
            <App />
        </React.StrictMode>
    </ApolloProvider>,
    document.getElementById('root')
);

And I have a function that makes a query that looks like this:

import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';

const Flavors = () => {

    const GET_FLAVORS = gql`
        query listAll {
            items {
                name,
                image
            }
        }
    `;

    const { loading, error, data } = useQuery(GET_FLAVORS);

    if(loading) return <p>loading...</p>
    if(error) return <p>Something went wrong...</p>

    return (
        <div>
        {
            data.listIceCreamTypes.items.map(type => {
                return <div key={type.name}>
                    <img src={type.image} alt={type.name} />
                    <h1>{type.name}</h1>
                </div>
            })
        }
        </div>
    )
}

export default Flavors;

I've gone through various solutions described in https://github.com/apollographql/react-apollo/issues/3148 such as adding:

"resolutions": {
    "apollo-client": "2.6.3"
 }

to package.json. Then re-running npm install and restarting the server.

Nothing seems to solve my issues.

Edit** Here's a repo to reproduce the problem: https://github.com/Rynebenson/IceCreamQL

Zwart answered 22/3, 2020 at 20:4 Comment(0)
S
11

I already answered this on other related question here on stackoverflow..

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';

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

Spade answered 22/4, 2020 at 21:17 Comment(1)
I saw your post on given link but using the same code in my project. Is there anything else to be done to get it working in production mode?Overpraise
S
0

Wanted to post my experience that is a more recent. The accepted answer is still correct. aws-appsync uses outdated packages which conflict with the newest versions of the apollo client.

import React from 'react';
import PropTypes from 'prop-types';

// Apollo Settings
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
import { ApolloLink } from 'apollo-link';

// AppSync
import { Auth } from 'aws-amplify';
import { createAuthLink } from 'aws-appsync-auth-link';
import { createHttpLink } from 'apollo-link-http';
import awsconfig from 'assets/lib/aws-exports';

// jwtToken is used for AWS Cognito.
const client = new ApolloClient({
  link: ApolloLink.from([
    createAuthLink({
      url: awsconfig.aws_appsync_graphqlEndpoint,
      region: awsconfig.aws_appsync_region,
      auth: {
        type: awsconfig.aws_appsync_authenticationType,
        apiKey: awsconfig.aws_appsync_apiKey,
        jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken(),
      },
    }),
    createHttpLink({ uri: awsconfig.aws_appsync_graphqlEndpoint }),
  ]),
  cache: new InMemoryCache(),
});

const withApollo = ({ children}) => {
  return <ApolloProvider client={client}><App /></ApolloProvider>;
};

withApollo.propTypes = {
  children: PropTypes.object,
  authData: PropTypes.object,
};

export default withApollo;

Package.json

"@apollo/client": "^3.3.15",
"@apollo/react-hooks": "^4.0.0",
"apollo-link": "^1.2.14",
"apollo-link-http": "^1.5.17",
"aws-amplify": "^3.3.27",
"aws-amplify-react-native": "^4.3.2",
"aws-appsync-auth-link": "^3.0.4",
Seventeen answered 23/4, 2021 at 15:12 Comment(1)
Hi there. I have implemented the same code but it only seem to be working for development mode. Is there any other configuration for production that needs to be done?Overpraise
P
0

You must initialize appsync like the following method.

const graphqlClient = new appsync.AWSAppSyncClient({
url: graphqlEndpoint,
region: process.env.AWS_REGION,
auth: {
    type: 'AWS_IAM',
    credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
        sessionToken: process.env.AWS_SESSION_TOKEN
    }
},
disableOffline: true

});

Pisistratus answered 1/11, 2021 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.