T
TanStack4y ago
metropolitan-bronze

Using React Query with Supabase

Hi, i've just started using React Query and i'm a bit confused about how i should use it with supabase. If someone who already have an experience with it could help me, i would be very much appreciated. I getting the current user like this
export const getUser = async () => {
const onFetch = await supabase.auth.getUser();
const userId = onFetch.data.user?.id;
let { data, error } = await supabase
.from("profiles")
.select()
.eq("id", userId);
return error ? error : data;
};

export const useUser = () => {
return useQuery(["user"], () => getUser());
};
export const getUser = async () => {
const onFetch = await supabase.auth.getUser();
const userId = onFetch.data.user?.id;
let { data, error } = await supabase
.from("profiles")
.select()
.eq("id", userId);
return error ? error : data;
};

export const useUser = () => {
return useQuery(["user"], () => getUser());
};
And at the profile screen i'm trying to display the user as const { data, isLoading } = useUser(); But when i try to display any info typescript throws an error. How should i get user info?
10 Replies
stormy-gold
stormy-gold3y ago
@Talajax did you figure this out?
metropolitan-bronze
metropolitan-bronzeOP3y ago
Hi Yeah, i don't remember now, but i think the problem was how i was calling the data Do you have the same problem?
quickest-silver
quickest-silver3y ago
@Domcario what issues are you having? I recently set this up (two days ago)
export const getUserInfo = async () => {
const { data, error } = await supabase.from("users").select("*");
if (error) {
throw new Error(error.message);
}
return { ...data[0] };
};

export const useGetUserInfo = () => {
return useQuery(["userInfo"], getUserInfo);
};
export const getUserInfo = async () => {
const { data, error } = await supabase.from("users").select("*");
if (error) {
throw new Error(error.message);
}
return { ...data[0] };
};

export const useGetUserInfo = () => {
return useQuery(["userInfo"], getUserInfo);
};
stormy-gold
stormy-gold3y ago
@Talajax @Premiare my business logic is: 1. get current supabase user's id 2. fetch company_id value from the preview_users supabase table by filtering for current user's id 3. feed company_id into a axios fetch request for an nextjs api route useEvents.jsx
import { useQuery } from "@tanstack/react-query";
import { supabase } from "../../utils/supabase utils/supabaseClient";

const fetchUserAndCompanyData = async (userID) => {
if (!userID) {
console.log('userID is undefined');
return null; // or return an empty object
}

const { data, error } = await supabase
.from(`${process.env.NEXT_PUBLIC_VERCEL_ENV != undefined ? `${process.env.NEXT_PUBLIC_VERCEL_ENV}_users` : `preview_users`}`)
.select('*,company_id(*)')
.eq('uuid', userID)

if (error) {
console.log('error while getting user data: ', error);
return null
}
else {
console.log('data: ', data[0]);
return data
// console.log(data[0].company_id.uuid);
}
}

export default function useEvents() {
const getUserAndData = async () => {
const { data: user, error } = await supabase.auth.getUser();
if (user) {
return fetchUserAndCompanyData(user.id);
}
};

return useQuery(['events'], getUserAndData);
}
import { useQuery } from "@tanstack/react-query";
import { supabase } from "../../utils/supabase utils/supabaseClient";

const fetchUserAndCompanyData = async (userID) => {
if (!userID) {
console.log('userID is undefined');
return null; // or return an empty object
}

const { data, error } = await supabase
.from(`${process.env.NEXT_PUBLIC_VERCEL_ENV != undefined ? `${process.env.NEXT_PUBLIC_VERCEL_ENV}_users` : `preview_users`}`)
.select('*,company_id(*)')
.eq('uuid', userID)

if (error) {
console.log('error while getting user data: ', error);
return null
}
else {
console.log('data: ', data[0]);
return data
// console.log(data[0].company_id.uuid);
}
}

export default function useEvents() {
const getUserAndData = async () => {
const { data: user, error } = await supabase.auth.getUser();
if (user) {
return fetchUserAndCompanyData(user.id);
}
};

return useQuery(['events'], getUserAndData);
}
events.jsx
import useEvents from './useEvents';

export default function MyComponent() {
const { isLoading, isError, data } = useEvents();

if (isLoading) {
return <p>Loading...</p>;
}

if (isError) {
return <p>Error: {isError.message}</p>;
}

return <div>{JSON.stringify(data)}</div>;
}
import useEvents from './useEvents';

export default function MyComponent() {
const { isLoading, isError, data } = useEvents();

if (isLoading) {
return <p>Loading...</p>;
}

if (isError) {
return <p>Error: {isError.message}</p>;
}

return <div>{JSON.stringify(data)}</div>;
}
quickest-silver
quickest-silver3y ago
And what is currently being returned, what's the error? And I'm also assuming the axios request for the api route will go in the else statement?
stormy-gold
stormy-gold3y ago
just realized i can simplify the fetch, let me update it and send with error this time. sorry! ok got it to work now! we chilling
quickest-silver
quickest-silver3y ago
:WICKED:
stormy-gold
stormy-gold3y ago
@Premiare would it be safe to combine these into 1 file? useEvents.jsx
import { useQuery } from "@tanstack/react-query";
import { supabase } from "../../utils/supabase utils/supabaseClient";
import axios from 'axios'

export default function useEvents() {
const getUser = async () => {
const { data: user, error } = await supabase.auth.getUser();
if (user) {
// console.log('user.user.id: ', user.user.id);
return axios(`/api/user/${user.user.id}/events`)
}
};

return useQuery(['events'], getUser);
}
import { useQuery } from "@tanstack/react-query";
import { supabase } from "../../utils/supabase utils/supabaseClient";
import axios from 'axios'

export default function useEvents() {
const getUser = async () => {
const { data: user, error } = await supabase.auth.getUser();
if (user) {
// console.log('user.user.id: ', user.user.id);
return axios(`/api/user/${user.user.id}/events`)
}
};

return useQuery(['events'], getUser);
}
events.jsx
import useEvents from './useEvents';

export default function MyComponent() {
const { isLoading, isError, data } = useEvents();

if (isLoading) {
return <p>Loading...</p>;
}

if (isError) {
return <p>Error: {isError.message}</p>;
}

return <div>{JSON.stringify(data)}</div>;
}
import useEvents from './useEvents';

export default function MyComponent() {
const { isLoading, isError, data } = useEvents();

if (isLoading) {
return <p>Loading...</p>;
}

if (isError) {
return <p>Error: {isError.message}</p>;
}

return <div>{JSON.stringify(data)}</div>;
}
i dont get the point of abstracting it out into 2 files, which some guides ive read suggest? unless i misunderstood them
quickest-silver
quickest-silver3y ago
Well, useEvents.jsx doesn't need to be .jsx It can just be .js And I guess the idea is to keep your queries / mutations separate from your components. https://discord.com/channels/719702312431386674/1074425875128385598 See this file structure thread for more clarity. If you were going to use useEvents in other components, that would be another reason to keep them separate.
stormy-gold
stormy-gold3y ago
ah true, i will be reusing it thanks man!

Did you find this page helpful?