0

firebase.database().ref('zones').on('value', (snapper) => {
    //For each zone, populate HTML
    snapper.forEach((snap) => {
       var html = '<div id="child">Blahblah</div>';
       //Add the Injected HTML to the parent div called 'new'
       $("#parent").append(html);
    }
});
<!-- this is the parent div where I inject my HTML from JS -->

<div id="parent">

</div>

I have a div that I am dynamically populating through a query from Firebase. My firebase query retrieves data that I inject into HTML using $("#parent").append(html).

Now once this parent div is all populated from the firebase call and html injection, I then want to run a function on that parent div - which basically sorts each child div numerically.

I can't seem to figure out how to wait for the parent div to finish populating completely before running the function I want to. I know that due to asynchronous operations, my function is running before the parent div is even getting populated and thus my issue...

user3892254
  • 139
  • 2
  • 15
  • Show your actual code inside any loops etc. so we may better help with this. Note jQuery append() behaves synchronously thus you need to provide more information here on the specific details which in this particular case are important. – Mark Schultheiss Dec 11 '17 at 16:31

2 Answers2

3

Since you are concerned with when the call finishes why not use .once (found in the docs) which will read the data and return once. This way when it returns you know you have all the data and then can sort it

firebase.database().ref('zones').once('value').then(function(snapper) {
    //For each zone, populate HTML
    snapper.forEach((snap) => {
            var html = '<div id="child">Blahblah</div>';
            //Add the Injected HTML to the parent div called 'new'
            $("#parent").append(html);
    });
    // call sort function
});
Andrew Lohr
  • 5,380
  • 1
  • 26
  • 38
  • Where my thoughts were going also – Mark Schultheiss Dec 11 '17 at 16:53
  • Trying this method, but the function doesn't sort the child divs as expected. I know the function does what it supossed to because when I try it in the console on dev tools, works fine – user3892254 Dec 11 '17 at 16:59
  • Might there be an extra `}` in there? – Mark Schultheiss Dec 11 '17 at 17:01
  • nah no luck, will keep debugging :/ – user3892254 Dec 11 '17 at 17:08
  • just want to make sure that I'm saying this right. I want the dom to populate with the divs and then run my function to sort it. I don't want to do anything before the dom gets populated with the divs. I think the .then gets executed when the firebase query finishes but this doesn't help me because at this time the dom hasn't been populated just the query has finished so my sort function might execute but it won't do anything as nothing has actually been added to the dom yet – user3892254 Dec 11 '17 at 17:11
  • 1
    After the forEach you should call your sort method. forEach is synchronous so all the divs should be appended to the DOM (from `$("#parent").append(html);`) at that time – Andrew Lohr Dec 11 '17 at 17:39
  • my fault, my sort function was actually breaking it. I was comparing strings as integers without adding the + so my sort was breaking there. Thank you for the solution regardless! – user3892254 Dec 15 '17 at 13:39
0

I don't think append in jquery includes a callback so you may have to put script at the end of the html that you are appending.

    html = html.append('<script>yourfunctiontorunattheend();</' + 'script>');

Then do:

    $("#parent").append(html)

EDIT: To run after the for statement (see comments):

string lcscript = '<script>yourfunctiontorunattheend();</' + 'script>'
for () {
 ...
}
$("#parent").append(lcscript);
Wattcey
  • 113
  • 1
  • 7
  • I don't think this will work because my append is basically inside a for loop - so for each object I retrieve from my database, I'm adding html using that object and appending to the parent div. Your method will add a script tag to each object that gets appended to my HTML... not sure..? – user3892254 Dec 11 '17 at 16:28
  • Do you want to run the script at the very end after the for loop is finished? – Wattcey Dec 11 '17 at 16:31
  • Yes, the for loop will populate my parent div. Once that full process is complete, I want to run this function – user3892254 Dec 11 '17 at 16:32
  • So then just append the – Wattcey Dec 11 '17 at 16:33
  • what is the difference between this and just calling the function directly after the for loop? Maybe I am misunderstanding how firebase works – Andrew Lohr Dec 11 '17 at 16:38
  • @AndrewLohr i was trying to use .then on the firebase call (since it returns a promise) and run the function that way but the dom still hadn't populated with the html so it didn't work – user3892254 Dec 11 '17 at 16:41
  • Not sure if a promise will work with multiple events, only a single event. – Wattcey Dec 11 '17 at 16:46
  • Have a look at [Link](https://stackoverflow.com/questions/45097858/how-can-i-return-a-nested-firebase-query-promise-in-express) – Wattcey Dec 11 '17 at 16:47
  • yea the promise returns one object which contains a list of entries. I loop through each entry, add some html to the data and then append it to my parent div as shown..just need to figure out how to call a function on that parent div once that entire process has completed – user3892254 Dec 11 '17 at 16:50