Reputation: 53
I am making a ticket generator using javascript. I am using firebase to give the users a code that has already been stored on the database. my database is layed out like this:
"qrcodes" : {
"23KU8877" : {
"email" : "[email protected]",
"ticketgenerated" : "true"
},
"288RX9U5" : {
"email" : "[email protected]",
"ticketgenerated" : "true"
}
}
my script allows me to get the first code in the qrcodes list and then move it to another database where another website processes it. But I was wanting to find a way that will make a function take a new snapshot everytime it is run.
The functions that grab the data from firebase are here:
function generatehtml(){
ticketname = document.getElementById('name').value;
ticketemail = document.getElementById('email').value;
adultnumber = document.getElementById('adults').value;
childnumber = document.getElementById('child').value;
while (functionruncount < inputnumber){
grabfirebasecode();
}
}
function grabfirebasecode(){
ref.limitToFirst(1).once('value', function(snapshot) {
for(key in snapshot.val()){
genvar = snapshot.child(key + "/ticketgenerated" ).val();
var genvarpath = "test/" + key + "/ticketgenerated";
if (genvar === "false"){
snapshot.forEach(function(childSnapshot) {
ref.child(childSnapshot.key).remove();
});
ref2.child(key).set({
email: ticketemail,
ticketgenerated: "true",
});
createticket();
}
}
});
functionruncount ++;
}
so if the code above runs succesully and grabs the first child of the qrcode list (e.g "23KU8877"), it will stay the same no matter how many times the function loops.
I am not sure how to fix this. Any help would be appreciated.
Thanks, Daniel Martinez
Upvotes: 0
Views: 295
Reputation: 598740
You're attaching a same listener multiple times in a tight loop. All those listeners start at pretty much the same time, and thus all see the same value from the database. To get a next code, you must be sure to only start reading the next code after you've deleted the previous one. A common way to do this is with a recursive function:
function generatehtml(){
ticketname = document.getElementById('name').value;
ticketemail = document.getElementById('email').value;
adultnumber = document.getElementById('adults').value;
childnumber = document.getElementById('child').value;
grabfirebasecode(inputnumber);
}
function grabfirebasecode(inputnumber){
if (inputnumber > 0) {
ref.limitToFirst(1).once('value', function(snapshot) {
for(key in snapshot.val()){
genvar = snapshot.child(key + "/ticketgenerated" ).val();
var genvarpath = "test/" + key + "/ticketgenerated";
if (genvar === "false"){
var promises = [];
snapshot.forEach(function(childSnapshot) {
promises.push(ref.child(childSnapshot.key).remove());
});
promises.push(
ref2.child(key).set({
email: ticketemail,
ticketgenerated: "true",
})
);
Promise.all(promises).then(function() {
grabfirebasecode(inputnumber-1);
});
createticket();
}
}
});
}
}
So this code builds an array of promises, one for each database operation that happen asynchronously. When all those operations completes, it calls itself again with one lover number.
If your createticket()
also performs asynchronous operations, you might want to also include it in the promises
array so that its work is completed before the next iteration starts.
Upvotes: 1