0

I'm using apollo within my vue.js application, I'm currently trying to remove an object by running a mutation, here is the code :

this.$apollo.mutate({
        mutation: require("../graphql/deleteTag.gql"),
        variables: {
          id: idToDelete,
        },
        update: (store, { data: { delete_tags } }) => {
          if (delete_tags.affected_rows) {
            const data = store.readQuery({
              query: require("../graphql/fetchDevices.gql"),
            });
            data.device_id_to_tag_id = data.device_id_to_tag_id.filter((x) => {
              return x.id != tag.device_id_to_tag_id.id;
            });
            store.writeQuery({
              query: require("../graphql/fetchDevices.gql"),
              data,
            });
          }
        },
      });

And my deleteTag.gql file :

mutation delete_tags($id: Int!){
  delete_extras_taggeditem(where: { id: { _eq: $id } }) {
    affected_rows
  }
}

But when I run this the following error appears :

enter image description here

I don't really know what's going on because I followed the Hasura vue.js documentation... Thanks in advance for your help !

ryuzak1
  • 234
  • 3
  • 14
  • 1
    Perhaps try a little less destructuring and check the values of your arguments. Eg `update: (state, thing) => { console.log(JSON.stringify(thing)) }`. What does that second argument look like? – Phil Oct 08 '20 at 08:26
  • In fact you're righ delete_tags wasn't the correct object name, but know I found the correct one that in fact contains an affected_rows field that is equal to 1, the console.log of this affected_rows shows undefined so it doesn't enter the if condition – ryuzak1 Oct 08 '20 at 09:12

2 Answers2

0

I believe you are missing optimisticResponse parameter in mutate. the "update" function takes 2 passes - first with data from optimisticResponse, and then the data from the actual mutation response.

e.g. something like...

this.$apollo.mutate({
        mutation: require("../graphql/deleteTag.gql"),
        variables: {
          id: idToDelete,
        },
        optimisticResponse: {
          delete_extras_taggeditem: {
              __typename: 'extras_taggeditem',
              id: -1,
              affected_rows
          }
        },
        update: (store, { data: { delete_extras_taggeditem } }) => {
          if (delete_extras_taggeditem.affected_rows) {
            const data = store.readQuery({
              query: require("../graphql/fetchDevices.gql"),
            });
            data.device_id_to_tag_id = data.device_id_to_tag_id.filter((x) => {
              return x.id != tag.device_id_to_tag_id.id;
            });
            store.writeQuery({
              query: require("../graphql/fetchDevices.gql"),
              data,
            });
          }
        },
      });

https://apollo.vuejs.org/guide/apollo/mutations.html#server-side-example

Also, generally speaking I would always return id in your responses back for any level of resource. Apollo relies on __typename + id to maintain and manipulate its cache.

avimoondra
  • 886
  • 5
  • 9
  • Thanks for your answer but delete_tags.affected_rows is set to 1 when I console log the delete_tags object but when I console log delete_tags.affected_rows its undefined so the If condition doesn't run... – ryuzak1 Oct 09 '20 at 08:21
  • I'd try this approach again (don't destructure) - https://stackoverflow.com/questions/64258496/cannot-read-property-affected-rows-of-undefined-when-trying-to-run-an-hasura-m/64264749?noredirect=1#comment113629363_64258496 And agree it'd look more like {data: delete_extras_taggeditem: {...}} given how Hasura structures the response based on the field, not query name. – avimoondra Oct 09 '20 at 14:13
0

You can specify the name of the returned key in graphql if you want your result data to be called just delete_extras instead of delete_extras_taggeditem:

mutation delete_tags($id: Int!){
  delete_extras: delete_extras_taggeditem(where: { id: { _eq: $id } }) {
    affected_rows
  }
}

but right now, you query do not return you a

kigiri
  • 2,952
  • 21
  • 23
  • delete_extras_taggeditem.affected_rows is undefined anyway even with optimistic response... – ryuzak1 Oct 09 '20 at 13:11
  • it is because the `update` function gets called twice. without optimisticResponse provided the client doesn't know how to update the object in cache (until the real response comes back) – avimoondra Oct 09 '20 at 14:14