My updateUser
takes an email input and updates that user's firstName/lastName
at the backend. Currently, my mutations run in a way that if I only enter firstName and leave the lastName textfield empty, at the backend, the lastName changes to ''blank.
I want a method that the if I am submitting the form with only the firstName, only the firstName should be updated while the lastName stays the same. I can't figure out where exactly to put these conditions and how.
UpdateUserPage:
export default function UpdateUserPage() {
const [state, setState] = useState({
firstName: '',
lastName: '',
email: '',
phoneNumber:'',
});
const [isSubmitted, setIsSubmitted] = useState(false);
const [isAdded, setIsAdded] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
function StatusMessage() {}
function submitForm(UpdateUserMutation: any) {
setIsSubmitted(true);
const { firstName, lastName, email, phoneNumber } = state;
if (email && (firstName || lastName || phoneNumber)) {
UpdateUserMutation({
variables: {
firstName: firstName,
lastName: lastName,
email: email,
phoneNumber: phoneNumber,
},
}).then(({data}:any) => {
setIsAdded(true);
})
.catch((error: { message: string; }) => {
setIsAdded(false);
setErrorMessage(error.message)
})
}
}
return (
<Mutation mutation={UpdateUserMutation}>
{(UpdateUserMutation: any) => (
<div>
<Formik
initialValues={{ firstName: '', lastName: '', email: ''}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
validationSchema={schema}
>
{props => {
const {
values: { firstName, lastName, email, phoneNumber },
errors,
touched,
handleChange,
isValid,
setFieldTouched
} = props;
const change = (name: string, e: any) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
setState( prevState => ({ ...prevState, [name]: e.target.value }));
};
return (
<div className='main-content'>
<form style={{ width: '100%' }}
onSubmit={e => {e.preventDefault();
submitForm(UpdateUserMutation);StatusMessage()}}>
<div>
<TextField
variant="outlined"
margin="normal"
id="email"
name="email"
helperText={touched.email ? errors.email : ""}
error={touched.email && Boolean(errors.email)}
label="Email"
value={email}
onChange={change.bind(null, "email")}
/>
<br></br>
<TextField
variant="outlined"
margin="normal"
id="firstName"
name="firstName"
helperText={touched.firstName ? errors.firstName : ""}
error={touched.firstName && Boolean(errors.firstName)}
label="First Name"
value={firstName}
onChange={change.bind(null, "firstName")}
/>
<br></br>
<TextField
variant="outlined"
margin="normal"
id="lastName"
name="lastName"
helperText={touched.lastName ? errors.lastName : ""}
error={touched.lastName && Boolean(errors.lastName)}
label="Last Name"
value={lastName}
onChange={change.bind(null, "lastName")}
/>
<Button
type="submit"
disabled={!isValid || !email}
>
Update User Info</Button>
</div>
</form>
<br></br>
{isSubmitted && StatusMessage()}
</div>
)
}}
</Formik>
</div>
)
}
</Mutation>
);
The mutation:
export const UpdateUserMutation = gql`
mutation UpdateUserMutation($email: String!, $firstName: String, $lastName: String){
updateUser(email: $email, input: {firstName: $firstName, lastName: $lastName}){id,firstName}
}
`;
On the playground, the mutation works even when only one of the fields is passed. In that case, only that field is altered and the other fields remain same. Now I don't know how to implement it on the front-end according to my existing code.
You're claiming that playground invoked mutation works ... compare requests [details] in browser dev tools (network tab).
Mixing 'old style' compoinents ( <Mutation />
, <Formik />
) with hooks is [at least] not a good idea. Use useFormik
and useMutation
hooks.
Formik manages values for fields then no need to manage them in state.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.