Apollo-client: Uncaught (in promise) Error: Must contain a query definition.

Created on 4 Apr 2017  ·  8Comments  ·  Source: apollographql/apollo-client

OS: Windows 10 Pro
apollo-client: "^1.0.0"
react-apollo: "^1.0.0-rc.3"

Intended outcome:
GraphQL mutation to fire an update.

Actual outcome:
An Uncaught (in promise) Error: Must contain a query definition. is issued. See attached image.

How to reproduce the issue:
Initiating an onClick event causes the error to be issued.

My code is as follows:

import { gql, withApollo } from 'react-apollo';
import ApolloClient from 'apollo-client';

const Photo = React.createClass({

  incrementPostLikesQuery(idVal, incVal) {
    this.props.client.query({
      query: gql`
        mutation ($id: ID!, $count: Int) {
          updatePosts (id: $id, likes: $count) {
            id
            likes
          }
        }
      `,
      variables: {
        "id": idVal,
        "count": incVal
       },
    });
  },

  render() {
    const { post, i} = this.props;

    return (
      <figure key={i} className="grid-figure">
        <div className='grid-photo-wrap'>
          <Link to={`/view/${i}`}>
            <img className='grid-photo' src={post.displaysrc} alt={post.caption} />
          </Link>
          <CSSTransitionGroup transitionName="like" transitionEnterTimeout={500} transitionLeaveTimeout={500}>
            <span key={post.likes} className="likes-heart">{post.likes}</span>
          </CSSTransitionGroup>
        </div>
        <figcaption>
          <p>{post.caption}</p>
          <div className="control-buttons">
            <button onClick={this.incrementPostLikesQuery.bind(null, post.id, 1)} className="likes">&hearts; {post.likes}</button>
            <Link to={`/view/${i}`} className="button">
              <span className="comment-count">
                <span className="speech-bubble"></span> {(post.comments ? Object.keys(post.comments).length : 0)}
              </span>
            </Link>
          </div>
        </figcaption>
      </figure>
    )
  }
});

Photo.propTypes = {
  client: React.PropTypes.instanceOf(ApolloClient).isRequired,
}
const PhotoWithApollo = withApollo(Photo);

export default PhotoWithApollo;

query-definition-error

Most helpful comment

FTR the issue here is calling .query() with a mutation. I think the error could be more helpful.

All 8 comments

@TheoMer Your mutation needs to have a name, e.g. mutation Blah (id: Int!) { ...

I'm not sure that's the issue, but it kind of jumps out at me. If it isn't, feel free to reopen the issue.

@helfer Many thanks for your response. Unfortunately that did not resolve the issue.

FTR the issue here is calling .query() with a mutation. I think the error could be more helpful.

@TheoMer any reason why you aren't using graphql from react-apollo? It has the same interface for mutations / queries / subscriptions to help prevent issues like this

@jbaxleyiii I'm using gql because I needed to retrieve data only on the onClick event, hence the use of withApollo.

Many thanks All

I went through same error message, using .mutate() solved this.

Not using react-apollo since It's running in a crawler.

@TheoMer, using .mutate() and changing the following line from:

query: gql`

to:

mutation: gql`

worked for me!

I was having same issue, same cause, when trying to write some functional tests for my graphql server (hit real endpoints & data, test everything.) I wrote this helper for my functional-tests that might be useful to others:

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import gql from 'graphql-tag'
import fetch from 'node-fetch'

const GRAPHQL_ENDPOINT = process.env.GRAPHQL_ENDPOINT || 'http://localhost:3000/graphql'
const httpLink = createHttpLink({ uri: GRAPHQL_ENDPOINT, fetch })

export const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache()
})

export const query = (query, variables) => client.query({query: gql(query), variables})
export const mutate = (mutation, variables) => client.mutate({mutation: gql(mutation), variables})

Here is some example usage (in jest):

/* global describe, it, expect */

import { generate as shortid } from 'shortid'
import { mutate, query } from './graphql'

const email = `${shortid() + shortid()}@test.com`

describe('auth', () => {
  describe('Mutation.signup', () => {
    it('should allow signup', async () => {
      const s = await mutate(`mutation Signup {
        signup(
          email: "${email}",
          password: "password",
          name: "Test User"
        ){
          user {
            id
          }
        }
      }`)
      expect()
    })
  })

  describe('Query.me', () => {
    it('should not allow user to get info without a token', async () => {
      try {
        const m = await query(`query Me {
          me {
            id
          }
        }`)
      } catch (e) {
        expect(e.message).toEqual('GraphQL error: Login is required for me.')
      }
    })
  })
})
Was this page helpful?
0 / 5 - 0 ratings