Реакция Аполлона - Странный эффект при создании мутации? - PullRequest
0 голосов
/ 13 октября 2018

Я установил приложение React с React-Apollo и могу успешно запрашивать мой API.

Однако, когда я делаю мутацию, возникает странный эффект.Я вернул все данные успешно (как видно на вкладке «Сеть» в Chrome Dev Tools), но при попытке console.log данных он говорит, что это null.

Вот соответствующий код:

// mutation file

import gql from "graphql-tag";
export default gql`
  mutation CreateReservation($name: String!, $time: String!, $persons: String, $specialMessage: String, $email: String!) {
    createReservation(input: {
        name: $name,
        time: $time,
        persons: $persons,
        specialMessage: $specialMessage,
        email: $email
    }) {
        __typename
        error
        data
    }
  }
`;

// component file

import React from "react";
import {graphql, compose} from "react-apollo";
import CreateReservationMutation from "../../graphql/mutations/api/CreateReservation";

class Reservations extends React.Component {
testGraphQL = ({ reservationName, reservationTime, reservationEmail, reservationPartySize, reservationMessage}) => {

    const variables = {
        name: reservationName,
        time: reservationTime,
        persons: reservationPartySize,
        specialMessage: reservationMessage,
        email: reservationEmail
    };

    this.props.createReservation(variables)
    .then(({data}) => {
        console.log("Data received: ", data); // Here is the problem
    }).catch((err) => {
        console.log("Error sending data: ", err);
    })
}
render() {
    return (
        <div>
            ...
            <div>
                <Form 
                    ...
                    submitFunc={this.testGraphQL}
                />
            </div>
            ...
            </div>
        </div>
    )
  }
}

export default compose(
    graphql(CreateReservationMutation, {
        props: ({mutate}) => ({
            createReservation: (variables) => mutate({variables})
        })
    })
)(Reservations);

Поэтому, когда я вызываю функцию testGraphQL, я получаю в консоли следующее:

Data received:  {createReservation: null}

Но, просматривая вкладку Сеть, я вижу, что данныена самом деле там, в конце концов, и это именно то, что я ищу.Кроме того, моя база данных правильно обновлена ​​со всеми деталями бронирования, поэтому я точно знаю, что мутация выполняется.

Это то, что я вижу на вкладке Сеть:

{"data":{"createReservation":{"__typename":"ReservationResponse","error":null,"data":"Success"}}}

Это то, что я ожидаю увидеть, когда позвоню console.log в testGraphQL.

ТакЯ знаю, что у меня нет ошибок с моей схемой, моим клиентом Apollo или моим файлом мутации.

Вместо этого, проблема заключается в том, как я настраиваю свой оператор compose иликак я называю мутацию.

Пожалуйста, дайте мне знать, если вы заметите здесь ошибку.Спасибо

ОБНОВЛЕНИЕ

Следует отметить, что я использую AWS AppSync в качестве моего провайдера GraphQL.

Мутация вызывает лямбда-функцию, которая выполняетследующее:

...
Promise.all([dynamodbPromise, snsPromise, sesPromise])
    .then((data) => {
        callback(null, {data: "Success"});
    })
    .catch((err) => {
        callback(null, {error: err});
    });

Вот мой распознаватель для этой мутации:

// request mapping template

{
  "version" : "2017-02-28",
  "operation": "Invoke",
  "payload": $util.toJson($ctx.args.input)
}

//  response mapping template

$util.toJson($context.result)

ОБНОВЛЕНИЕ 2

Настройка optimisticResonse и перезапись моегомутация, подобная этой:

this.props.createReservation({
        variables,
        optimisticResponse: {
            createReservation: {
                __typename: "ReservationResponse",
                errorMessage: null,
                responseMessage: "_TEST_"
            }
        }
    })
    .then(res => {
        console.log("Apllo Data: ", res);
    })

Приводит меня к получению только данных из оптимистического ответа, а именно:

{data:
  createReservation: {
    __typename: "ReservationResponse", 
    errorMessage: null, 
    responseMessage: "Optimistic Success"
}

Таким образом, возвращаемые данные не должны обновляться с фактическим ответомиз API.

Как теперь заставить Apollo обновить ответ после возврата оптимистического ответа?

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Я наконец-то решил ее, хотя решение не идеально.

Мне пришлось написать функцию обновления для моей мутации.Это базовая реализация, которая в конечном итоге дает мне фактические данные из API:

this.props.createReservation({
        variables,
        optimisticResponse: {
            createReservation: {
                __typename: "ReservationResponse",
                errorMessage: null,
                responseMessage: "Optimistic Success"
            }
        },
        update: (proxy, {data: {createReservation}}) => {
            console.log("Update: ", createReservation);
        }
    })
    .then(res => {
        console.log("Apllo Data: ", res);
    })

Функция обновления вызывается три раза.Первые два запуска перед выполнением обещания включают данные из optimisticResponse, как показано в моем разделе «Обновление 2».Наконец, третий вызов возвращает фактические данные из API.

Пока это будет работать, пожалуйста, дайте мне знать, если здесь есть более прямой метод.В этом случае я не хочу, чтобы optimisticResponse возвращался вообще.Я хочу, чтобы возвращались только фактические данные из моего API.Таким образом, я могу дать своим пользователям правильную обработку ошибок в случае, если что-то пойдет не так.

Спасибо, и я надеюсь, что мы можем помочь другим людям, которые имеют эту проблему.

0 голосов
/ 13 октября 2018

У вас есть два варианта получения ответа на данные от мутации:

В компоненте мутации:

<Mutation>{mutation, {data}}</Mutation>

Или в функции мутации:

mutate().then(data => ...)

Вы получаете ответ на изменение мутации, но ожидаете, что объект состояния, который apollo передает компоненту Mutation.

Для apollo не имеет смысла передавать объект состояния, потому что если мутация разрешенавсе прошло успешно, любая ошибка приведет к тому, что обещание будет отклонено, и при вызове mutate состояние загрузки не будет предоставлено.

Итак, чтобы исправить свой код, вам просто нужно изменить это

this.props.createReservation(variables)
    .then(data => {
...