Snapgram Edit Profile
Task 🎯
Your goal is to develop a completely functional “Edit Profile” page
Example 🧩
Visit the Figma Design and see how the feature should look like
Resources 📖
-
Mutation
-
useMutation API Reference
-
React Hook Form
-
How to use Zod with TypeScript & React Hook Form
-
Shadcn Form
Hint 💡
Stuck somewhere? No worries, we’re here to help!
Ask yourself —
What is expected (The Output)?
We want a new page where the user will be able to edit their profile details, i.e., name, bio, and profile image
What do we need in order to build that?
- A new page
- Shadcn form elements
- Appwrite API
- Tanstack/React query mutations
- ….?
We have already learned how to create a form using shadcn, react hook form, and Zod. So without any further delay, start by setting up the form UI on the new page:
- Create a new route for the Edit Profile
- Setup the Form field using the shadcn for
- Name (Input text)
- Username (Input text)
- Email (…)
- Bio (…)
- At the top, use the FormField of shadcn again to create the file uploader
- Create a new file to handle the Profile upload
- If you see, the code will be almost similar to what we did inside the
FileUploader
. All the drag-drop logic will be the same. The only change that you would have to make is the inside UI. The UI has only two elements. In which direction are they? Think!
Think more and try it out.
Next,
- Set up the default state for each of these fields along with the zod validation so we can show the user what current values that user has
const form = useForm<z.infer<typeof ProfileValidation>>({**resolver: zodResolver(ProfileValidation),defaultValues: {file: [],name: user.name,username: user.username,email: user.email,bio: user.bio || "",},**});
- Create the
**handleUpdate**
function and retrieve the latest data that has been updated
Now time to create the mutation,
- Create a new mutation hook
useUpdateUser
which will be responsible for handling the mutationexport const useUpdateUser = () => {return useMutation({// ...});}; - Similar to what we have with
useQuery
, i.e.,queryFn
we havemutateFn
with mutations to perform the desired action. For this function, assign the Appwrite APIexport const useUpdateUser = () => {return useMutation({mutationFn: (user: IUpdateUser) => updateUser(user),});}; - Lastly, regarding the mutation query, we need to do something when the request has been successfully completed. Do you remember anything that we did with creating posts or similar?
Yes, validate!
Think about which queries we’ll have to validate on success of this mutation so we’ll see the instant change on the UI.
- Current User?
- …?
Now, let’s develop the updateUser
API function,
- Create the
updateUser
with a try-catch block - First, validate the image and see if the user has really changed the image
- If yes, then use the
uploadFile
function we created before to upload the new image- And immediately after that, delete the previous image from the storage
- If no, do nothing
- If yes, then use the
- Using the New image data (if any) along with others, call the appwrite update function.
What we’ll need for that again?
- Appwrite
databases.updateDocument
- Database ID
- Collection ID
- User ID (the one that we’ll be updating)
- User data (the data that we want to update)
- Appwrite
So far, all good?
Now call this mutation hook, i.e., useUpdateUser
inside the Edit Profile page. It’ll give us plenty of things back. Refer to the resources shared above for Mutation API to know what we get.
Among these many others, the mutation hook will provide us the mutate async function, which we can call anywhere:
const { mutateAsync: updateUser, isLoading: isLoadingUpdate } = useUpdateUser();
So, what are you waiting for? Call this renamed mutateAsync function inside the **handleUpdate
** function, pass the necessary data and check how it’s working 😃
These challenges or features are more logic-oriented, and there may be other solutions. So take your time, think carefully, develop your logical abilities, and give it a try.
We believe in your capabilities ❤️