reactjs - Supabase join returnează 1 obiect în loc de listă de obiecte
Încerc să interoghez tabelul meu posts pentru o postare, care conține user_id al utilizatorului și vreau să îl alătur cu tabelul profiles folosind user_id.
schema tabel post: (post_id: uuid, created_at: timestamptz, image_url: text, user_id: uuid, num_likes: integer, description: text) Relația mea de cheie străină este configurată pe Supabase cu acest tabel și profilurile pentru user_id.
schema tabelului profiles: (user_name: text, first_name: text, last_name: text, is_premium: boolean, user_id: uuid, num_posts: smallint, num_followers: integer, num_following: integer)
când încercați să interogați tabelele cu:
const { data, error } = await supabase
.from("posts")
.select(
`post_id, created_at, image_url, user_id, num_likes, description, profiles ( user_id, user_name, first_name, last_name, num_followers, num_following, num_posts, is_premium )`
)
.limit(1)
.single();
Nu primesc erori și primesc corect informațiile despre profilul unui utilizator, dar data.profiles este de așteptat să fie un array. Cu toate acestea, nu returnează un array, ci returnează doar un obiect unic pentru data.profiles.
exemplu de ceea ce returnează interogarea:
Object {
"created_at": "2023-07-29T15:54:53.849017+00:00",
"description": "This is a description",
"image_url": "NULL",
"num_likes": 3,
"post_id": "e0392738-5085-4026-9446-56e4bde69fee",
"profiles": Object {
"first_name": "John",
"is_premium": true,
"last_name": "Doe",
"num_followers": 0,
"num_following": 0,
"num_posts": 0,
"user_id": "108a1e53-1df6-4baf-a4ca-f0c445f085d2",
"user_name": "User123",
},
"user_id": "108a1e53-1df6-4baf-a4ca-f0c445f085d2",
}
dar acesta este tipul așteptat:
data: {
post_id: any;
created_at: any;
image_url: any;
user_id: any;
num_likes: any;
description: any;
profiles: {
user_id: any;
user_name: any;
first_name: any;
last_name: any;
num_followers: any;
num_following: any;
num_posts: any;
is_premium: any;
}[];
}
Mai mult context: Iată funcția needitată care apelează din supabase:
export const getNextPost = createAsyncThunk(
"getNextPost",
async (payload: {
lastPostCreatedAt: string;
}): Promise<(postsTableRow & { profiles: profilesTableRow }) | null> => {
const { data, error } = await supabase
.from("posts")
.select(
`post_id, created_at, image_url, user_id, num_likes, description, profiles ( user_id, user_name, first_name, last_name, num_followers, num_following, num_posts, is_premium )`
)
.order("created_at", { ascending: false })
.lt("created_at", payload.lastPostCreatedAt)
.limit(1)
.single();
if (error?.code === "PGRST116") return null;
if (error) console.warn(error);
console.log("DATA:", data);
return data as postsTableRow & { profiles: profilesTableRow };
}
);
dacă schimb tipul de returnare de la: Promise<(postsTableRow & { profiles: profilesTableRow }) | null> la Promise<(postsTableRow & { profiles: profilesTableRow[] }) | null>
Avertizarea compilatorului dispare, dar încă returnează un profilesTableRow, nu profilesTableRow[] așteptat
Răspuns #1
Ca soluție temporară, conversia rezultatului ca unknown și apoi la tipul corect rezolvă eroarea. În cazul meu am făcut data?.profiles as unknown as profilesTableRow astfel încât data.profiles să nu mai fie așteptat să fie un array (deși deja nu este un array).
Se pare că este doar un bug al supabase
Răspunsul #2
Am găsit o soluție mult mai bună: Se pare că generarea de tipuri pentru clientul supabase, folosind cli-ul supabase, pare să fi rezolvat și această problemă. Documentația Supabase: https://supabase.com/docs/guides/api/rest/generating-types