9

I have my project setup to import .graphql files. That works fine. But my problem is I don't know how to define a query in a .graphql file and import that into a component to use with react-apollo's <Query ...> component.

In this example the author defines the query in JavaScript variable using gql:

import gql from "graphql-tag";
import { Query } from "react-apollo";

const GET_DOGS = gql`
  {
    dogs {
      id
      breed
    }
  }
`;

const Dogs = ({ onDogSelected }) => (
  <Query query={GET_DOGS}>
    {({ loading, error, data }) => {
      if (loading) return "Loading...";
      if (error) return `Error! ${error.message}`;

      return (
        <select name="dog" onChange={onDogSelected}>
          {data.dogs.map(dog => (
            <option key={dog.id} value={dog.breed}>
              {dog.breed}
            </option>
          ))}
        </select>
      );
    }}
  </Query>
);

But, I instead want to store that query in a separate .graphql file and import it into the component.

Here's what I have tried in my project. Here is a component, and I attempt to import UserQuery from my schema.

import React from 'react'
import { Query } from 'react-apollo'

import { UserQuery } from '../api/schema.graphql'

export default () => 
    <Query query={ UserQuery }>
        {({ loading, error, data }) => {
            if (loading) return 'Loading...'
            if (error) return `Error! ${error.message}`
            return
                <ul>
                    {data.users.map(name => <li>{name}</li>)}
                </ul>
        }}
    </Query>

Here is the schema:

# schema.graphql

query UserQuery {
    user {
        name,
        age,
        gender        
    }
}

type User {
    name: String,
    age: Int,
    gender: String
}

type Query {
    say: String,
    users: [User]!
}

When I try to import and use I get an error:

modules.js?hash=e9c17311fe52dd0e0eccf0d792c40c73a832db48:28441 Warning: Failed prop type: The prop query is marked as required in Query, but its value is undefined.

How can I import queries this way?

BugHunterUK
  • 8,346
  • 16
  • 65
  • 121
  • The message you posted is just a warning regarding Query component's proptypes. This won't break your build, but it is advisable to fix it. Your problem is caused by something else. – Capaj Apr 14 '18 at 09:52
  • The Query component isn't receiving the `query`. It's undefined. `UserQuery` is not being imported. – BugHunterUK Apr 14 '18 at 10:40

1 Answers1

11

To import GraphQL queries you need a specific loader. When you are using webpack you can for example use graphql-tag/loader from graphql-tag. It will transform your queries to JavaScript modules so that they can be imported by webpack. Furthermore you should not put your schema and your query into the same file. I don't think the GraphQL loader is made for exporting schema definition language (even though it might be able to parse it since the GraphQL-JS parser parses both). Create a file specifically for the query. If there is only one query in the file you can import the query as default

import UserQuery from 'UserQuery.graphql';

If there are multiple definitions, e.g. fragments, mutations, etc. they are exported as named exports with their name.

This makes everything a bit more complicated than it should with the GraphQL loader. A tip for debugging modules: You can console.log or inspect the contents of a module.

import * as file from 'UserQuery.graphql';
console.log(file);

This will print the object to your (browser) console and you can see the exported names as keys in the object.

Herku
  • 7,198
  • 27
  • 36
  • 1
    On the server-side, if you don't want to use webpack, you can use `babel` along with `babel-plugin-inline-import`, which will allow you to import your schema as text – Katie Apr 17 '18 at 20:11