'Is there other method for passing a variable as parameter to onSnapshot function conditionally onclick?
I tried passing collection reference conditionally to onSnapshot function but as the colRef variable inside the addEventListener is scope restricted the colRef value is not getting changed on selecting sorting options from list. Is there any other method of implementing the code and able to pass colRef as parameter conditionally ?
My relevant code :
index.html
// list of options for sorting data
<ul>
<li id="al">Alphabetical Order</li>
<li id="yr">Year</li>
<li id="rt">Rating</li>
<li id="ca">Created At</li>
</ul>
index.js
// collection Reference
let colRef = collection(db, 'Books');
window.addEventListener('click', (e) => {
if(e.target.id === 'al'){
colRef = query(colRef, orderBy('title', 'asc'))
} else if(e.target.id === 'yr'){
colRef = query(colRef, orderBy('year', 'asc'))
} else if(e.target.id === 'rt'){
colRef = query(colRef, orderBy('title', 'asc'))
} else if(e.target.id === 'ca'){
colRef = query(colRef, orderBy('createdAt'))
}
})
onSnapshot(colRef, (snapshot) => {
...Getting data and rendering it to html...
})
Thank You
Solution 1:[1]
No, you can't change the reference once the snapshot listener has been established.
Your event handler for click gets executed after you established a snapshot listener with onSnapshot. Once this listener is running, you can't change it.
Option 1
If the dataset isn't too big, you can just fetch all documents (as you do at the moment) and sort them on client side. For example, if the user clicks on yr, you can sort the data by year ascending.
window.addEventListener('click', (e) => {
if(e.target.id === 'al'){
sortData('titleAsc');
} else if(e.target.id === 'yr'){
sortData('yearAsc');
} else if(e.target.id === 'rt'){
sortData('titleDesc');
} else if(e.target.id === 'ca'){
sortData('createdAt');
}
})
function sortData(type) {
// Sort the data you got from your snapshot based on type
}
From my view, this is the easiest path to implementation.
Option 2
Don't use a snapshot listener; just fetch data once:
window.addEventListener('click', (e) => {
if(e.target.id === 'al'){
colRef = query(colRef, orderBy('title', 'asc'))
} else if(e.target.id === 'yr'){
colRef = query(colRef, orderBy('year', 'asc'))
} else if(e.target.id === 'rt'){
colRef = query(colRef, orderBy('title', 'asc'))
} else if(e.target.id === 'ca'){
colRef = query(colRef, orderBy('createdAt'))
}
// Fetch data from Firestore
fetchData();
})
async function fetchData() {
const snapshot = await getDocs(colRef);
// then do whatever you want with the data.
}
For more information, see docs. Consider caching them on the client, if the data doesn't require frequent updates.
This makes sense when you have a larger dataset and you want to limit the amount of documents returned by the query (for example, when using pagination).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
