Source

src/hooks/useProfile.ts

// This file houses crud methods to interact with user profile data on the server. They are generally called by react query mutations.

import axios, { AxiosRequestConfig } from "axios"
import { QueryClient, useMutation, useQuery, useQueryClient } from "react-query";
import { API_URL, reportAxiosError } from "../globals"
import { authStore } from "../stores/AuthStore";
import { useAuth } from "./useAuth";

/**
 * Interface that contains data in a user's profile.
 */
export interface UserProfile {
    /**
     * The user's id
     */
    id?: string
    /**
     * The user's username
     */
    username?: string
    /**
     * The user's email
     */
    email?: string
    /**
     * The user's base64 encoded profile picture.
     */
    picture?: string
}

/**
 * A custom hook containing [react-query]{@link https://react-query.tanstack.com/} queries and mutations and other logic related to interacting with {@link UserProfile} objects.
 * @category Hooks
 * @namespace useProfile
 */
export const useProfile = (userId: string) => {
    /**
     * The local instance of the [react-query QueryClient]{@link https://react-query.tanstack.com/reference/QueryClient#_top}.
     * @memberOf useLandmarks
     */
    let queryClient: QueryClient;

    try {
        queryClient = useQueryClient()
    } catch (error) {
        console.log("Something went wrong when retrieving query client:")
        console.log(error)
    }

    const { refreshAccessToken } = useAuth();

     /**
     * The callback responsible for retrieving the {@link Profile} matching the given ID from the API , used by the [react-query useQuery]{@link https://react-query.tanstack.com/reference/useQuery#_top} hook.
     * * @memberOf useProfile
     */
    const getProfile = async (id: string) => {
        const config: AxiosRequestConfig = {
            method: 'GET',
            url: API_URL + `/api/user-profile/${id}/`,
            headers: { "Authorization": "Bearer " + authStore.accessToken, }
        } 

        try {
            const response = await axios(config);   
            return response.data;
        } catch (error) {
            if (error.response.status == 401) {
                try {
                    await refreshAccessToken()    
                    const response = await axios({...config, headers: { "Authorization": "Bearer " + authStore.accessToken }});   

                    return response.data;
                } catch (error) {
                    // refreshAccessToken will report errors
                }
            }

            reportAxiosError('Something went wrong when retrieving landmarks', error)
            throw new Error;
        }
    }

    // get query
    const { data: profile, status: getProfileStatus } = useQuery<UserProfile, Error>(['getProfile', userId], async () => getProfile(userId))

    return { profile, getProfileStatus } //reading 
}