Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

store.writeQuery On Mutation Only Takes Effect If optimisticResponse Provided #436

Closed
dsanders11 opened this issue Oct 29, 2018 · 5 comments
Labels

Comments

@dsanders11
Copy link

I struggled for a bit getting updates to the store to work in a reactive way. I could see that update on my $apollo.mutate was being called, and could poke the store and see that the value changed in there, but it wasn't updating the UI. This was for a simple case of adding an item to a list, like the standard Todo example.

Only after defining an optimisticResponse response on my $apollo.mutate did things work as expected. I don't see anything in the documentation about this being required. Is this a requirement, or a bug?

I still can't get the delete mutation working with update. Again, everything looks correct, but no UI update. Without the optimisticResponse, nothing visually happens, with it, there's a flash as the item is removed, then put back. The response from the server is simply a boolean, and the optimistic response value is true since I expect to to succeed. Switching that to false (so that it actually differs from the server response) has no effect. However, changing anything in the code and letting HMR refresh the code, then trying the delete again succeeds.

Any suggestions?

export default {
  data () {
    return {
      items: []
    }
  },
  methods: {
    async addItem () {
      const input = { name: 'Test' }

      try {
        await this.$apollo.mutate({
          mutation: ADD_ITEM_MUTATION,
          variables: { input },
          update: (store, { data: { addItem } }) => {
            const data = store.readQuery({ query: ITEMS_QUERY })
            data.items.push(addItem)
            store.writeQuery({ query: ITEMS_QUERY, data })
          },
          optimisticResponse: {
            __typename: 'Mutation',
            addItem: {
              __typename: 'Item',
              id: null,
              created: utils.currentTimestamp(),
              ...input
            },
          }
        })
      catch (err) {
        console.log(err)
      }
    },
    async deleteItem (item) {
      const itemId = item.id

      try {
        await this.$apollo.mutate({
          mutation: DELETE_ITEM_MUTATION,
          variables: { itemId },
          update: (store, { data: { deleteItem } }) => {
            // Update the list of items
            const data = store.readQuery({ query: ITEMS_QUERY })
            const idx = data.items.indexOf(item)

            if (idx) {
              data.items.splice(idx, 1)
              store.writeQuery({ query: ITEMS_QUERY, data })
            }
          },
          optimisticResponse: {
            __typename: 'Mutation',
            deleteItem: true
          }
        })
      } catch (err) {
        console.log(err)
      }
    }
  }
}
@Akryum
Copy link
Member

Akryum commented Oct 29, 2018

@flytedan
Copy link

flytedan commented Oct 30, 2018

I am also seeing this issue. Seems to not be limited to using the optimistic response though. The optimistic response always works, but sometimes it will revert back to the incorrect state. I am monitoring the data stored in the Apollo cache, and I see values are getting updated correctly, but the UI itself is not matching what is stored in the Apollo store.

So there is some weird disconnect (but only is certain scenarios) where the data provided by Vue Apollo does not match what is in the Apollo Store. I am still trying to pin down the exact reproducible steps are. Definitely a new problem. Been using Vue Apollo for about 6 months without this issue. I did update a fair number of packages, so also trying to filter down which package upgrades caused this issue.

UPDATE:
Seems like my problem is limited to updating data in queries that are 3+ levels deep in an object. 1st and 2nd level data seems to persist, but anything deeper than that seems to be reverted. Still trying to figure out the root cause.

@Akryum
Copy link
Member

Akryum commented Oct 30, 2018

If you follow my link, you will see it's an issue with recent versions of apollo-client and apollo-utilities.

@dsanders11
Copy link
Author

dsanders11 commented Oct 30, 2018

@Akryum, thanks for the link, and makes sense that it would be upstream. There's a comment there that apollo-client@2.4.5 fixes the issue, and it does for me, and I tested it in your reproduce CodeSandbox and it works there as well.

I did, however, notice that there's no need to do the store.writeQuery on delete, as it appears the result from store.readQuery is not a deep copy, so modifying the list via splice will immediately affect the store state.

So I guess bumping the apollo-client version in this project's package.json would close this issue?

@Akryum
Copy link
Member

Akryum commented Nov 8, 2018

It should be fixed in the latest apollo client related packages.

@Akryum Akryum closed this as completed Nov 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants