0
votes

I'm working on a NextJS project using Strapi as CMS, with GraphQL plugin and Apollo as GraphQL client. My issue is related to Apollo Hooks. I'm trying to use query fragments with the new useQuery hook, with no success.

Testing my query on GraphQL playground, everything is ok - data are returned correctly, as shown here:

GraphQL test

But, by porting this one inside the project, it generates a 500 network error in Apollo client like this:

Error while running `getDataFromTree` { Error: Network error: Response not successful: Received status code 500
    at new ApolloError (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:92:26)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:1587:34
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2007:15
    at Set.forEach (<anonymous>)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2005:26
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2003:20)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:1482:29
    at process._tickCallback (internal/process/next_tick.js:68:7)
  graphQLErrors: [],
  networkError:
   { ServerError: Response not successful: Received status code 500
       at Object.exports.throwServerError (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-link-http-common/lib/index.js:23:17)
       at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-link-http-common/lib/index.js:48:21
       at process._tickCallback (internal/process/next_tick.js:68:7)
     name: 'ServerError',
     response:
      Response {
        size: 0,
        timeout: 0,
        [Symbol(Body internals)]: [Object],
        [Symbol(Response internals)]: [Object] },
     statusCode: 500,
     result: { errors: [Array] } },
  message:
   'Network error: Response not successful: Received status code 500',
  extraInfo: undefined }

Here's my implementation:

Apollo

// Module Start
// Apollo Client
// JS imports
import {
  ApolloClient
} from 'apollo-client';
import {
  InMemoryCache
} from 'apollo-cache-inmemory';
import {
  HttpLink
} from 'apollo-link-http';
import {
  onError
} from 'apollo-link-error';
import {
  ApolloLink
} from 'apollo-link';
import fetch from 'isomorphic-unfetch';

let apolloClient = null;

/**
 * @description Client definition
 * @author Luca Cattide
 * @date 2019-06-27
 * @param {*} initialState
 * @return {object}
 */
function create(initialState) {
  const isBrowser = typeof window !== 'undefined';

  // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
  return new ApolloClient({
    connectToDevTools: isBrowser,
    // Disables forceFetch on the server (so queries are only run once)
    ssrMode: !isBrowser,
    link: ApolloLink.from([
      onError(({
        graphQLErrors,
        networkError
      }) => {
        if (graphQLErrors)
          graphQLErrors.forEach(({
              message,
              locations,
              path
            }) =>
            console.log(
              `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
            ),
          );
        if (networkError) console.log(`[Network error]: ${networkError}`);
      }),
      new HttpLink({
        // Server URL (must be absolute) - Es. https://api.graph.cool/simple/v1/cixmkt2ul01q00122mksg82pn
        // TODO: Change to proper url in production
        uri: 'http://localhost:1337/graphql',
        // Additional fetch() options like `credentials` or `headers`
        credentials: 'same-origin',
        // Use fetch() polyfill on the server
        fetch: !isBrowser && fetch
      })
    ]),
    cache: new InMemoryCache().restore(initialState || {}),
  });
}

/**
 * @description Client initialization
 * @author Luca Cattide
 * @date 2019-06-27
 * @export
 * @param {*} initialState
 * @return {object}
 */
export default function initApollo(initialState) {
  // Make sure to create a new client for every server-side request so that data
  // isn't shared between connections (which would be bad)
  if (typeof window === 'undefined') {
    return create(initialState);
  }

  // Reuse client on the client-side
  if (!apolloClient) {
    apolloClient = create(initialState);
  }

  return apolloClient;
}
// Module End

Query

// Module Start
// JS imports
import gql from 'graphql-tag';
import Pages from './fragments/pages';

// Queries
// Page
const PAGE_QUERY = gql`
  query Pages($where: JSON, $isHome: Boolean!) {
    pages(where: $where) {
      ...PagesFragmentsPage
      ...PagesFragmentsHome @include(if: $isHome)
    }
  }

  ${Pages.fragments.page}
  ${Pages.fragments.home}
`;

// Module export
export default PAGE_QUERY;
// Module end

Fragments

// Module Start
// JS imports
import gql from 'graphql-tag';

// Fragments
const Pages = {};

// Pages
Pages.fragments = {
  page: gql`
    fragment PagesFragmentsPage on Page {
      id
      name_en
      keywords_en
      description_en
    }
  `,
  home: gql`
    fragment PagesFragmentHome on Page {
      headline_en
      cta_en
      cta_two_en
      cta_three_en
      cta_four_en
      cta_five_en
      summary_title_en
      summary_en
      headline_two_en
      headline_three_en
      headline_four_en
      headline_five_en
      section_title_en
      indicators {
        id
        value
        label_en
      }
      testimonials {
        id
        name
        quote_en
      }
    }
  `,
};

// Module export
export default Pages;
// Module End

NextJS Page

// Module Start
// Home
// Various imports...
// JS imports
import dynamic from 'next/dynamic'
import {useQuery} from '@apollo/react-hooks'
import PAGE_QUERY from '../backend/queries/pages'

const ErrorDb = dynamic(() =>
  import('../components/ErrorDb')
)
// Main
const Index = ({origin, pathname}) => {
  const {loading, error, data} = useQuery(PAGE_QUERY, {
    variables: {
      where: {
        name_en: 'Home'
      },
      isHome: true
    }
  });
  const {pages} = data;

  // Exception check
  if (error) {
    return <ErrorDb />
  }
  // DB fetching check
  if (loading) {
    return null;
  }

  return (
    <>
      // Implementation...
    </>
  );
}

// Module export
export default Index
// Module End

What is generating the error? This is my first project by using these technologies, so probably I'm missing something.

Thanks in advance for the help.

1

1 Answers

2
votes

Issue solved. It was caused by a stupid syntax error inside PagesFragmentHome fragment declaration. By replacing it with:

PagesFragmentsHome

Everything works fine.