_tl;dr - anyone know why `maybeSingle()` errors wh...
# help
x
tl;dr - anyone know why
maybeSingle()
errors when 0 rows are returned? I thought that was the whole point of it over
.single()
I've got a many:many join table called `teams_users`:
Copy code
ts
id // auto-increment
created_at // NOW()
team_id // foreign key teams.id
user_id // foreign key users.id
When I do the following:
Copy code
ts
supabase
  .from("teams_users")
  .select("id")
  .match({ team_id, user_id })
  .maybeSingle();
I get an
406 Not Acceptable
error:
Copy code
json
{
  "message":"JSON object requested, multiple (or no) rows returned",
  "details":"Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row"
}
The docs are pretty barebones atm so difficult to learn from but includes this quote: > Result must be at most one row (e.g. using eq on a UNIQUE column), otherwise this will result in an error. The
e.g. using eq on a UNIQUE column
strikes me as just an example, can
maybeSingle()
ONLY be used after passing a primary key in to
.match/.eq
?
n
Hello @xephyr! 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.
x
It's not the biggest problem, I've sidestepped it by doing
Copy code
ts
const { data, error } = await supabase
  .from("teams_users")
  .select("id")
  .match({ team_id, user_id });

if ((data || []).length > 0) doTheThings();
as opposed to the neater and preferred:
Copy code
ts
const { data, error } = await supabase
  .from("teams_users")
  .select("id")
  .match({ team_id, user_id })
  .maybeSingle();

if (data) doTheThings();
But I am curious as to why it doesn't work as expected.
g
So are you actually getting an error back from the await? The network response will have 406, but the postgrest.js code checks for the error and returns correct data with error = null for the case of 0 rows.
Copy code
maybeSingle(): PromiseLike<PostgrestMaybeSingleResponse<T>> {
    this.headers['Accept'] = 'application/vnd.pgrst.object+json'
    const _this = new PostgrestTransformBuilder(this)
    _this.then = ((onfulfilled: any, onrejected: any) =>
      this.then((res: any): any => {
        if (res.error?.details?.includes('Results contain 0 rows')) {
          return onfulfilled({
            error: null,
            data: null,
            count: res.count,
            status: 200,
            statusText: 'OK',
            body: null,
          })
        }

        return onfulfilled(res)
      }, onrejected)) as any
    return _this as PromiseLike<PostgrestMaybeSingleResponse<T>>
  }
n
xephyr (2022-05-08)
x
Looks like that's exactly what I get yeah, do we know why it is returning 406 when the status 200/OK though?
g
It is supabase.js (actually postgres.js) hiding the error from single() to PostgREST. There is really no method to do maybeSingle() there, so they just know they can ignore that specific error and return in data/error what you would expect.
x
Ah oaky, so if I want clean console/network tab I should
.limit(1)
or omit the modifier entirely and just handle it as I did above? (
.length > 0
etc)
g
limit 1 would return an array of 1 item or empty array, so as long as you can deal with that yes.
Oh except it won't error if there were 2 results on the server....