React-apollo: How to use updateQueries?

Created on 5 Sep 2016  路  6Comments  路  Source: apollographql/react-apollo

I am trying to update my props.data after a mutation is successfully sent. However, I don't understand how to use updateQueries correctly.

I tried to set it in the options of the HOC:

export default graphql(gql`
    mutation($item: ItemInputType!) {
        item(item: $item) {
            id
        }
    }
`, {
    options: (ownProps) => ({
        forceFetch: true,
        updateQueries: {
            console.log('not called...');
        }
    }),
})(MyComponent)

and also in the call of the mutation method:

this.props.mutate({
    variables: { item: { id, featuredCategoryID }},
    updateQueries: {
        console.log('not called...');
    }
})

However, non of this worked. Is this a bug, or am I doing it wrong?

Most helpful comment

Which version are you using? Does mutation actually work and you get a valid GraphQL response? I think that if there are errors, updateQueries wont be called.

Anyway, it's hard to tell from your example what's wrong, so I'm posting my code that works 100%

import React, { Component, PropTypes } from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

class AddGallery extends Component {...}

const CREATE_GALLERY = gql`
  mutation createGallery($name: String!, $description: String) {
    createGallery(name: $name, description: $description) {
      id
      name
      slug
      description
      images {
        id
        slug
        name
        description
      }
    }
  }
`

const withCreateGallery = graphql(CREATE_GALLERY, {
  name: 'createGallery',
  options: {
    updateQueries: {
      galleries: (prev, { mutationResult, queryVariables }) => {
        return {
          galleries: [...prev.galleries, mutationResult.data.createGallery],
        }
      }
    }
  }
})

export default withCreateGallery(AddGallery)

All 6 comments

Which version are you using? Does mutation actually work and you get a valid GraphQL response? I think that if there are errors, updateQueries wont be called.

Anyway, it's hard to tell from your example what's wrong, so I'm posting my code that works 100%

import React, { Component, PropTypes } from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

class AddGallery extends Component {...}

const CREATE_GALLERY = gql`
  mutation createGallery($name: String!, $description: String) {
    createGallery(name: $name, description: $description) {
      id
      name
      slug
      description
      images {
        id
        slug
        name
        description
      }
    }
  }
`

const withCreateGallery = graphql(CREATE_GALLERY, {
  name: 'createGallery',
  options: {
    updateQueries: {
      galleries: (prev, { mutationResult, queryVariables }) => {
        return {
          galleries: [...prev.galleries, mutationResult.data.createGallery],
        }
      }
    }
  }
})

export default withCreateGallery(AddGallery)

ok, I can't really see a difference.

  • react-apollo: 0.4.7
  • apollo-client: 0.4.14
class AppRoute extends React.Component {
    render() {
        return <button onClick={() => this.props.mutate({
                        variables: { item: { id: '...', spotlight: true }},
                    })}>
                Test
            </button >;
    }
}

const withMutation = graphql(gql`
    mutation($item: ItemInputType!) {
        item(item: $item) {
            id
        }
    }
`, {
    options: {
        updateQueries: {
            spotlightItems: (prev, { mutationResult, queryVariables }) => {
                console.log('not called');
            }
        }
    },
})(AppRoute);

export default graphql(gql`
    query($search: String, $status: ItemStatusOutputType, $aspectRatio: AspectRatioOrUncropped!) {
        items(search: $search, status: $status) {
            ...itemSpotlight
            categories {
                id
            }
        }
        spotlightItems: items(status: $status, spotlight: true) {
            ...itemSpotlight
        }
        categories {
            id,
            title,
            color,
            featuredItems {
                ...itemSpotlight
            }
        }
    }
`, { options: ownProps => ({
    fragments: discoverItemFragment,
    variables: {
        search: ownProps.params.search,
        status: 'LIVE',
        aspectRatio: 'SQUARE',
    },
})})(withMutation);

The mutation seems to work fine. The data is modified on the server, when I add .then(...) it is also called.

The only difference I see is that you pass a function as the options parameter.

@danielbuechele I think your query is unnamed (query(...), rather than query NAME(...)).

Instead you are trying to update a top-level field on the query, which isn't supported (for one thing you could have multiple queries that select something called spotlightItems with different parameters).

Ok, I got it working with naming my query like this:

query test1($search: String, $status: ItemStatusOutputType, $aspectRatio: AspectRatioOrUncropped!)

and then

updateQueries: {
    test1: (prev, { mutationResult }) => {}
}

But how would I split my query into multiple queries?

@danielbuechele I mean you could use multiple graphql wrappers (or the new compose support, I'm not sure it's documented yet).

But otherwise reaching into the query to update a single field is pretty standard.

Was this page helpful?
0 / 5 - 0 ratings