Why is my javascript code running out of order? [duplicate]












0
















This question already has an answer here:




  • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

    6 answers




I am trying to display data from my firebase database and images from firebase storage. Currently it seems to run some of my code before the other. I have shown my code below:






 <script>
var wrapper = document.getElementById("myHTMLWrapper");
var myHTML = '';
var databaseRef = firebase.database().ref('items/');
databaseRef.once('value', function(snapshot)
{
snapshot.forEach(function(childSnapshot)
{
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
myHTML += '<div class="card">';
myHTML += '<div class="card-body">';
var urlimage;
storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
urlimage = url;
console.log(urlimage);
});
console.log('url outside of function is: '+urlimage);
myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
console.log('images/'+ childData.id +'.jpg');
myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
myHTML += '</div>';
myHTML += '</div>';
});
wrapper.innerHTML = myHTML;
});
</script>





It is returning the data from the database correctly but it is having issues resolving the URL of the image. From my console logs, the issue seems to be that the code is reaching console.log('url outside of function is: '+urlimage); before it reaches console.log(urlimage); even though it is above it in the code structure. I think it has something to do with how Javascript handles it. I would highly appreciate some help. Thanks in advance.










share|improve this question















marked as duplicate by Bergi javascript
Users with the  javascript badge can single-handedly close javascript questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 25 '18 at 22:12


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.























    0
















    This question already has an answer here:




    • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

      6 answers




    I am trying to display data from my firebase database and images from firebase storage. Currently it seems to run some of my code before the other. I have shown my code below:






     <script>
    var wrapper = document.getElementById("myHTMLWrapper");
    var myHTML = '';
    var databaseRef = firebase.database().ref('items/');
    databaseRef.once('value', function(snapshot)
    {
    snapshot.forEach(function(childSnapshot)
    {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    myHTML += '<div class="card">';
    myHTML += '<div class="card-body">';
    var urlimage;
    storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
    urlimage = url;
    console.log(urlimage);
    });
    console.log('url outside of function is: '+urlimage);
    myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
    console.log('images/'+ childData.id +'.jpg');
    myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
    myHTML += '</div>';
    myHTML += '</div>';
    });
    wrapper.innerHTML = myHTML;
    });
    </script>





    It is returning the data from the database correctly but it is having issues resolving the URL of the image. From my console logs, the issue seems to be that the code is reaching console.log('url outside of function is: '+urlimage); before it reaches console.log(urlimage); even though it is above it in the code structure. I think it has something to do with how Javascript handles it. I would highly appreciate some help. Thanks in advance.










    share|improve this question















    marked as duplicate by Bergi javascript
    Users with the  javascript badge can single-handedly close javascript questions as duplicates and reopen them as needed.

    StackExchange.ready(function() {
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function() {
    $hover.showInfoMessage('', {
    messageElement: $msg.clone().show(),
    transient: false,
    position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
    dismissable: false,
    relativeToBody: true
    });
    },
    function() {
    StackExchange.helpers.removeMessages();
    }
    );
    });
    });
    Nov 25 '18 at 22:12


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





















      0












      0








      0


      1







      This question already has an answer here:




      • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

        6 answers




      I am trying to display data from my firebase database and images from firebase storage. Currently it seems to run some of my code before the other. I have shown my code below:






       <script>
      var wrapper = document.getElementById("myHTMLWrapper");
      var myHTML = '';
      var databaseRef = firebase.database().ref('items/');
      databaseRef.once('value', function(snapshot)
      {
      snapshot.forEach(function(childSnapshot)
      {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      myHTML += '<div class="card">';
      myHTML += '<div class="card-body">';
      var urlimage;
      storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
      urlimage = url;
      console.log(urlimage);
      });
      console.log('url outside of function is: '+urlimage);
      myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
      console.log('images/'+ childData.id +'.jpg');
      myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
      myHTML += '</div>';
      myHTML += '</div>';
      });
      wrapper.innerHTML = myHTML;
      });
      </script>





      It is returning the data from the database correctly but it is having issues resolving the URL of the image. From my console logs, the issue seems to be that the code is reaching console.log('url outside of function is: '+urlimage); before it reaches console.log(urlimage); even though it is above it in the code structure. I think it has something to do with how Javascript handles it. I would highly appreciate some help. Thanks in advance.










      share|improve this question

















      This question already has an answer here:




      • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

        6 answers




      I am trying to display data from my firebase database and images from firebase storage. Currently it seems to run some of my code before the other. I have shown my code below:






       <script>
      var wrapper = document.getElementById("myHTMLWrapper");
      var myHTML = '';
      var databaseRef = firebase.database().ref('items/');
      databaseRef.once('value', function(snapshot)
      {
      snapshot.forEach(function(childSnapshot)
      {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      myHTML += '<div class="card">';
      myHTML += '<div class="card-body">';
      var urlimage;
      storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
      urlimage = url;
      console.log(urlimage);
      });
      console.log('url outside of function is: '+urlimage);
      myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
      console.log('images/'+ childData.id +'.jpg');
      myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
      myHTML += '</div>';
      myHTML += '</div>';
      });
      wrapper.innerHTML = myHTML;
      });
      </script>





      It is returning the data from the database correctly but it is having issues resolving the URL of the image. From my console logs, the issue seems to be that the code is reaching console.log('url outside of function is: '+urlimage); before it reaches console.log(urlimage); even though it is above it in the code structure. I think it has something to do with how Javascript handles it. I would highly appreciate some help. Thanks in advance.





      This question already has an answer here:




      • Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

        6 answers







       <script>
      var wrapper = document.getElementById("myHTMLWrapper");
      var myHTML = '';
      var databaseRef = firebase.database().ref('items/');
      databaseRef.once('value', function(snapshot)
      {
      snapshot.forEach(function(childSnapshot)
      {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      myHTML += '<div class="card">';
      myHTML += '<div class="card-body">';
      var urlimage;
      storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
      urlimage = url;
      console.log(urlimage);
      });
      console.log('url outside of function is: '+urlimage);
      myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
      console.log('images/'+ childData.id +'.jpg');
      myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
      myHTML += '</div>';
      myHTML += '</div>';
      });
      wrapper.innerHTML = myHTML;
      });
      </script>





       <script>
      var wrapper = document.getElementById("myHTMLWrapper");
      var myHTML = '';
      var databaseRef = firebase.database().ref('items/');
      databaseRef.once('value', function(snapshot)
      {
      snapshot.forEach(function(childSnapshot)
      {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      myHTML += '<div class="card">';
      myHTML += '<div class="card-body">';
      var urlimage;
      storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
      urlimage = url;
      console.log(urlimage);
      });
      console.log('url outside of function is: '+urlimage);
      myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
      console.log('images/'+ childData.id +'.jpg');
      myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
      myHTML += '</div>';
      myHTML += '</div>';
      });
      wrapper.innerHTML = myHTML;
      });
      </script>






      javascript html firebase firebase-storage






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 20:35







      J W

















      asked Nov 25 '18 at 19:37









      J WJ W

      135




      135




      marked as duplicate by Bergi javascript
      Users with the  javascript badge can single-handedly close javascript questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 25 '18 at 22:12


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









      marked as duplicate by Bergi javascript
      Users with the  javascript badge can single-handedly close javascript questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 25 '18 at 22:12


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


























          1 Answer
          1






          active

          oldest

          votes


















          1














          it looks like "getDownloadURL" returns a Promise and you will get the url when that Promise is resolved so the behaviour you explained is normal. If you want to use the url value you have to move your code inside the callback function. something like this



          var getURL = function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          return storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
          var myHTML = '';
          myHTML += '<div class="card">';
          myHTML += '<div class="card-body">';
          myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';

          myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
          myHTML += '</div>';
          myHTML += '</div>';
          return myHTML;
          });
          }
          var promises = ;
          snapshot.forEach(function(childSnapshot) {
          promises.push(getURL(childSnapshot));
          }
          Promise.all(promises).then(results => {
          wrapper.innerHTML = results.join('');
          }





          share|improve this answer


























          • Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

            – J W
            Nov 25 '18 at 21:30











          • if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

            – Reza Nasiri
            Nov 25 '18 at 21:38











          • I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

            – J W
            Nov 25 '18 at 21:41











          • You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

            – Reza Nasiri
            Nov 25 '18 at 21:50











          • Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

            – J W
            Nov 25 '18 at 22:03


















          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          it looks like "getDownloadURL" returns a Promise and you will get the url when that Promise is resolved so the behaviour you explained is normal. If you want to use the url value you have to move your code inside the callback function. something like this



          var getURL = function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          return storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
          var myHTML = '';
          myHTML += '<div class="card">';
          myHTML += '<div class="card-body">';
          myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';

          myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
          myHTML += '</div>';
          myHTML += '</div>';
          return myHTML;
          });
          }
          var promises = ;
          snapshot.forEach(function(childSnapshot) {
          promises.push(getURL(childSnapshot));
          }
          Promise.all(promises).then(results => {
          wrapper.innerHTML = results.join('');
          }





          share|improve this answer


























          • Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

            – J W
            Nov 25 '18 at 21:30











          • if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

            – Reza Nasiri
            Nov 25 '18 at 21:38











          • I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

            – J W
            Nov 25 '18 at 21:41











          • You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

            – Reza Nasiri
            Nov 25 '18 at 21:50











          • Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

            – J W
            Nov 25 '18 at 22:03
















          1














          it looks like "getDownloadURL" returns a Promise and you will get the url when that Promise is resolved so the behaviour you explained is normal. If you want to use the url value you have to move your code inside the callback function. something like this



          var getURL = function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          return storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
          var myHTML = '';
          myHTML += '<div class="card">';
          myHTML += '<div class="card-body">';
          myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';

          myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
          myHTML += '</div>';
          myHTML += '</div>';
          return myHTML;
          });
          }
          var promises = ;
          snapshot.forEach(function(childSnapshot) {
          promises.push(getURL(childSnapshot));
          }
          Promise.all(promises).then(results => {
          wrapper.innerHTML = results.join('');
          }





          share|improve this answer


























          • Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

            – J W
            Nov 25 '18 at 21:30











          • if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

            – Reza Nasiri
            Nov 25 '18 at 21:38











          • I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

            – J W
            Nov 25 '18 at 21:41











          • You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

            – Reza Nasiri
            Nov 25 '18 at 21:50











          • Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

            – J W
            Nov 25 '18 at 22:03














          1












          1








          1







          it looks like "getDownloadURL" returns a Promise and you will get the url when that Promise is resolved so the behaviour you explained is normal. If you want to use the url value you have to move your code inside the callback function. something like this



          var getURL = function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          return storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
          var myHTML = '';
          myHTML += '<div class="card">';
          myHTML += '<div class="card-body">';
          myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';

          myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
          myHTML += '</div>';
          myHTML += '</div>';
          return myHTML;
          });
          }
          var promises = ;
          snapshot.forEach(function(childSnapshot) {
          promises.push(getURL(childSnapshot));
          }
          Promise.all(promises).then(results => {
          wrapper.innerHTML = results.join('');
          }





          share|improve this answer















          it looks like "getDownloadURL" returns a Promise and you will get the url when that Promise is resolved so the behaviour you explained is normal. If you want to use the url value you have to move your code inside the callback function. something like this



          var getURL = function(childSnapshot) {
          var childKey = childSnapshot.key;
          var childData = childSnapshot.val();
          return storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
          var myHTML = '';
          myHTML += '<div class="card">';
          myHTML += '<div class="card-body">';
          myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';

          myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
          myHTML += '</div>';
          myHTML += '</div>';
          return myHTML;
          });
          }
          var promises = ;
          snapshot.forEach(function(childSnapshot) {
          promises.push(getURL(childSnapshot));
          }
          Promise.all(promises).then(results => {
          wrapper.innerHTML = results.join('');
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 '18 at 22:57

























          answered Nov 25 '18 at 21:18









          Reza NasiriReza Nasiri

          560115




          560115













          • Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

            – J W
            Nov 25 '18 at 21:30











          • if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

            – Reza Nasiri
            Nov 25 '18 at 21:38











          • I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

            – J W
            Nov 25 '18 at 21:41











          • You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

            – Reza Nasiri
            Nov 25 '18 at 21:50











          • Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

            – J W
            Nov 25 '18 at 22:03



















          • Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

            – J W
            Nov 25 '18 at 21:30











          • if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

            – Reza Nasiri
            Nov 25 '18 at 21:38











          • I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

            – J W
            Nov 25 '18 at 21:41











          • You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

            – Reza Nasiri
            Nov 25 '18 at 21:50











          • Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

            – J W
            Nov 25 '18 at 22:03

















          Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

          – J W
          Nov 25 '18 at 21:30





          Ah that makes sense. But I am having an issue where its just skipping over the callback function. Where myHTML just shows up blank. What do you think? Thanks.

          – J W
          Nov 25 '18 at 21:30













          if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

          – Reza Nasiri
          Nov 25 '18 at 21:38





          if the callback is not called, that means your Promise is rejected. I think it is because of the "." you have in your key(.jpg) but you can add a catch block to see exactly why it is rejected.

          – Reza Nasiri
          Nov 25 '18 at 21:38













          I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

          – J W
          Nov 25 '18 at 21:41





          I apologize for the confusion. What I meant was that it skipped it when it reached that part of the code. The promise eventually resolved but it was after the page already set the wrapper.innerHTML to an empty myHTML.

          – J W
          Nov 25 '18 at 21:41













          You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

          – Reza Nasiri
          Nov 25 '18 at 21:50





          You have to use Promise.all then. wait until all URLs are retrieved and then set the wrapper.innerHTML.

          – Reza Nasiri
          Nov 25 '18 at 21:50













          Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

          – J W
          Nov 25 '18 at 22:03





          Thank you again Reza. I am not too familiar with promise.all. Would you please kindly clarify? Thank you for your time and expertise.

          – J W
          Nov 25 '18 at 22:03



          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)