【问题标题】:Rails/GraphQL: Uncaught (in promise): Error: Cannot read property of undefinedRails/GraphQL:未捕获(承诺):错误:无法读取未定义的属性
【发布时间】:2020-05-13 04:18:31
【问题描述】:

我正在处理一个 Rails/React/GraphQl 项目,并在 RegisterUser 突变中获得一个 Uncaught (in promise): Error: Cannot read property of undefined。我在谷歌上搜索了类似的问题,但找不到类似的东西。我对React/GraphQL/Apollo 很陌生。

当出现ActiveReacord 错误时,它已通过此设置成功记录到控制台。

success 上,我收到成功消息加上上面提到的Uncaught Error 打印到控制台。另外,我在 rails 控制台中看到创建了新用户,但表单挂起并且没有关闭(我假设是由于错误?)。

这是错误的来源:(.then(({ data: { registerUser: { success, errors: [{ message }] } } }) => 行)

注册用户/index.js:

import React, { useState } from 'react';
import { useHistory } from "react-router-dom";
import { Mutation } from 'react-apollo';
import { Register } from './operations.graphql';


const RegisterUser = () => {
  const isLoggedIn = JSON.parse(sessionStorage.getItem('isLoggedIn'));
  const history = useHistory();
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [email, setEmail] = useState("");

  const onCompleted = (resp) => {
    console.log(resp.registerUser.success);
  }

  const onError = (message) => {
    console.log(message);
  }

    if(!isLoggedIn) {
      return (
        <Mutation mutation={Register} onCompleted={onCompleted}>
          {(registerUser, { loading, error }) => (
            <div className="card bg-light col-md-4 offset-md-4 shadow p-3 mb-5 rounded">
              <article className="card-body mx-auto" style={{maxWidth: '400px'}}>
                <p className="text-center">Create an account</p>
                <form onSubmit={ e => {
                    e.preventDefault();
                    registerUser({
                      variables: {
                        username: username,
                        password: password,
                        email:    email,
                      }
                    }).then(({ data: { registerUser: { success, errors: [{ message }] } } }) => {
                      if (success) {
                        history.push("/login");
                      } else {
                        onError(message);
                      }
                    });
                  }}
                >
                  <div className="form-group input-group">
                    <input
                      type="text"
                      value={username}
                      className="form-control"
                      onChange={e => setUsername(e.target.value)}
                      placeholder="username"
                      required
                    />
                  </div>
                  <div className={"form-group input-group"}>
                    <input
                      type="email"
                      value={email}
                      className="form-control"
                      onChange={e => setEmail(e.target.value)}
                      placeholder="email"
                      required
                    />
                  </div>
                  <div className="form-group input-group">
                    <input
                      type="password"
                      value={password}
                      className="form-control"
                      onChange={e => setPassword(e.target.value)}
                      placeholder="password"
                      required
                    />
                  </div>
                  <input type="submit" className="btn btn-primary btn-block" value="Sign up!" />
                  <p className="text-center">Have an account? <a href="/login">Log In</a> </p>
                </form>
              </article>
              {loading && <p>Loading...</p>}
              {error && <p>Error! Please try again</p>}
            </div>
          )}
        </Mutation>
      );
    }
}
export default RegisterUser;

register_user.rb:

module Mutations
  class RegisterUser < Mutations::BaseMutation
    graphql_name "RegisterUser"

    argument :attributes, Types::UserRegistrationAttributes, required: true

    field :user, Types::UserType, null: true

    def resolve(attributes:)
      user = User.new(username: attributes[:username],
                      password: attributes[:password],
                      email: attributes[:email])
      if user.save
        # current_user needs to be set so authenticationToken can be returned
        context[:current_user] = user
        {
          user: user,
          errors: [],
          success: "Sign up successfull. Please confirm your email",
        }
      else
        user_errors = user.errors.messages.map do |key, message|
          path = ["attributes", key.to_s.camelize(:lower)]
          {
            path: path,
            message: "#{key.to_s.camelize} #{message}",
          }
        end
        {
          user: user,
          errors: user_errors,
        }
      end
    end
  end
end

base_mutation.rb:

module Mutations
  # This class is used as a parent for all mutations, and it is the place to have common utilities
  class BaseMutation < GraphQL::Schema::Mutation

    field :success, String, null: true
    field :errors, [Types::UserErrorType], null: true

    protected

    def authorize_user
      return true if context[:current_user].present?

      raise GraphQL::ExecutionError, "User not signed in"
    end
  end
end

user_error_type.rb:

module Types
  class UserErrorType < Types::BaseObject
    description "A user-readable error"

    field :message, String, null: true, description: "A description of the error"
    field :path, [String], null: true, description: "Which input value this error came from"
  end
end

不确定是什么导致了这个错误,非常感谢任何建议。感谢您的宝贵时间。

更新(S): 2020 年 1 月 29 日问题已根据 @xadm 在下面的回复得到修复。

1) 注册

操作.graphql

mutation Register($username: String!, $password: String!, $email: String!) {
  __typename
  registerUser(attributes: {username: $username, password: $password, email: $email}) {
    user {
      id
      username
      authenticationToken
    }
    success
    errors {
      message
      path
    }
  }
}
```

【问题讨论】:

  • Register 定义?
  • 变异测试用graphiQL“外部”,邮递员?响应示例
  • @xadm - re;注册定义,我在“更新”1)下更新了问题。我通过 Chrome 中的 Apollo 扩展测试了突变。它给出了相同的结果。

标签: ruby-on-rails reactjs graphql apollo


【解决方案1】:

在外部工具中的测试证明这不是 [相当] react/apollo 故障。

它来自非标准错误处理 - 可选元素(消息)以突变形式表达,预期响应。使用 UNION 的类似问题:useQuery returns undefined, But returns data on gql playground

您指向的错误:

这是错误的来源:(at line .then(({ data: { registerUser: { success, errors: [{ message }] } } }) =>)

是“过于乐观的解构”的一个例子,不是故障安全(不会在空值上停止),将其更改为

.then(({ data: { registerUser: { success, errors } } }) =>)

并在正文中处理errors - 这是一个数组,所以没有message 参数。

【讨论】:

  • 宾果游戏!你的建议奏效了!太感谢了。我在 onError() 函数中使用了console.log(errors[0]["message"]); 来获取消息。 这是一个正确的方法吗??另外,我从你的回复中学到了一些东西,再次感谢。
  • 不 - 它与标准相差甚远......您应该使用 const { loading, error, data } = useQuery... 并在 error 上操作,而不是 data.XXX.errors 阅读 apollographql.com/docs/react/api/react-hooks/#usequeryapollographql.com/docs/apollo-server/data/errors 以获取自定义错误
猜你喜欢
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多