HTML: How to get a calculation result before executing a function

I have a script that I am trying to execute. I need the script to, on the press of the submit button:

  1. fetch values from Google firestore
  2. Use those values in a calculation
  3. use the result of this calculation to write back to the firestore database

I have put console.log("eff[1,2,3]" + result of calculation) to help trace in the console log the order of execution. It first displays eff3 then eff1 then eff2 so this means that the value submitted to firestore is zero (as it is before the calculation) The calculation does calculate the correct answer it just doesn’t submit the answer to the database.

How do I change my code to have it execute in the right order?

// Triggered when the send new message form is submitted.
function onMessageFormSubmit(e) {
  e.preventDefault();
  //Calculate efficiency
  var preodo = 0
  var efficiency = 0
  firebase.firestore().collection('Vehicle').doc(reg.value).collection('Refuels').orderBy('Date', 'desc').limit(1)
    .onSnapshot(function(snapshot) {
      snapshot.docChanges().forEach(function(change) {
        preodo = change.doc.data().Odometer
        efficiency = (odo.value - preodo) / amount.value
        efficiency = efficiency.toFixed(4);
        console.log("eff1:" + efficiency)
      });
      console.log("eff2:" + efficiency)
    });
  //Save refuel transaction with all details form the form as well as the calculated efficiency        
  console.log("eff3:" + efficiency)
  saveMessage(reg.value, odo.value, date.value, amount.value, price.value, rebate.value, efficiency).then(function() {
    window.alert('Refuel submitted!')
    // Clear message text field and re-enable the SEND button.
    resetMaterialTextfield();
    toggleButton();
  });
}

1 thought on “HTML: How to get a calculation result before executing a function”

  1. By using @Professor Abronsius’ suggestion, I put my code in a Promise

    // Triggered when the send new message form is submitted.
    function onMessageFormSubmit(e) {
      e.preventDefault();
      let myPromise = new Promise(function(myResolve, myReject) {
        //Calculate efficiency
        var preodo = 0
        var efficiency = 0
        firebase.firestore().collection('Vehicle').doc(reg.value).collection('Refuels').orderBy('Date', 'desc').limit(1)
          .onSnapshot(function(snapshot) {
            snapshot.docChanges().forEach(function(change) {
              preodo = change.doc.data().Odometer
              efficiency = (odo.value - preodo) / amount.value
              efficiency = efficiency.toFixed(4);
              console.log("eff1:" + efficiency)
            });
            console.log("eff2:" + efficiency)
            myResolve(efficiency); // when successful
            myReject("Not able to calculate efficiency"); // when error
          });
      });
    
      // "Consuming Code" (Must wait for a fulfilled Promise)
      myPromise.then(
        function(efficiency) {
          //Save refuel transaction with all details form the form as well as the calculated efficiency        
          console.log("eff3:" + efficiency)
          saveMessage(reg.value, odo.value, date.value, amount.value, price.value, rebate.value, efficiency).then(function() {
            window.alert('Refuel submitted!')
            // Clear message text field and re-enable the SEND button.
            resetMaterialTextfield();
            toggleButton();
          });
        },
        function(error) {
          window.alert(error)
        }
      );
    }

    This works… It submits to the firestore only once but… it prints to the console log as follows:
    eff1, eff2, eff3, eff1, eff1, eff2.

    I’m now curious as to why it repeats itself? It doesn’t really matter that it repeats this because it doesn’t affect the database or the user interface but I am curious.

    Reply

Leave a Comment