我对React Apollo和graphQL非常陌生。我正在尝试创建一个将个人数据添加到用户个人资料的编辑个人资料表单。当我单击“提交”时,什么都没有发生,并且在控制台日志中得到错误:
理想情况下,我希望表单最初以用户先前输入的任何数据呈现,以便在提交表单并且他们没有更改所有输入时,不会覆盖他们没有更改的输入。 mongoDB数据库。
所有和任何建议将不胜感激!谢谢!
在我的schema.js中,我有以下内容:
editOtherProfileDetails(email: String!, locationCity: String!, locationState: String!, locationCountry: String!, interests: String!): User
在我的resolvers.js中,我有以下内容:
editOtherProfileDetails: async (root, { email, locationCity, locationState, locationCountry, interests }, { User }) => {
const user = await User.findOneAndUpdate({ email },
{ $set: { locationCity: locationCity } },
{ $set: { locationState: locationState } },
{ $set: { locationCountry: locationCountry } },
{ $set: { interests: interests } },
{ new: true }
);
if (!user) {
throw new Error('User Not Found');
}
return user;
},
在我的index.js中,我有:
export const EDIT_OTHER_PROFILE_DETAILS = gql`
mutation($locationCountry: String!){
editOtherProfileDetails(email: $email, locationCity: $locationCity, locationState: $locationState, locationCountry: $locationCountry, interests: $interests){
email
locationCity
locationState
locationCountry
interests
}
}
`;
在我的editProfile.js中,我具有以下内容:
import React, { Fragment } from 'react';
import { Mutation } from 'react-apollo';
import {GET_USER_PROFILE, EDIT_OTHER_PROFILE_DETAILS, PROFILE_PAGE } from './../../queries';
import { withRouter } from 'react-router-dom';
import toastr from 'toastr';
const initialState = {
locationCity: '',
locationState: '',
locationCountry: '',
interests: '',
error: ''
}
class EditOtherProfileMutations extends React.Component {
constructor(props) {
super(props);
this.state = {
locationCity: '',
locationState: '',
locationCountry: '',
interests: '',
error: ''
}
}
componentDidMount() {
if (this.props.profile) {
this.setState({
locationCity: this.props.profile.locationCity,
locationState: this.props.profile.locationState,
locationCountry: this.props.profile.locationCountry,
interests: this.props.profile.interests
});
}
toastr.options = {
"closeButton": false,
"debug": false,
"newestOnTop": true,
"progressBar": true,
"positionClass": "toast-bottom-right",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
}
}
handleChange(event) {
const name = event.target.name;
const value = event.target.value;
this.setState({
[name]: value.charAt(0).toUpperCase() + value.substr(1).toLowerCase()
});
}
handleSubmit(event, editOtherProfileDetails) {
event.preventDefault();
editOtherProfileDetails().then(async () => {
toastr.success('We have updated your details!', 'Saved!');
}).catch(error => {
this.setState({
error: error.graphQLErrors.map(x => x.message)
})
// console.error("ERR =>", error.graphQLErrors.map(x => x.message));
});
}
render() {
const { locationCity, locationState, locationCountry, interests } = this.state
const userName = this.props.session.getCurrentUser.userName;
this.state;
return (
<Fragment>
<Mutation
mutation={EDIT_OTHER_PROFILE_DETAILS}
variables={{ email: this.props.session.getCurrentUser.email, locationCity, locationState, locationCountry, interests }}
refetchQueries={() => [
{ query: GET_USER_PROFILE },
{ query: PROFILE_PAGE, variables: { userName } }
]}>
{/* eslint-disable */}
{(editOtherProfileDetails, { data, loading, error }) => {
/* eslint-enable */
return (
<form className="form" onSubmit={event => this.handleSubmit(event, editOtherProfileDetails)}>
<div className="form_wrap">
<div className="form_row">
<div className="form_item">
<div className="form_input">
<span className="edit_profile_span">City</span>
<input type="text" name="locationCity" placeholder="City" value={locationCity} style={{ textTransform: "capitalize"}} onChange={this.handleChange.bind(this)}/>
<span className="bottom_border"></span>
</div>
</div>
</div>
<div className="form_row">
<div className="form_item">
<div className="form_input">
<span className="edit_profile_span">State</span>
<input type="text" name="locationState" placeholder="State" value={locationState} style={{ textTransform: "capitalize"}} onChange={this.handleChange.bind(this)}/>
<span className="bottom_border"></span>
</div>
</div>
</div>
<div className="form_row">
<div className="form_item">
<div className="form_input">
<span className="edit_profile_span">Country</span>
<input type="text" name="locationCountry" placeholder="Country" value={locationCountry} style={{ textTransform: "capitalize"}} onChange={this.handleChange.bind(this)}/>
<span className="bottom_border"></span>
</div>
</div>
</div>
<div className="form_row">
<div className="form_item">
<div className="form_input">
<span className="edit_profile_span">Interests</span>
<input type="text" name="interests" placeholder="Interests (e.g Sports, Wine, Outdoors ect.)" value={interests} style={{ textTransform: "capitalize"}} onChange={this.handleChange.bind(this)}/>
<span className="bottom_border"></span>
</div>
</div>
</div>
<div className="form_buttons">
<button type="submit" className="btn">
Save changes</button>
</div>
</div>
</form>
);
}}
</Mutation>
</Fragment>
)
}
}
export default withRouter(EditOtherProfileMutations);
答案 0 :(得分:0)
我认为问题在于您的变异输入字段 不同于与您在 schema 中定义的字段相同。
您的架构具有:
editOtherProfileDetails(
email: String!,
locationCity: String!,
locationState: String!,
locationCountry: String!,
interests: String!
): User
您对突变的定义如下:
mutation($locationCountry: String!){ ... }
输入参数必须匹配,所以我认为如果您这样定义突变,它将起作用:
mutation NameOfYourMutation(
$email: String!,
$locationCity: String!,
$locationState: String!,
$locationCountry: String!,
$interests: String!
) { ... }
此外,正如您可能预期的那样,这将逐渐变得难以维护。 我建议您看看input objects。
答案 1 :(得分:0)
看
您声明的变异带有一个参数,在解析器中,它使用电子邮件,locationCity,locationState,locationCountry,此args感兴趣,但未声明它将引起问题,您应该使用$ locationCity等,但它不是数据文件应该作为参数
这样的形状
mutation($locationCountry: String!
,$locationCity: String!,
$locationState: String!,
$locationCountry: String!,
$interests: String!){
editOtherProfileDetails(email: $email, locationCity: $locationCity, locationState: $locationState, locationCountry: $locationCountry, interests: $interests){
email
locationCity
locationState
locationCountry
interests
}
告诉我是否提交
答案 2 :(得分:0)
我发现我做错了。代替:
const user = await User.findOneAndUpdate({ email },
{ $set: { locationCity: locationCity } },
{ $set: { locationState: locationState } },
{ $set: { locationCountry: locationCountry } },
{ $set: { interests: interests } },
{ new: true }
);
我需要放:
const user = await User.findOneAndUpdate({ email },
{ $set: { locationCity: locationCity, locationState: locationState, locationCountry: locationCountry, interests: interests } },
{ new: true }
);