When implementing a shared counter, it's important to think it in a way that is resistant to latency induced `race-conditions`
Let's say you want to show a like button after each track, allowing a player to increment a global likes counter during the quiz.
A naive implementation would look like this:
$scope.onLikeButtonClick = ()=>{
$quiz.inc('likes'); // increment counter
}
// listen to counter changes and update UI
$quiz.on('bag-likes', o=>{
$scope.likes = $quiz.get('likes');
});
But when the button pops-up, many users will click at about the same time, and since we emulate server logic in client via global variables, the latency between users will make the incrementation unreliable: when a user clicks, it will take some milliseconds to update the counter of all other players, time during which any other user click won't be counted
While a single variable is not atomic in this sense, the bag object can be used to count separately each user's likes, and no risk of overlapping would occur:
$scope.onLikeButtonClick = ()=>{
$quiz.inc('likes'+$me.id); // increment player counter
}
// listen to counter changes and update UI
$quiz.on('bag-*', o=>{
$scope.likes = Object.values($quiz.getBag('likes.*')).reduce((s, a) => s + a*1, 0);
});