supabase-js icon indicating copy to clipboard operation
supabase-js copied to clipboard

Storing part of a query in a variable and reusing it causes unexpected behaviors

Open dshukertjr opened this issue 1 year ago • 4 comments

Bug report

  • [x] I confirm this is a bug with Supabase, not with my own application.
  • [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

Storing part of a query in a variable is a common pattern in Firebase development. Right now because our client library is not immutable, when you try to do this with Supabase client library, some of the information is kept in the original instance causing unexpected behaviors.

const restaurantsTable = supabase.from('restaurants')

const { data: restaurant } = await restaurantsTable.select().eq('id', id).single()
const { data: restaurants } = await restaurantsTable.select() // the query here will contain the `eq` and `single` statement from the previous line, therefore returning a single restaurant.

Expected behavior

Storing part of a query in a variable and running multiple queries using it should return the proper data.

const restaurantsTable = supabase.from('restaurants')

const { data: restaurant } = await restaurantsTable.select().eq('id', id).single()
const { data: restaurants } = await restaurantsTable.select() // `restaurants` contains the unfiltered query result.

Additional context

Maybe this is something to keep in mind when doing the next major release.

dshukertjr avatar May 02 '23 05:05 dshukertjr

+1 to this. Its seems like the chaining of methods is mutating the original query, so you can't re-use it.

kurtisauc3 avatar Jan 28 '24 17:01 kurtisauc3

Having same issue :(

brettmwright avatar Mar 20 '24 14:03 brettmwright

Same issue - It would be great when I have a join and end up generating a type for it, I could do those once somewhere where I can export the query and type so I'm not doing the same thing over and over again; however this makes that very awkward because only the type is reusable and not the query.

rjbrooksjr avatar May 20 '24 15:05 rjbrooksjr

What we've done that seems to work is to write a function that builds the query.

Let's say for example that you want to fetch a list of messages in a thread. Create the query in a function:

function buildThreadMessagesQuery(threadId: number) {
  return supabaseClient
    .from('messages')
    .select('id, text, created_at')
    .eq('thread_id', threadId)

}

Call that function whenever you need the query; you can even modify it here without it affecting other uses of the function:

let query = buildThreadMessagesQuery(threadId);
query = query.order('created_at')

const { data, error } = await query();

jhwheeler avatar Sep 24 '24 08:09 jhwheeler