Is there any way to fetch the last eg.30 rows in d...
# help
t
Is there any way to fetch the last eg.30 rows in descending order? I tried with ascending: false but the order is not correct. The last item of table is first on fetched array.
n
Hello @theuknowner! This thread has been automatically created from your message in #843999948717555735 a ``few seconds ago``. Pinging @User so that they see this as well! 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.
n
theuknowner (2022-03-28)
s
and https://supabase.com/docs/reference/javascript/range. Some combo should allow you to get something sorted.
t
I tried with ascending: false but as I wrote, I get incorrect results. The order is wrong
I get the items like: 0 -> 450, 1 -> 499 ...29 - > 421. I want to get on 29 position the item with ID 450. So it should be in descending order
I tried with -> .limit(30) .range(0,30) .order('id', { ascending: false}) . but I get the same results wrong order
s
> 0 -> 450, 1 -> 499 ...29 - > 421 I don't understand what you're showing here. Are you getting rows with ID's in this order:
[0, 1, 2, 3, 4, ..., 450]
? What is the
1 -> 499
and
...29 -> 421
showing us? If you do a
range(30, 100).order('id', {ascending: false})
, do you get results with ID's in the order
[100, 99, 98, 97, 96, ..., 33, 32, 31, 30]
?
t
Yes these are ids in the array position
[{id:450},{id:449}]
I'll explain it to you better, I have a table named cities, in this table there are cities with IDs (incremented) from 1 - 450. I want to fetch the last 30 cities
g
use .limit(30) instead of range
t
let cityList = await supaClient .from('cities') .select('*') .limit(30) .range(0,30) .order('id', { ascending: false})
I tried with limit also
g
drop range
t
My original code was without range
same results
let cityList = await supaClient .from('cities') .select('*') .limit(30) .order('id', { ascending: false})
What I mean by wrong order, it fetches the last 30 rows but the order in fetched array is in ascending order. That's why the 1st object of the array ([0]) has the id 450 and the last item ([29]) has the id 420
g
const { data:messages, error:error1 } = await supabase .from('test') .select('*') .limit(5) .order('id',{ascending:false})
t
It should be the opposite. 29 -> 450, 0-> 420
s
So...
data.reverse()
if you want the indexes reversed?
t
So only on client side can I achieve this?
s
The DB is bringing back the data you wanted in the order you asked for it. The indexes in the JS side of things are completely independent. Index 0 will map to 450 because it's in descending order from the end as you asked.
t
Okay so the only way is on client side with reverse
I was thinking if it was the same as Firebase. In firebase you get the last eg. 30 items using orderByKey().limitToLast(30)
and the order is like object 0-> 420.... object 29 -> 450
g
I think limitToLast is only on their realtime Database. When I used Firestore database it worked the same as here.
t
Yes, I was using the Realtime Database
I switch from Realtime Database to Supabase
@User What's the best way to fetch the next X number of items? For example, I have fetched the item with ID 450 and I want to fetch the next items with ID 451 etc. but the exact number of items is unknown. So I want to fetch all items starting from id 450. Is this possible? In firebase I can use -> orderByKey().startAt('value-key-id')
g
@User Actually you could also use a .range(451,500) and it will return what it can. This is the best way for pagination. Normally you have filters on your data like by user_id and so id column is not useful as a direct number. Range is on your query result set.
t
Yes but If i don't know the item's row (451)? For example, I have stored 100 items in db, user fetches the last 30 , I save the last 30 items in an indexed db. When the user logs in again, I want to fetch the next items of the last 30 if exist. In firebase i would do it with startAt(last saved index id), with range I should know from the beginning
g
Same here sort of. Limit is the number of the result in query, not the id of the row. So if you don't change the query, then if you fetched 100 last time, you start at 100 this time.
This ignores deletes and such.
t
In firebase is the key id of item
startAt(eg. id) and fetches all next items
I understand what you you, it would be (0,50) , next fetch (100, 50) , (200,50) etc like offset
g
You can do .gt(‘id’, 450).limit(30)
t
Yes I think that's the best-easiest way
and without limit can fetch all next items
g
@User You say you are storing these to indexedDb. That works fine if the saved rows never change or are not deleted on the server. If they do your, indexedDb data will be stale. Since you are coming from Firebase, just wondering. I cache data to indexedDb, but rely on live database queries when user logs in to get current "live" record numbers in case some have been deleted. I also always write a new record if data changes and delete the old record versus updating...
a
If you really want to do it on the server side, you can create a stored procedure that subqueries your filtered set and restores ascending order,
Copy code
select * from (
  select * from cities order by id desc limit 30
) order by id asc
t
@User It's for my chat module. So the flow is like this: 1) User fetches last 30 msgs from DB, I store them in Indexed DB. When he receives a new msg, I append the msg to array and I store it in indexed db also. If user is not connected when he received the msgs, I check the last msg id of conv with the last id of stored conv. If they are different, I fetch all new msgs and store them in indexed db as well.
@User I think sorterring the results on client side is easier
g
Sounds good for chat as messages don’t change or get deleted that might be in indexedDb.
t
@User I have created a conversations table in which every user can listen for update. In conversation table I store id, participants etc, and Last message details. So instead of having multiple listeners for each conversation, I have one listener on conversations table and the user is notified when the last message id has been changed. Is there any way to fetch specific columns on Update event for realtime listener? I want to fetch only the columns with the last_message (last_message_id, lastMessage_sentBy etc..) not the whole row.
g
You get the whole row, although that would be a good feature request, at least to just get primary key(s)
t
Yes that would be very useful