最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to handle GraphQL errors with React-Apollo? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to move from Rest API to GraphQL using Express + Mongoose on server and React + Apollo on client.

async resolve(_, { email, password, passwordConfirmation }) { // Sign Up mutation
            const user = new User({ email });
            user.password = password;
            user.passwordConfirmation = passwordConfirmation;
            try{
                const createdUser = await user.save();
                return createdUser;
            } catch(error) {
                console.log(error); // Returns errors object like {email: {message: 'E-mail is required'}}
                throw new Error(error); // But on the client there is a string with all errors
            }
        }`

How can I handle the whole object of errors on the client?

I'm trying to move from Rest API to GraphQL using Express + Mongoose on server and React + Apollo on client.

async resolve(_, { email, password, passwordConfirmation }) { // Sign Up mutation
            const user = new User({ email });
            user.password = password;
            user.passwordConfirmation = passwordConfirmation;
            try{
                const createdUser = await user.save();
                return createdUser;
            } catch(error) {
                console.log(error); // Returns errors object like {email: {message: 'E-mail is required'}}
                throw new Error(error); // But on the client there is a string with all errors
            }
        }`

How can I handle the whole object of errors on the client?

Share Improve this question asked Aug 20, 2017 at 22:23 user8353384user8353384
Add a ment  | 

2 Answers 2

Reset to default 6

The Apollo client returns a promise when you make a mutation. The errors from that promise can be accessed in the catch block of the mutation's resultant promise. See my example below.

If there are errors from my login mutation, I will access them in the catch block of the promise that is returned and then set those errors to local state in the ponent. From there the errors can be rendered if they exist, or even passed down to a child ponent to be rendered if you like. Please note that errors are usually returned in an array.

class LoginForm extends Component {
  constructor(props) {
    super(props);

    this.state = { errors: [] };
  }


  onSubmit({ email, password }) {
    this.props.mutate({
      variables: { email, password },
      refetchQueries: [{ query }]
    }).catch(res => {
      const errors = res.graphQLErrors.map(error => error.message);
      this.setState({ errors });
    });
  }

  render() {
    return (
      <div>
        <AuthForm
          errors={this.state.errors}
          onSubmit={this.onSubmit.bind(this)}
        />
      </div>
    );
  }
}

export default graphql(query)(
  graphql(mutation)(LoginForm)
);

You can also use renderProps in react-apollo which gives you error and loading states in an object in the second argument.

import React, { Component } from 'react';
import { Mutation } from 'react-apollo';
import gql from 'graphql-tag';
import Error from './ErrorMessage';

const LOGIN_MUTATION = gql`
  mutation LOGIN_MUTATION($email: String!, $password: String!) {
    signin(email: $email, password: $password) {
      id
      email
      name
    }
  }
`;

class Login extends Component {
  state = {
    name: '',
    password: '',
    email: '',
  };
  saveToState = e => {
    this.setState({ [e.target.name]: e.target.value });
  };
  render() {
    return (
      <Mutation
        mutation={LOGIN_MUTATION}
        variables={this.state}
      >
        {(login, { error, loading }) => (
          <form
            method="post"
            onSubmit={async e => {
              e.preventDefault();
              await login();
              this.setState({ name: '', email: '', password: '' });
            }}
          >
            <fieldset disabled={loading}>
              <h2>Sign into your account</h2>
              <Error error={error} />
              <label htmlFor="email">
                Email
                <input
                  type="email"
                  name="email"
                  placeholder="email"
                  value={this.state.email}
                  onChange={this.saveToState}
                />
              </label>
              <label htmlFor="password">
                Password
                <input
                  type="password"
                  name="password"
                  placeholder="password"
                  value={this.state.password}
                  onChange={this.saveToState}
                />
              </label>

              <button type="submit">Sign In!</button>
            </fieldset>
          </form>
        )}
      </Mutation>
    );
  }
}

export default Login;

Hope this helps!

发布评论

评论列表(0)

  1. 暂无评论