I am trying to flip my query snapshot docs but nothing happens:
export async function getUserPosts(
userId,
getOldPosts = true,
startAfter,
limit = MAX_USER_POSTS_TO_RETRIEVE
) {
...
const query = userPostsRef
.orderBy("date", getOldPosts ? "desc" : "asc")
.startAfter(startAfter);
const querySnapshot = await query.limit(limit).get();
if(!getOldPosts) {
console.log("=== BEFORE ===");
querySnapshot.docs.forEach((prev) => {
console.log(prev.data().date.toDate());
});
// Flip the docs if we are fetching new posts
querySnapshot.docs.reverse(); <-----
console.log("=== AFTER FLIP ===");
querySnapshot.docs.forEach((prev) => {
console.log(prev.data().date.toDate());
});
}
...
}
When I just call my method like this:
getUserPosts("...", false, new Date()); // will execute an orderBy("date", "asc")
Console logs the following data:
=== BEFORE ===
2021-11-08T20:57:31.382Z // (oldest)
2021-11-08T20:57:32.816Z
2021-11-08T20:57:36.130Z // (most recent)
=== AFTER FLIP ===
2021-11-08T20:57:31.382Z // (oldest)
2021-11-08T20:57:32.816Z
2021-11-08T20:57:36.130Z // (most recent)
As you can see, docs are not flipped... I expect to get
=== AFTER FLIP ===
2021-11-08T20:57:36.130Z // (most recent)
2021-11-08T20:57:32.816Z
2021-11-08T20:57:31.382Z // (oldest)
as the result of the operation, and I don't understand why this is not working if the following code does:
const querySnapshot = {
docs: [
{
data: () => ({ timestamp: 1 })
},
{
data: () => ({ timestamp: 2 })
}
]
}
// Before flipping: [1, 2]
querySnapshot.docs.reverse();
// Expected: [2, 1]
querySnapshot.docs.forEach((doc) => {
console.log(doc.data().timestamp)
})
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The QuerySnapshot.docs
property is calculated, and returns a fresh array each time you call it. Its implementation:
/** An array of all the documents in the `QuerySnapshot`. */
get docs(): Array<QueryDocumentSnapshot<T>> {
const result: Array<QueryDocumentSnapshot<T>> = [];
this.forEach(doc => result.push(doc));
return result;
}
So your reverse()
call reverses an ephemeral array, while your subsequent call to querySnapshot.docs
then returns a new array in the order from the database.
To fix this problem, store a reference to the docs when you first get them from the QuerySnapshot.docs
and reverse that:
console.log("=== BEFORE ===");
let docs = querySnapshot.docs;
docs.forEach((prev) => {
console.log(prev.data().date.toDate());
});
// Flip the docs if we are fetching new posts
docs.reverse(); <-----
console.log("=== AFTER FLIP ===");
docs.forEach((prev) => {
console.log(prev.data().date.toDate());
});