5

After I'm sending a createMessage mutation in my app, I want to update the local ApolloStore using updateQueries.

My setup looks as follows:

const ChatWithAllMessages = graphql(allMessages, {name: 'allMessagesQuery'})(Chat)
export default graphql(createMessage, {
   props({ownProps, mutate}) {
    return {
      createMessageMutation(text, conversationId) {
        return mutate({
          variables: { text, conversationId },
          updateQueries: {
            allConversations: (previousState, {mutationResult}) => {
              console.log('Chat - did send mutation for allConversationsQuery: ', previousState, mutationResult)
              return ...
            }
          }
        })
      }
    }
  }
})(ChatWithAllMessages)

I'm calling the createMessageMutation in my code like so:

_onSend = () => {
  this.props.createMessageMutation(this.state.message, this.props.conversationId)
}

With this setup I would expect the function that I specified in the value for updateQueries to be executed, however, that doesn't seem to happen (the logging statement is never printed).

For reference, this is what the allConversation query in the ApolloStore looks like:

enter image description here

Also, this how it's defined in my JS code:

const findConversations = gql`
    query allConversations($customerId: ID!) {
        allConversations(filter: {
          customer: {
            id: $customerId
          }
        }){
            id
            updatedAt
            slackChannelName
            agent {
                id
                slackUserName
            }
            messages(last: 1) {
                id
                text
                createdAt
            }
        }
    }
`

Does anyone spot what I'm doing wrong?

nburk
  • 22,409
  • 18
  • 87
  • 132

1 Answers1

3

If you use the query and the mutation in the same component you could compose the mutation and the query. Like in solution 1.

If you do not need the mutation in the component you could add the named query (Since version 0.11.1 / hereby the related query has to be called at least once else the apollo store does not know about the query) or you could add the query itself to updateQueries.

1) Component which uses mutation and query

import { compose } from 'react-apollo';

...

import findConversationsQuery from './.../findConversationsQuery';

...

const ChatWithAllMessages = compose(
    graphql(allMessages, {name: 'allMessagesQuery'}),
    findConversationsQuery,
    graphql(createMessage, {
      props({ ownProps, mutate }) {
        return {
          createMessageMutation(text, conversationId) {
            return mutate({
              variables: {
                text,
                conversationId
              },
              updateQueries: {
                allConversations: (previousState, {
                  mutationResult
                }) => {
                  console.log('Chat - did send mutation for allConversationsQuery: ', previousState, mutationResult)
                  return ...
                }
              }
            })
          }
        }
      }
    })(Chat)

with the graphql query defined in the file, because you only want to have it instantiated once

import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

const findConversations = gql`
    query allConversations($customerId: ID!) {
        allConversations(filter: {
          customer: {
            id: $customerId
          }
        }){
            id
            updatedAt
            slackChannelName
            agent {
                id
                slackUserName
            }
            messages(last: 1) {
                id
                text
                createdAt
            }
        }
    }
`

const findConversationsQuery = graphql(findConversations, {
   name: "findConversationsQuery"
});

export default findConversationsQuery
Locco0_0
  • 3,420
  • 5
  • 30
  • 42
  • > The updateQuery functionality is only called when the view for the mutation holds the reference to the query. Do you have a reference for that statement? – marktani Mar 06 '17 at 17:16
  • It is not written directly like this in the documentation of apollo. When you read through the [updateQueries definition](http://dev.apollodata.com/react/cache-updates.html#updateQueries) there are two statements "We expose this mutation through a function prop that the CommentsPage component can call" and "The comments page itself is rendered with the following query". So i thought the query has to be in the props of the component. – Locco0_0 Mar 06 '17 at 17:32
  • referring to [this comment](https://github.com/apollographql/apollo-client/issues/1129#issuecomment-270677147) it sounds like that behaviour is a bug. Even though I'm not clear on the current agreement here. – marktani Mar 06 '17 at 17:38
  • Yes you're right, so maybe with version 0.11.1 it works without composing the query and the mutation – Locco0_0 Mar 06 '17 at 17:50
  • The mutation doesn't need to hold a reference to the query, it just needs to know the name of the query (not the JSvariable name, but the name given in the graphql query string, i.e. in "query (var1: String, ...){ ... "). UpdateQueries will only work if the named query was previously executed though, because otherwise Apollo Client isn't aware of the query. To circumvent that problem, you can provide a query + variables directly to updateQueries (instead of a query name). Could you update your answer accordingly? – helfer Mar 06 '17 at 19:22
  • > (not the JSvariable name, but the name given in the graphql query string, i.e. in "query (var1: String, ...){ ... ") Arg, I'm tripping over that every single time :P – marktani Mar 06 '17 at 21:43
  • I had to update the node package to a higher version than it also worked with just the named query – Locco0_0 Mar 07 '17 at 07:08