Reputation: 51
I've browsed for the last few hours but have been entirely unable to successfully detach an onSnapshot listener. Currently my HTML is:
<nav>
<butt onclick="navButt(`Chat`)" class="navItem">Chat</butt>
<butt onclick="navButt(`Staff`)" class="navItem">Staff</butt>
<butt onclick="navButt(`Logout`)" class="navItem">Signout</butt>
</nav>
<module id="Chat" class="mod">
<h3>Chat</h3>
</module>
<module id="Staff" class="mod active">
<h3>Users</h3>
<ul id="usersList">
<li><span>User 1 Name</span><span>User 1 email</span></li> //Planned output of data, using console logging for testing, though.
</ul>
</module>
And my Javascript is:
function staff(){
FS.collection('users').where('company','==',`${userToken.claims.company}`).onSnapshot(snap=>{
let userList = []
snap.forEach(function(doc){
userList.push(doc.data().email);
})
console.log('Users: ' + userList)
})
}
function navButt (butt) {
let unsubscribe = FS.collection('users').where('company','==',`${userToken.claims.company}`).onSnapshot(function(){}) //placed inside so the auth token can be populated first
//I've also tried FS.collection('users').onSnapshot(function(){}) //but this results in a permission error since users can only read other user docs of the same company
switch (butt) {
case 'Logout':
FA.signOut();
break;
case 'Chat':
changeMod(butt);
unsubscribe(); //This is where I've tried all the things
break;
case 'Staff':
changeMod(butt)
staff();
break;
default:
console.log('No tied function')
break;
}
}
//Change Module
function changeMod (target) {
document.querySelectorAll('.mod').forEach((modules)=>{modules.classList.remove('active')})
document.querySelector(`#${target}`).classList.add('active')}
If some kind soul could look at my onSnapshot function above and show me what the detaching code should look like, that would be greatly appreciated, thank you!
Upvotes: 1
Views: 480
Reputation: 51
I finally figured out and understand capturing and calling the unsubscribe. Only started learning Javascript a month ago, so for those in the same shoes, here's my fix:
case 'Chat':
changeMod(butt);
try {unsubscribe()} catch {} //Since it won't exist on the first click, wrap in a try{}
var unsubscribe = FS.collection('users').where('company','==',`${userToken.claims.company}`).onSnapshot(snap=>{ //Use a var so it can be initialized and declared repeatedly, but also the first time. Alternatively, use a let globally set to '' (nothing) and just "unsubscribe = "
let userList = []
snap.forEach(function(doc){
userList.push(doc.data().email);
})
console.log('Users: ' + userList)
}) //What got me was that capturing the onSnapshot in a variable IS creating the snapshot listener, it's a two in one action. Mind blown.
break;
case 'Staff':
changeMod(butt)
try {unsubscribe()} catch {} //Once it's been captured it will be "true" because it exists, and can be called to unsubscribe the last one before being set to the new one.
var unsubscribe = FS.collection('users').where('company','==',`${userToken.claims.company}`).onSnapshot(snap=>{
let userList = []
snap.forEach(function(doc){
userList.push(doc.data().email);
})
console.log('Users: ' + userList)
})
break;
When reading anything on it I just always interpreted the capturing of unsubscribe to be it's own, independent action.
Upvotes: 2