Rails/GraphQL: Uncaught (in promise): Error: Cannot read property of undefined
Rails/GraphQL: Uncaught (in promise): Error: Cannot read property of undefined
我正在做一个 Rails/React/GraphQl
项目并在 RegisterUser 突变中得到一个 Uncaught (in promise): Error: Cannot read property of undefined
。我在 Google 上搜索了类似的问题,但找不到任何类似的问题。我是 React/GraphQL/Apollo
的新手。
当出现 ActiveReacord
错误时,已使用此设置成功将其记录到控制台。
在 success
上,我收到成功消息 plus 上面提到的 Uncaught Error
打印到控制台.此外,我在 rails 控制台中看到新用户已创建,但表单挂起且未关闭(我假设是由于错误?)。
这是错误的来源:(第 .then(({ data: { registerUser: { success, errors: [{ message }] } } }) =>
行)
RegisterUser/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
不确定是什么导致了这个错误,非常感谢任何建议。谢谢你的时间。
更新:
1/29/2020 问题已根据@xadm 的回复修复。
1) 注册
operations.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
}
}
}
```
在外部工具中的测试证明这不是[完全] react/apollo 错误。
它来自非标准错误处理 - 以突变表示的可选元素(消息),预计会在响应中出现。使用 UNION 的类似问题:useQuery returns undefined, But returns data on gql playground
您指向的错误:
Here's where the error is coming from: (at line .then(({ data: { registerUser: { success, errors: [{ message }] } } }) =>)
是"too optimistic destructuring"的一个例子,不安全(不停止在空值上),将其更改为
.then(({ data: { registerUser: { success, errors } } }) =>)
并在正文中处理 errors
- 这是一个数组,因此没有 message
参数。
我正在做一个 Rails/React/GraphQl
项目并在 RegisterUser 突变中得到一个 Uncaught (in promise): Error: Cannot read property of undefined
。我在 Google 上搜索了类似的问题,但找不到任何类似的问题。我是 React/GraphQL/Apollo
的新手。
当出现 ActiveReacord
错误时,已使用此设置成功将其记录到控制台。
在 success
上,我收到成功消息 plus 上面提到的 Uncaught Error
打印到控制台.此外,我在 rails 控制台中看到新用户已创建,但表单挂起且未关闭(我假设是由于错误?)。
这是错误的来源:(第 .then(({ data: { registerUser: { success, errors: [{ message }] } } }) =>
行)
RegisterUser/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
不确定是什么导致了这个错误,非常感谢任何建议。谢谢你的时间。
更新: 1/29/2020 问题已根据@xadm 的回复修复。
1) 注册
operations.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
}
}
}
```
在外部工具中的测试证明这不是[完全] react/apollo 错误。
它来自非标准错误处理 - 以突变表示的可选元素(消息),预计会在响应中出现。使用 UNION 的类似问题:useQuery returns undefined, But returns data on gql playground
您指向的错误:
Here's where the error is coming from: (at line .then(({ data: { registerUser: { success, errors: [{ message }] } } }) =>)
是"too optimistic destructuring"的一个例子,不安全(不停止在空值上),将其更改为
.then(({ data: { registerUser: { success, errors } } }) =>)
并在正文中处理 errors
- 这是一个数组,因此没有 message
参数。