Why is my javascript code running out of order? [duplicate]
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.
javascript html firebase firebase-storage
marked as duplicate by Bergi
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.
add a comment |
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.
javascript html firebase firebase-storage
marked as duplicate by Bergi
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.
add a comment |
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.
javascript html firebase firebase-storage
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
javascript html firebase firebase-storage
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
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
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.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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('');
}
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
|
show 6 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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('');
}
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
|
show 6 more comments
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('');
}
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
|
show 6 more comments
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('');
}
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('');
}
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
|
show 6 more comments
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
|
show 6 more comments