I have an UpdateUserPage which can call mutations in different ways depending on how many input variables are being passed for eg:
only firstname is updated
mutation{
updateUser(email: "[email protected]",
input: {firstName:"check"}){id}
}
both, firstname & lastName are updated:
mutation{
updateUser(email: "[email protected]",
input: {firstName:"check", lastName: "new"}){id}
}
Query in my code right now:
export const UPDATE_USER = gql`
mutation UpdateUser($email: String!, $firstName: String, $lastName: String) {
updateUser(
email: $email
input: { firstName: $firstName, lastName: $lastName }
) {
id
firstName
}
}
`;
What I want:
I want to change my form in such a way that if the user enters only the firstName and leaves the lastName field blank, then only firstName should be updated, meaning that the first type of query should be used and the lastName should remain what it was before the mutation was called.
What's Happening Now:
For instance, previously the firstName was HELLO and lastName was WORLD. Now, I am updating the firstName to CHECK and leaving the lastName option blank. So when it returns values, it should return CHECK as the firstName and un-modified WORLD as the lastName. However, right now, it shows lastName as undefined. If I inspect the Resources, I see this:
{"operationName":"UpdateUser","variables":{"email":"[email protected]","firstName":"Final"},"query":"mutation UpdateUser($email: String!, $firstName: String, $lastName: String) {\n updateUser(email: $email, input: {firstName: $firstName, lastName: $lastName}) {\n id\n firstName\n __typename\n }\n}\n"} Looks like the lastName is still being passed in the mutation.
which means that the lastName is still being used in the mutation. So, I need a way to pass custom variables into my query:
$input : Object!doesn't work.
Here's the code for my whole page:
export default function UpdateUserPage() {
const [isSubmitted, setIsSubmitted] = useState(false);
const [isUpdated, setIsUpdated] = useState(false);
const [updateUser] = useMutation(UPDATE_USER);
let submitForm = (
email: string,
firstName: string,
lastName: string,
) => {
setIsSubmitted(true);
if (email && (firstName || lastName || phoneNumber)) {
const vars:any = {
email
};
if( firstName !== ''){
vars.firstName = firstName}
if( lastName !== ''){
vars.lastName = lastName}
updateUser({
variables: vars})
.then(({ data }: any) => {
setIsUpdated(true);
console.log(updateUser);
console.log('FN: ', data.updateUser.firstName);
console.log('LN: ', data.updateUser.lastName);
})
.catch((error: { message: string }) => {
setIsUpdated(false);
});
}
};
return (
<div>
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
phoneNumber: '',
}}
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: FormEvent) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
};
return (
<div className="main-content">
<form
style={{ width: '100%' }}
onSubmit={e => {
e.preventDefault();
submitForm(email, firstName, lastName);
}}>
<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')}
/>
<CustomButton
text={'Update User Info'}
/>
</div>
</form>
</div>
);
}}
</Formik>
</div>
);
}
Edit:
From the schema:
input: UpdateUserInput!
input UpdateUserInput {
email: String
firstName: String
lastName: String
phoneNumber: String
}
Now, I have done this:
interface UpdateUserInput {
email: String
firstName: String
lastName: String
phoneNumber: String
}
export const UPDATE_USER = gql`
mutation UpdateUser($email: String!, $input : UpdateUserInput) {
updateUser(
email: $email
input: $input
) {
id
firstName
}
}
`;
However, when I submit the form, I still get this error:
GraphQL error: The variable `input` type is not compatible with the type of the argument `input`.
Expected type: `UpdateUserInput`.
Probably because I'm still passing vars from my main UpdateUserPage. How would I change that?