2

So, I'm testing subscriptions on Graphcool and would appreciate some clarification on how exactly they work.

I have a one to many relationship from Posts on Comments:

Schema

type Posts {
  caption: String!
  comments: [Comments!]! @relation(name: "PostsOnComments")
  createdAt: DateTime!
  displaysrc: String!
  id: ID!
  likes: Int
  updatedAt: DateTime!
}

type Comments {
  createdAt: DateTime!
  id: ID!
  posts: Posts @relation(name: "PostsOnComments")
  text: String!
  updatedAt: DateTime!
  user: String!
}

The subscription I run in Graphcool is as follows:

subscription CreatedDeletedComments {
 Comments(
    filter: {
      mutation_in: [CREATED, DELETED]
    }
  ) {
    mutation
    node {
      id
      user
      text
    }
  }
}

If I run the following in my React app, a created notification is fired:

    return this.props.client.mutate({
      mutation: gql`
        mutation createComment ($id: ID, $textVal: String!, $userVal: String!) {
          createComments (postsId: $id, text: $textVal, user: $userVal){
            id
            text
            user
          }
        }
      `,
      variables: {
        "id": postID,
        "textVal": textVal,
        "userVal": userVal
       },
      // forceFetch: true,
    })

But if I run the following, no deleted notification is fired:

    return this.props.client.mutate({
      mutation: gql`
        mutation removeComment ($id: ID!, $cid: ID!) {
          removeFromPostsOnComments (postsPostsId: $id, commentsCommentsId: $cid){
            postsPosts {
              id
              displaysrc
              likes
              comments {
                id
                text
                user
              }
            }
          }
        }
      `,
      variables: {
        "id": postID,
        "cid": commentID
       },
      // forceFetch: true,
    })

What am I overlooking here?

TheoG
  • 1,498
  • 4
  • 30
  • 54

1 Answers1

2

With the subscription

subscription CreatedDeletedComments {
    Comments(
    filter: {
      mutation_in: [CREATED, DELETED]
    }
  ) {
    mutation
    node {
      id
      user
      text
    }
  }
}

you are subscribing to comment nodes being created or deleted. However, with the mutation removeFromPostsOnComments, you are not deleting any comment nodes. Instead, you are only deleting the connection between a post and a comment.

You can adjust your mutation request to delete the comment entirely instead of disconnecting it from the post:

return this.props.client.mutate({
  mutation: gql`
    mutation removeComment ($cid: ID!) {
      deleteComment(id: $cid) {
        id
      }
    }
  `,
  variables: {
    "cid": commentID
   },
  // forceFetch: true,
})

If you don't want to delete the comment entirely but still want to hide it in your app, you could have a boolean field deleted that acts as a soft deletion marker.

Then you could subscribe to UPDATED comments instead of DELETED comments and check if the field deleted was updated. Refer to the docs for more information on how to do that with updatedFields.

Subscriptions for relations is also already part of our roadmap.

marktani
  • 7,578
  • 6
  • 37
  • 60
  • Perfect. The only issue I'm having with deleteComments, is in relation to my UI, reactive cache, not updating to reflect the change. How do I refactor updateQueries (See my updated question) to work with `this.props.client.mutate` (I'm triggering from an onClick event), as my root_query (as depicted in Apollo devTools), is `allPostses`? – TheoG Apr 06 '17 at 12:51
  • Could you post a separate question for that? In general, it seems that using `update` is recommended vs. using `updateQueries` nowadays anyway. – marktani Apr 06 '17 at 13:12
  • Sure. New question submitted. – TheoG Apr 06 '17 at 14:01
  • Is there a technical reason why removeFromPostsOnComments doesn't actually delete the comment node? – TheoG Apr 11 '17 at 18:08
  • There's a difference between removing the connection between two nodes (`removeFromPostsOnComments` in this case) and deleting a node. Sometimes you need one of the two, sometimes you need both. So having the atomic operations available makes sense and still allows you :) – marktani Apr 11 '17 at 19:32