What the heck am I doing wrong here? ```js cons...
# help
e
What the heck am I doing wrong here?
Copy code
js
  const getWriterData = async () => {
    if (session) {
      const { data: writerProfile, error } = await supabase
        .from('writer_profiles')
        .select('desired_title')
        .eq('id', session.user.id)
        .maybeSingle()
      return writerProfile
    }
  }

  useEffect(() => {
    getWriterData().then((writerProfile) => {
      setWriterData(writerProfile)
    })
  }, [getWriterData])
n
Hello @edgaras! This thread has been automatically created from your message in #843999948717555735 a few seconds ago. We have already mentioned the @User so that they can see your message and help you as soon as possible! Want to unsubscribe from this thread? Right-click the thread in Discord (or use the ``...`` menu) and select "Leave Thread" to unsubscribe from future updates. Want to change the title? Use the ``/title`` command! We have solved your problem? Click the button below to archive it.
g
Been awhile since I used react, but having getWriterData as the “trigger” for your useEffect doesn’t not seem right. You don’t say what your error is or what is not working though. If you are not getting data back in getWriterData call that means you don’t have a session yet.
n
Edg (2022-05-30)
e
Seems like this fixed the problem:
Copy code
js
  const getWriterData = async () => {
    if (session) {
      const { data, error } = await supabase
        .from('writer_profiles')
        .select('desired_title')
        .eq('id', session.user.id)
        .maybeSingle()
      console.log(data)
      setWriterData(data)
    }
  }

  useEffect(() => {
    getWriterData()
  }, [session])
but I am not big fan of putting the
setWriterData(data)
inside getWriterData function, because then it's specific to this particular page, and will be hard to move function to a seperate file later...
r
This helps tremendously with async load in React: https://github.com/streamich/react-use/blob/master/docs/useAsync.md
j
@edgaras let the function take a callback then?
f
Copy code
javascript
const { isLoading, isError, data: writerProfile, error } = useQuery('writerData', getWriterData)
e
Nice libs, but I want to try to keep things without dependencies for now... I ended up with this:
Copy code
js
  useEffect(() => {
    ;(async () => {
      if (session) {
        const { data, error } = await postData<any>(
          '/api/writer/get-or-create',
          {},
          session.access_token
        )
      }
    })()
  }, [session])
Is that weird? Also had to move the fetch logic to API route for security. (postData is a helper function):
Copy code
js

export async function postData<T>(
  url: string,
  body: unknown,
  token?: string
): Promise<{
  data: T | null
  error: unknown | null
}> {
  try {
    const response = await axios.post(url, body, {
      headers: {
        'Content-Type': 'application/json',
        token,
      },
    })

    return {
      data: response?.data ?? null,
      error: null,
    }
  } catch (error) {
    return {
      data: null,
      error: error,
    }
  }
}
j
@edgaras Problem with your useEffect is that session is a complex object ({}) and therefore it will run on every render. You probably want to find something about the session to watch on... in this case cause you're using session.access_token, that's what should be in your dependency array (assuming it's a string). If you have that, it doesn't seem weird.
e
@jaitaiwan oh thanks! I didn't know that useEffect cannot follow object changes. I thought React somehow serialized objects. Doesn't it?
j
@edgaras no unfortunately. The only objects that will work are those that are reactive variables like those created with useMemo or useState. It’s to do with js equality:
{} == {} // false
e
Well, my
session
is defined as a useState
const [session, setSession] = useState<Session | null>(null)
in user-context.tsx file
And it's set when
supabase.auth.session()
or
supabase.auth.onAuthStateChange
is called
Copy code
jsx
  useEffect(() => {
    const session = supabase.auth.session()
    setSession(session)
    setUser(
      session?.user ? { id: session.user.id, email: session.user.email } : null
    )

    const { data: authListener } = supabase.auth.onAuthStateChange(
      (event, session) => {
        setSession(session)
        setUser(
          session?.user
            ? { id: session.user.id, email: session.user.email }
            : null
        )
      }
    )

    return () => {
      authListener?.unsubscribe()
    }
  }, [])
j
I can't see anything wrong with that. I think you could possibly even simplify it more and just
return authListener?.unsubscribe
seems it's a callable function.