Karl Wolf
Karl Wolf

Reputation: 363

React/Supabase Response types for complex queries not working with filter

I am using React with Typescript and Supabase. To create a type from a complex query I use the schema provided by supabase like this:

import { QueryResult, QueryData, QueryError } from '@supabase/supabase-js'

const countriesWithCitiesQuery = supabase
  .from("countries")
  .select(`
    id,
    name,
    cities (
      id,
      name
    )
  `);
type CountriesWithCities = QueryData<typeof countriesWithCitiesQuery>;

const { data, error } = await countriesWithCitiesQuery;
if (error) throw error;
const countriesWithCities: CountriesWithCities = data;

In my example I use the query to fetch the data of two users and want to compare the groups that they are in. So I have my query like the following:

export const fetchUserWithGroups = supabase
  .from('user')
  .select('*, groups: group_user_mapping ( group: event_group ( * ) )')

But the way I am fetching the data looks like this. Because I need to be able to load this data for multiple users I filter the data by the UserId.

const response = await fetchUserWithGroups
      .eq('userId', userId)
      .maybeSingle();

I call the requests directly after each other in two Promises. After the first one is finished, I call the second one.

The problem The first request works just like expected. I query the data by the userId and I get the result I want. But in the second request somehow the filters get combined, so instead of .eq("userId", <user_2_id>) I see in my network tab the following: .eq("userId", <user_1_id>).eq("userId", <user_2_id>). Therefore I dont get any result because I cannot have a user with two different ideas.

I don't really know why this is happening. Maybe you can :)

Upvotes: 0

Views: 59

Answers (1)

Karl Wolf
Karl Wolf

Reputation: 363

Okay so the problem was that the query was directly used again and I did not check if it was a new QueryBuilder. To fix this and still keep my type definitions I did the following:

I turned the query builder into a function that returns me a new query every time

export const fetchUserWithGroups = () => supabase
  .from('user')
  .select('*, groups: group_user_mapping ( group: event_group ( * ) )')

To still create the type from that query I had to change my type creation

type UserWithGroupsBase = QueryData<ReturnType<typeof fetchUserWithGroups>> extends Array<infer U> ? U : never;

Just to make it clear. This code above creates a single type that is returned from the query wich otherwise would be an array of the given type. With the keyword ReturnType<typeof fetchUserWithGroups> I got the result I tried to achieve.

Upvotes: 0

Related Questions