Search code examples
graphqlsyntax-errorapollo

Suppress GraphQL: Syntax Error in VS Code when using template string


FYI: There are a ton of other posts concerning GraphQL Syntax Error in VS Code. I read many of them, but did not find anything relevant to this. My apologies if I missed it in the similar questions.

Environment:

I have a component that uses the useQuery hook. The query is retrieved from another query and comes in via a variable typed as string In order for the useQuery to correctly use the graphql query, it has first has to be made into a DocumentNode for which I use gql from graphql-tag npm package. The resulting code snippet looks like:

...
const PREPARED_QUERY = useMemo(() => gql`${query}`, [query])
const data = useQuery(PREPARED_QUERY, queryOptions)
...

This is working code, but the Apollo GraphQL extension throws a warning on this line:

Syntax Error: Unexpected <EOF>.GraphQL: Syntax

I understand this is because it is checking the query string to ensure that it is properly formatted and it does not understand the template string "hack".

Questions:

  1. Can this be silences with some form of ignore comment?
  2. If not, Is there any way to form this to make this template string pass the syntax check?

Solution

  • Looks like a known issue with the vscode extension - without a known solution :) https://github.com/graphql/vscode-graphql/issues/137 .

    Workaround

    Since gql is just a function, you can call it directly, so that the extension won't try to parse it and stop complaining.

    gql(query)
    

    Explanation on why it works

    If we take a look at tagged templates docs, we'll see that it's a regular function that takes the array of static string pieces as the first argument, and interpolated expressions as the remaining arguments. So when we do

    gql`some content`
    

    it translates to the following function call:

    gql(["some content"]) // a single argument, because there is no interpolations here
    

    Also this gql function has special code inside that allows to pass a plain string as the first arg (probably to support old JS where no template tags existed)