Cannot read property 'affected_rows' of undefined when trying to run an Hasura mutation

591 views Asked by At

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 !

2

There are 2 answers

2
kigiri On

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

2
avimoondra On

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.