user2888784 user2888784 - 7 months ago 12
Javascript Question

How can I make a while loop wait until the user swipes right on a picture?

I have a while loop that runs through my database and returns a list of pets that meets my query, until I have no more pets left. If the pet meets my criteria a function is called that displays all the pet information on a page. Right now the while loop runs through and returns all the pets, but only displays the last one because there's nothing to make the while loop stop and wait after each pet before moving on.

How can I make my while loop wait to display the second pet until the user swipes right and then obviously swiping right would let the while loop run to display the second pet.

Answer

General suggestions:

  • Load all your pet data from firebase at the beginning, rather than each time the pet id changes.
  • Keep a few central objects for your data, such as savedPets, dbPets, and currentPetId.
  • Break up code into short, focused functions, ideally that give the same output when run multiple times on the same input (pure).
  • Use as few top-level variables as possible. From what I can tell savedPets and whichPet might be globals, but they needn't be.

Here's your code reworked with comments. Note some things were unclear, so I made some guesses.

$("#pic").on("swiperight", petsNotLoadedYet)
getPets(afterPetsLoaded) // Starts loading the Firebase data and all subsequent actions.

function afterPetsLoaded (dbPets) {
  dbPets = dbPets
  .map(updateAgeValue) // Modify each pet in the list using this function.
  .filter(compareSavedPets) // Only keep pets in the list that match your criteria.

  var currentPetId = 0
  displayPet(dbPets[currentPetId])

  $("#pic").off("swiperight", petsNotLoadedYet)
  $("#pic").on("swiperight", displayNextPet)

  function displayNextPet () { // Needs to be in this scope to access currentPetId.
    currentPetId += 1
    if(currentPetId >= dbPets.length) { currentPetId = 0 } // Cycle back to beginning of list.
    displayPet(dbPets[currentPetId])
  }
}

function petsNotLoadedYet () { console.warn("Pets not loaded yet.") }

function displayPet (pet) { console.log('Now displaying pet', pet) }

function getPets (callback) {
  var config = tableConfig(whichPet)
  var ref = new Firebase("https://blazing-heat-5378.firebaseio.com/ASPCA/" + config.id +"/" + config.petName) // Hopefully you have an array of pet objects at this URL.
  ref.orderByValue().on("value", function (snapshot) {
    var dbPets = []
    snapshot.forEach(function (data, index) { // for each pet, add it to the dbPets list (or use Firebase's list if you'd rather).
      dbPet.push(snapshot.val())
    })
    callback(dbPets)
  })
}

function compareSavedPets (dbPet) {
  // Note you're looking at 1 savedPet vs 1 dbPet, but you probably have multiple
  // saved pets. So you might need to iterate through the list of saved pets to
  // find the one that corresponds with the current dbPet.
  var similarity = 0
  similarity += savedPet.age === dbPet.ageValue ? 1 : 0
  similarity += savedPet.special === dbPet.special ? 1 : 0
  similarity += savedPet.other_cats === dbPet.other_cats ? 1 : 0
  similarity += savedPet.other_dogs === dbPet.other_dogs ? 1 : 0
  similarity += savedPet.children === dbPet.children ? 1 : 0
  similarity += savedPet.gender === dbPet.gender ? 1 : 0
  return similarity >= 4
}

function updateAgeValue (dbPet) {
  if(whichPet === "cat") {
    if(dbPet.age <= 1) {
      dbPet.ageValue = "kitten"
    }
    else if(dbPet.age > 1 && dbPet.age <= 2) {
      dbPet.ageValue = "young"
    }
    else if(dbPet.age > 2 && dbPet.age <= 13) {
      dbPet.ageValue = "adult"
    }
    else if(dbPet.age > 13) {
      dbPet.ageValue = "senior"
    }
    else {
      dbPet.ageValue = "error"
    }
  } else if(whichPet === "dog") {
    if(dbPet.age <= 1) {
      dbPet.ageValue = "puppy"
    }
    else if(dbPet.age > 1 && dbPet.age <= 2) {
      dbPet.ageValue = "young"
    }
    else if(dbPet.age > 2 && dbPet.age <= 7) {
      dbPet.ageValue = "adult"
    }
    else if(dbPet.age > 7) {
      dbPet.ageValue = "senior"
    }
    else{
      dbPet.ageValue = "error"
    }
  }
  return dbPet
}

function tableConfig(whichPet) {
  if(whichPet === "dog") { return { petName: "Dog", id: 0 } }
  else if(whichPet === "cat") { return { petName: "Cat", id: 1 } }
  else { throw new Error("Can't handle pet of type: "+whichPet) }
}