Hello Everyone, in this part of the GraphQL series, we are going to fetch data using the Apollo Client package.
Inside the "Queries.ts" file which we had created in previosu part, add this code at the bottom.
export const CREATE_USER = gql`
mutation CreateUser($newUser: CreateUser!) {
createUser(newUser: $newUser) {
role
name
isEmployee
age
}
}
`;
export const UPDATE_USER = gql`
mutation UpdateUser($updatedUser: UpdateUser!) {
updateUser(updatedUser: $updatedUser) {
id
name
role
age
isEmployee
}
}
`;
So we have created a query for Adding a user with role,name, isEmployee and age fields and same for Updating a user
Imports
import { useMutation } from "@apollo/client";
import { CREATE_USER, UPDATE_USER, ALL_USERS } from "./Queries";
import { useCounterStore } from "./UsersList";
- We have imported useMutation hook to attach the method with onClick and onSubmit event handlers
- CREATE_USER, UPDATE_USER and ALL_USER are our queries
- useCounterStore from our UserList component to access states and their setter functions
Accessing the states and setter functions
...
const CreateUser = () => {
const id = useCounterStore((state) => state.id);
const name = useCounterStore((state) => state.name);
const setName = useCounterStore((state) => state.setName);
const age = useCounterStore((state) => state.age);
const setAge = useCounterStore((state) => state.setAge);
const role = useCounterStore((state) => state.role);
const setRole = useCounterStore((state) => state.setRole);
const isEmployee = useCounterStore((state) => state.isEmployee);
const setIsEmployee = useCounterStore((state) => state.setIsEmployee);
const isUpdate = useCounterStore((state) => state.isUpdate);
const setIsUpdate = useCounterStore((state) => state.setIsUpdate);
...
Input fields handler methods
...
const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
const handleAgeChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setAge(Number(event.target.value));
};
const handleOptionChange = (
event: React.ChangeEvent<HTMLInputElement>
): void => {
setIsEmployee(event.target.value === "true");
};
const handleRoleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setRole(event.target.value);
};
...
- Creating handler method for each input
Creating methods for add and update user
...
const [createUser] = useMutation(CREATE_USER, {
refetchQueries: [{ query: ALL_USERS }],
});
const [updateUser] = useMutation(UPDATE_USER, {
refetchQueries: [{ query: ALL_USERS }],
});
...
- createUser and updateUser are our methods which we can attach to our event listeners, inside useMutation, we have 2 params, first one is the query itself, second one is a refetch method, so whenever we add or update a user, ALL_USER query will run along with it and display the latest data in real time.
Form inputs
...
return (
<form className="flex flex-wrap items-center justify-center gap-5 py-5 px-4 bg-gradient-to-r from-slate-800 to-black">
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Name</label>
<input
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl"
type="text"
value={name}
onChange={handleNameChange}
/>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Age</label>
<input
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl"
type="number"
value={age}
onChange={handleAgeChange}
/>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Role</label>
<select value={role}
onChange={handleRoleChange}
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl">
<option> WebDeveloper</option>
<option>Tester</option>
<option>SoftwareEngineer</option>
</select>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<p className="font-semibold text-white">Employee</p>
<label className="text-white">
<input
type="radio"
value="true"
checked={isEmployee === true}
onChange={handleOptionChange}
/>
True
</label>
<label className="text-white">
<input
type="radio"
value="false"
checked={isEmployee === false}
onChange={handleOptionChange}
/>
False
</label>
</div>
...
- We have created 2 input fiels for name and age, select field for role and radio inputs for employee status.
Button condition for Add or Update
...
<div className="flex justify-center w-full md:w-fit ml-4 md:ml-0">
{isUpdate ? (
<>
<button
className="px-4 py-2 rounded-lg bg-blue-400 text-white"
onClick={(e) => {
e.preventDefault();
if (name === "" || role === "") {
alert("Fill all the details");
} else {
updateUser({
variables: {
updatedUser: {
id,
name,
age,
role,
isEmployee,
},
},
}).then(() => {
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
});
setIsUpdate(false);
}
}}
>
Update
</button>
<button
className="px-4 py-2 rounded-lg bg-red-400 text-white ml-3"
onClick={() => {
setIsUpdate(false);
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
}}
>
Cancel
</button>
</>
) : (
<button
className="px-4 py-2 rounded-lg bg-blue-600 text-white"
onClick={(e) => {
e.preventDefault();
if (name === "" || role === "") {
alert("Fill all the details");
} else {
createUser({
variables: {
newUser: {
name,
age,
role,
isEmployee,
},
},
}).then(() => {
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
});
}
}}
>
Add
</button>
)}
</div>
...
- We are checking for a isUpdate state, if it is true, show update button with updateUser method and if it is false, show add button with createUser method.Inside both the methods for create or update user, we have variable object and inside it we have the object with name same as the query param name which is "newUser" for createUser and "updateUser" for updateUser We are going to control this state from Display Component which we will discuss in next part of this series.
Complete code
import { useMutation } from "@apollo/client";
import { CREATE_USER, UPDATE_USER, ALL_USERS } from "./Queries";
import { useCounterStore } from "./UsersList";
const CreateUser = () => {
const id = useCounterStore((state) => state.id);
const name = useCounterStore((state) => state.name);
const setName = useCounterStore((state) => state.setName);
const age = useCounterStore((state) => state.age);
const setAge = useCounterStore((state) => state.setAge);
const role = useCounterStore((state) => state.role);
const setRole = useCounterStore((state) => state.setRole);
const isEmployee = useCounterStore((state) => state.isEmployee);
const setIsEmployee = useCounterStore((state) => state.setIsEmployee);
const isUpdate = useCounterStore((state) => state.isUpdate);
const setIsUpdate = useCounterStore((state) => state.setIsUpdate);
const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
const handleAgeChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setAge(Number(event.target.value));
};
const handleOptionChange = (
event: React.ChangeEvent<HTMLInputElement>
): void => {
setIsEmployee(event.target.value === "true");
};
const handleRoleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setRole(event.target.value);
};
const [createUser] = useMutation(CREATE_USER, {
refetchQueries: [{ query: ALL_USERS }],
});
const [updateUser] = useMutation(UPDATE_USER, {
refetchQueries: [{ query: ALL_USERS }],
});
return (
<form className="flex flex-wrap items-center justify-center gap-5 py-5 px-4 bg-gradient-to-r from-slate-800 to-black">
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Name</label>
<input
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl"
type="text"
value={name}
onChange={handleNameChange}
/>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Age</label>
<input
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl"
type="number"
value={age}
onChange={handleAgeChange}
/>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<label className="font-semibold text-white">Role</label>
<select value={role}
onChange={handleRoleChange}
className="border border-blue-400 px-2 py-1 w-52 rounded-2xl">
<option> WebDeveloper</option>
<option>Tester</option>
<option>SoftwareEngineer</option>
</select>
</div>
<div className="flex gap-4 justify-between w-full md:w-fit items-center">
<p className="font-semibold text-white">Employee</p>
<label className="text-white">
<input
type="radio"
value="true"
checked={isEmployee === true}
onChange={handleOptionChange}
/>
True
</label>
<label className="text-white">
<input
type="radio"
value="false"
checked={isEmployee === false}
onChange={handleOptionChange}
/>
False
</label>
</div>
<div className="flex justify-center w-full md:w-fit ml-4 md:ml-0">
{isUpdate ? (
<>
<button
className="px-4 py-2 rounded-lg bg-blue-400 text-white"
onClick={(e) => {
e.preventDefault();
if (name === "" || role === "") {
alert("Fill all the details");
} else {
updateUser({
variables: {
updatedUser: {
id,
name,
age,
role,
isEmployee,
},
},
}).then(() => {
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
});
setIsUpdate(false);
}
}}
>
Update
</button>
<button
className="px-4 py-2 rounded-lg bg-red-400 text-white ml-3"
onClick={() => {
setIsUpdate(false);
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
}}
>
Cancel
</button>
</>
) : (
<button
className="px-4 py-2 rounded-lg bg-blue-600 text-white"
onClick={(e) => {
e.preventDefault();
if (name === "" || role === "") {
alert("Fill all the details");
} else {
createUser({
variables: {
newUser: {
name,
age,
role,
isEmployee,
},
},
}).then(() => {
setName("");
setAge(18);
setRole("");
setIsEmployee(false);
});
}
}}
>
Add
</button>
)}
</div>
</form>
);
};
export default CreateUser;
In the next part of this GraphQL series, we will cover the update and delete feature for our data using "useMutation" hook.
THANK YOU FOR CHECKING THIS POST
You can contact me on -
Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com
^^You can help me with some donation at the link below Thank you👇👇 ^^
☕ --> https://www.buymeacoffee.com/waaduheck <--
Also check these posts as well
https://dev.to/shubhamtiwari909/website-components-you-should-know-25nm
https://dev.to/shubhamtiwari909/smooth-scrolling-with-js-n56
https://dev.to/shubhamtiwari909/swiperjs-3802
https://dev.to/shubhamtiwari909/custom-tabs-with-sass-and-javascript-4dej
Top comments (0)