1

Note: As the process for handling mutation/query/cache updates is now addressed by update, I am no longer using uodateQueries, making this question no longer relevant.

So, I have a one to many relationship from Posts to Comments:

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

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

and a Root_Query, as depicted in Apollo devTools (See attached image), of:

  query allPostsCommentsQuery {
    allPostses {
      id
      displaysrc
      caption
      likes
      comments {
        id
        posts {
          id
        }
        text
        user
      }
    }
  }

Running Add_Comment_Mutation or Remove_Comment_MutationNew:

export const Add_Comment_Mutation = gql`
  mutation createComment ($id: ID, $textVal: String!, $userVal: String!) {
    createComments (postsId: $id, text: $textVal, user: $userVal){
      id
      text
      user
    }
  }
`;

export const Remove_Comment_MutationNew = gql`
  mutation removeComment ($cid: ID!) {
    deleteComments(id: $cid) {
      id
    }
  }
`;

does not correctly update reactive cache, and thus my UI does not correctly reflect any additions/deletions of comments, which are triggered by onClick events.

How do I get updateQueries to correctly work with this.props.client.mutate, as current attempt generates "Error: update(): expected target of $unshift to be an array; got undefined." errors (See below):

import { graphql, gql, withApollo } from 'react-apollo';
import ApolloClient from 'apollo-client';
import update from 'immutability-helper';
import { Add_Comment_Mutation, Remove_Comment_MutationNew } from '../graphql/mutations';

const Comments = React.createClass({

  removeCommentMutation(commentID) {
    console.log ("Remove_Comment_MutationNew is called for id=" + commentID);
    const { client } = this.props;

    return this.props.client.mutate({
      mutation: Remove_Comment_MutationNew,
      variables: {
        "cid": commentID,
      },
      updateQueries: {
        allPostsCommentsQuery: (previous, { mutationResult }) => {
          console.log("Previous = " + previous);
          const newComment = mutationResult.data.removeComment;

          return update(previous, {
            allPostses: {
              comments: {
                $set: [newComment],
              },
            },
          });
        }
      }
    })
    .then(({ data }) => {
      console.log('got data', data.deleteComments.id);
    })
    .catch(this.handleSubmitError);
  },

Generated error:

Note - The issue appears to be with

const newComment = mutationResult.data.removeComment;

which is being returned as 'undefined', instead of as an object.

Error: update(): expected target of $unshift to be an array; got undefined.
    at invariant (http://localhost:7770/static/bundle.js:23315:16)
    at invariantPushAndUnshift (http://localhost:7770/static/bundle.js:71469:4)
    at Object.$unshift (http://localhost:7770/static/bundle.js:71430:6)
    at update (http://localhost:7770/static/bundle.js:71408:36)
    at update (http://localhost:7770/static/bundle.js:71410:32)
    at update (http://localhost:7770/static/bundle.js:71410:32)
    at allPostsCommentsQuery (http://localhost:7770/static/bundle.js:54181:52)
    at http://localhost:7770/static/bundle.js:39552:87
    at tryFunctionOrLogError (http://localhost:7770/static/bundle.js:39457:17)
    at http://localhost:7770/static/bundle.js:39552:44
    at Array.forEach (native)
    at data (http://localhost:7770/static/bundle.js:39536:47)
    at apolloReducer (http://localhost:7770/static/bundle.js:39789:24)
    at combination (http://localhost:7770/static/bundle.js:23011:30)
    at computeNextEntry (<anonymous>:2:27051)
    at recomputeStates (<anonymous>:2:27351)
    at <anonymous>:2:30904
    at Object.dispatch (http://localhost:7770/static/bundle.js:22434:23)
    at dispatch (<anonymous>:2:31397)
    at http://localhost:7770/static/bundle.js:41210:40
    at http://localhost:7770/static/bundle.js:73223:17
    at Object.dispatch (http://localhost:7770/static/bundle.js:23158:19)
    at http://localhost:7770/static/bundle.js:40597:30
tryFunctionOrLogError @ apollo.umd.js:1410
(anonymous) @ apollo.umd.js:1501
data @ apollo.umd.js:1485
apolloReducer @ apollo.umd.js:1738
combination @ combineReducers.js:132
computeNextEntry @ VM77918:2
recomputeStates @ VM77918:2
(anonymous) @ VM77918:2
dispatch @ createStore.js:179
dispatch @ VM77918:2
(anonymous) @ apollo.umd.js:3159
(anonymous) @ index.js:14
dispatch @ applyMiddleware.js:45
(anonymous) @ apollo.umd.js:2546

enter image description here

TheoG
  • 1,498
  • 4
  • 30
  • 54

1 Answers1

0

I don't think you can concatenate mutations. At least the error message tells so. It should be something like:

...

removeCommentMutation(commentID) {
    const { client } = this.props;

    client.mutate({
      mutatation: Remove_Comment_Mutation,
      variables: {
        "cid": commentID
      },
      updateQueries: {
        removeComment: (previous, { mutationResult }) => {
          const newComment = mutationResult.data.submitComment;

          return update(prev, {
            allPostses: {
              comments: {
                $unshift: [newComment],
              },
            },
          });
        }
      }
    });
  }

  ...
Locco0_0
  • 3,420
  • 5
  • 30
  • 42
  • Unfortunately this just throws up `Uncaught TypeError: Cannot read property 'kind' of undefined` errors. – TheoG Apr 07 '17 at 11:11
  • updated the answer the `updateQueries` did not use the correct named query. Should have been `removeComment` – Locco0_0 Apr 07 '17 at 15:34
  • Unfortunately the outcome is still the same, albeit the error message has now changed. See my updated question to see my amended client.mutate code and error messages. – TheoG Apr 07 '17 at 17:59
  • Oh sorry, i was wrong again. It must be of course the query you want to change and that should be `allPostsCommentsQuery` not `removeComment`. Did you try a `console.log` on the `previous` – Locco0_0 Apr 07 '17 at 19:46
  • allPostsCommentsQuery didn't resolve the issue, and attempting to console.log `previous` failed, as the process didn't reach that far. I think it's `updateQueries` itself that is failing the whole process. – TheoG Apr 07 '17 at 20:18
  • Ok maybe you have to change the mutation. You could take a look at this part in the [docu](http://dev.apollodata.com/react/mutations.html#calling-mutations). Or you try it with the `graphql()` functionality which is defined further down. – Locco0_0 Apr 07 '17 at 20:52
  • progress is being made, I'm now getting `update(): expected target of $unshift to be an array; got undefined.` error messages. See my amended client.mutate code and generated errors. – TheoG Apr 08 '17 at 01:23
  • Yes its close. First error is that your mutation is called `removeComment` and not delete comments. Then i think you have to find the index of the comment you want to delete in the comments array and use the splice function – Locco0_0 Apr 08 '17 at 06:55
  • So my reading of the immutability-helper docs, was that `$set: [newComment]`, see updated `client.mutate` code, would replace the `comments` tree with everything minus the deleted comment, but alas no. – TheoG Apr 08 '17 at 11:14
  • immutability-helper docs: https://github.com/kolodny/immutability-helper – TheoG Apr 08 '17 at 11:15
  • The issue appears to be with `const newComment = mutationResult.data.removeComment;`, which is being returned as 'undefined', instead of as an object. – TheoG Apr 08 '17 at 12:08
  • shouldn't it be `const newComment = mutationResult.data.deleteComment;`? print out `mutationResult.data` to be sure :) – marktani Apr 08 '17 at 20:47