ApolloClient: Refactor updateQueries для работы с this.props.client.mutate

Примечание. Поскольку процесс обработки обновлений мутации / запросов / кэша теперь решается с помощью обновлений, я больше не использую uodateQueries, что делает этот вопрос более неактуальным.

Итак, у меня есть отношения один ко многим из сообщений в комментарии:

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!
}

и Root_Query, как показано в Apollo devTools (см. прилагаемое изображение), из:

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

Выполнение Add_Comment_Mutation или 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
    }
  }
`;

не корректно обновляет реактивный кеш, и, следовательно, мой пользовательский интерфейс неправильно отражает какие-либо добавления / удаления комментариев, которые запускаются событиями onClick.

Как заставить updateQueries корректно работать с this.props.client.mutate, поскольку текущая попытка генерирует "Ошибка: update(): ожидаемая цель $unshift будет массивом; получена неопределенная". ошибки (см. ниже):

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);
  },

Сгенерированная ошибка:

Примечание. Проблема, по-видимому, связана с

const newComment = mutationResult.data.removeComment;

который возвращается как "неопределенный", а не как объект.

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

1 ответ

Я не думаю, что вы можете объединить мутации. По крайней мере, сообщение об ошибке говорит так. Это должно быть что-то вроде:

...

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],
              },
            },
          });
        }
      }
    });
  }

  ...

Другие вопросы по тегам