Проблема при выполнении обновления пользовательской мутации - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть страница настроек, где пользователь может обновить свою электронную почту, имя и фамилию.Я обертываю весь компонент настроек компонентом User, который содержит все реквизиты данных для пользователя.Данные извлекаются и отображаются в полях ввода просто отлично, но я получаю следующую ошибку при отправке данных из компонента настроек:

[GraphQL error]: Message: You provided an invalid argument for the where selector on User., Location: , Path: updateUser

Uncaught (in promise) Error: GraphQL error: You provided an invalid argument for the where selector on User.

schema.graphql

...
# import * from './generated/prisma-client/prisma.graphql'

updateUser(email: String, firstName: String, lastName: String, password: String): User!
...

Mutation.js

async updateUser(parent, args, ctx, info) {
    // First check if there is a user with that email
    const user = await ctx.db.query.user({ where: { email: args.email } });
    if (user) {
      throw new Error(`The email ${args.email} is already being used`);
    }
    const updatedUser = await ctx.db.mutation.updateUser({
      where: { id: args.id },
      data: {
        email: args.email,
        firstName: args.firstName,
        lastName: args.lastName
      }
    });
    return updatedUser;
  }

Мутация внешнего интерфейса:

const UPDATE_USER_MUTATION = gql`
  mutation UPDATE_USER_MUTATION(
    $email: String!
    $firstName: String!
    $lastName: String!
  ) {
    updateUser(email: $email, firstName: $firstName, lastName: $lastName) {
      id
      email
      firstName
      lastName
    }
  }
`;

Если это поможет, я могутакже предоставьте полный компонент Settings.js.Я все еще изучаю GraphQL / Apollo, поэтому я уверен, что делаю очевидную ошибку, но не могу найти где.Любая помощь будет принята с благодарностью!Спасибо

РЕДАКТИРОВАТЬ: Добавление файла Settings.js:

import React from "react";
import { Formik } from "formik";
import * as Yup from "yup";
import styled, { keyframes } from "styled-components";
import { Mutation, Query } from "react-apollo";
import { Button, Flex, Card, Box } from "rebass";
import gql from "graphql-tag";
import Link from "./Link";
import Text from "./Text";
import Error from "./ErrorMessage";
import User, { CURRENT_USER_QUERY } from "./User";

const UPDATE_USER_MUTATION = gql`
  mutation UPDATE_USER_MUTATION(
    $id: ID!
    $email: String
    $firstName: String
    $lastName: String
  ) {
    updateUser(
      id: $id
      email: $email
      firstName: $firstName
      lastName: $lastName
    ) {
      id
      email
      firstName
      lastName
    }
  }
`;

const StyledInput = styled(Box).attrs({
  as: "input",
})`
  font-size: 1em;
  border-radius: 3px;
  width: 15em;
  border: 1px solid ${props => props.theme.colors.greys[1]};
  padding: 0.5em;
`;

const UpdateSchema = Yup.object().shape({
  email: Yup.string()
    .email("Invalid email address")
    .required("You must enter an email address"),
});

const Settings = props => (
  <User>
    {({ data: { currentUser } }) => (
      <Mutation
        mutation={UPDATE_USER_MUTATION}
        refetchQueries={[{ query: CURRENT_USER_QUERY }]}

      >
        {(updateUser, { error, loading, called }) => (
          <Formik
            initialValues={{
              id: props.userId,
              email: currentUser.email,
              firstName: currentUser.firstName,
              lastName: currentUser.lastName,
            }}
            validationSchema={UpdateSchema}
            onSubmit={values => {
              updateUser({
                variables: {
                  email: values.email,
                  firstName: values.firstName,
                  lastName: values.lastName,
                },
              });
            }}
            render={({
              values,
              errors,
              touched,
              handleChange,
              handleBlur,
              handleSubmit,
            }) => (
              <Flex
                flexDirection={["column"]}
                mb={[2, 0]}
                width={1}
                alignItems="center"
                height={1}
              >
                <form onSubmit={handleSubmit} method="post">
                  <fieldset disabled={loading} aria-busy={loading}>
                    <Box>
                      <Error error={error} />
                      <Box mb="30px">
                        <label htmlFor="email">
                          <Text my={2}>Email</Text>
                          <StyledInput
                            placeholder="Enter your email address"
                            type="email"
                            name="email"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.email}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              Email successfully updated!
                            </Text>
                          )}

                          {touched.email && errors && errors.email && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.email}
                            </Text>
                          )}
                        </label>
                      </Box>

                      <Box mb="30px">
                        <label htmlFor="First Name">
                          <Text my={2}>First Name</Text>
                          <StyledInput
                            placeholder="Please enter your first name"
                            type="text"
                            name="firstName"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.firstName}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              First name updated!
                            </Text>
                          )}

                          {touched.firstName && errors && errors.firstName && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.firstName}
                            </Text>
                          )}
                        </label>
                      </Box>

                      <Box mb="30px">
                        <label htmlFor="Last Name">
                          <Text my={2}>Last Name</Text>
                          <StyledInput
                            placeholder="Please enter your last name"
                            type="text"
                            name="lastName"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.lastName}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              Last name updated!
                            </Text>
                          )}

                          {touched.lastName && errors && errors.lastName && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.lastName}
                            </Text>
                          )}
                        </label>
                      </Box>
                      <Box>
                        <Button type="submit" width={1} primary>
                          Update
                        </Button>
                      </Box>
                    </Box>
                  </fieldset>
                </form>
              </Flex>
            )}
          />
        )}
      </Mutation>
    )}
  </User>
);

export default Settings;
export { UPDATE_USER_MUTATION };

1 Ответ

0 голосов
/ 19 февраля 2019

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

Пожалуйста, укажите его в мутации внешнего интерфейса.

const UPDATE_USER_MUTATION = gql`
  mutation UPDATE_USER_MUTATION(
    $id: ID!
    $email: String!
    $firstName: String!
    $lastName: String!
  ) {
    updateUser(id: $id, email: $email, firstName: $firstName, lastName: $lastName) {
      id
      email
      firstName
      lastName
    }
  }
`;

РЕДАКТИРОВАТЬ : также обновите файл schema.graphql

...
# import * from './generated/prisma-client/prisma.graphql'

updateUser(id: ID!, email: String, firstName: String, lastName: String, password: String): User!
...

РЕДАКТИРОВАТЬ : также обновите компонент реагирования следующим образом:


import React from "react";
import { Formik } from "formik";
import * as Yup from "yup";
import styled, { keyframes } from "styled-components";
import { Mutation, Query } from "react-apollo";
import { Button, Flex, Card, Box } from "rebass";
import gql from "graphql-tag";
import Link from "./Link";
import Text from "./Text";
import Error from "./ErrorMessage";
import User, { CURRENT_USER_QUERY } from "./User";

const UPDATE_USER_MUTATION = gql`
  mutation UPDATE_USER_MUTATION(
    $id: ID!
    $email: String
    $firstName: String
    $lastName: String
  ) {
    updateUser(
      id: $id
      email: $email
      firstName: $firstName
      lastName: $lastName
    ) {
      id
      email
      firstName
      lastName
    }
  }
`;

const StyledInput = styled(Box).attrs({
  as: "input",
})`
  font-size: 1em;
  border-radius: 3px;
  width: 15em;
  border: 1px solid ${props => props.theme.colors.greys[1]};
  padding: 0.5em;
`;

const UpdateSchema = Yup.object().shape({
  email: Yup.string()
    .email("Invalid email address")
    .required("You must enter an email address"),
});

const Settings = props => (
  <User>
    {({ data: { currentUser } }) => (
      <Mutation
        mutation={UPDATE_USER_MUTATION}
        refetchQueries={[{ query: CURRENT_USER_QUERY }]}

      >
        {(updateUser, { error, loading, called }) => (
          <Formik
            initialValues={{
              id: props.userId,
              email: currentUser.email,
              firstName: currentUser.firstName,
              lastName: currentUser.lastName,
            }}
            validationSchema={UpdateSchema}
            onSubmit={values => {
              updateUser({
                variables: {
                  id: currentUser.id,
                  email: values.email,
                  firstName: values.firstName,
                  lastName: values.lastName,
                },
              });
            }}
            render={({
              values,
              errors,
              touched,
              handleChange,
              handleBlur,
              handleSubmit,
            }) => (
              <Flex
                flexDirection={["column"]}
                mb={[2, 0]}
                width={1}
                alignItems="center"
                height={1}
              >
                <form onSubmit={handleSubmit} method="post">
                  <fieldset disabled={loading} aria-busy={loading}>
                    <Box>
                      <Error error={error} />
                      <Box mb="30px">
                        <label htmlFor="email">
                          <Text my={2}>Email</Text>
                          <StyledInput
                            placeholder="Enter your email address"
                            type="email"
                            name="email"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.email}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              Email successfully updated!
                            </Text>
                          )}

                          {touched.email && errors && errors.email && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.email}
                            </Text>
                          )}
                        </label>
                      </Box>

                      <Box mb="30px">
                        <label htmlFor="First Name">
                          <Text my={2}>First Name</Text>
                          <StyledInput
                            placeholder="Please enter your first name"
                            type="text"
                            name="firstName"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.firstName}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              First name updated!
                            </Text>
                          )}

                          {touched.firstName && errors && errors.firstName && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.firstName}
                            </Text>
                          )}
                        </label>
                      </Box>

                      <Box mb="30px">
                        <label htmlFor="Last Name">
                          <Text my={2}>Last Name</Text>
                          <StyledInput
                            placeholder="Please enter your last name"
                            type="text"
                            name="lastName"
                            onChange={handleChange}
                            onBlur={handleBlur}
                            value={values.lastName}
                          />

                          {!error && !loading && called && (
                            <Text fontSize={1} color="green" pt={1}>
                              Last name updated!
                            </Text>
                          )}

                          {touched.lastName && errors && errors.lastName && (
                            <Text fontSize={1} color="red" pt={1}>
                              {errors.lastName}
                            </Text>
                          )}
                        </label>
                      </Box>
                      <Box>
                        <Button type="submit" width={1} primary>
                          Update
                        </Button>
                      </Box>
                    </Box>
                  </fieldset>
                </form>
              </Flex>
            )}
          />
        )}
      </Mutation>
    )}
  </User>
);

...