art vanderlay
art vanderlay

Reputation: 2463

jquery dynamically generated .append() sometimes appends to wrong div

I have a block of jquery that builds a form with more than 40 element using a loop to .append() div elements that load .ajax() json.

9 out of 10 times the form renders as expected. However randomly some of the elements will suffer from two types of errors

  1. the dom element will be created but not displayed (does not show in source)(on deeper investigation, it seems the elements are always generated, just wrong parent (2))
  2. the dom element is placed as a child to the wrong parent.

for example below, id3 should be attached to delta[14] but is instead generated at beta[3] OR id3 should be at gamma[6] but does not display at all

the format of build is

hard code

<div id="alpha">
   <div id="beta"></div>
   <div id="gamma"></div>
   <div id="delta"></div>
</div>

doAppendStuff(beta, ajaxUrletc1);
doAppendStuff(beta, ajaxUrletc2);
...
doAppendStuff(gamma, ajaxUrletc10);
doAppendStuff(gamma, ajaxUrletc11);
...
doAppendStuff(delta, ajaxUrletc20);
doAppendStuff(delta, ajaxUrletc21);

dynamic

    function randId(baseID) {
        return baseID+"_"+Math.round(new Date().getTime() + (Math.random() * 555));
    }

    var id1= randId("myIdOne");
    var id2= randId("myIdTwo");
    var id3= randId("myIdThree");

    function doAppendStuff(elemId, ajaxUrletc){
    $('#' + elemId).append(
        '<div id="' + id1 + '" >' +
           '<div id="' + id2 + '">' +
              '<select id="' + id3 + '"></select>' +
            '</div>' +
        '</div>'
     );
    ... // log id1, id2,id3
    ... //do .ajax stuff + callback on id3

I have added callbacks to each loop to ensure that the .append is fired and no errors are generated complaining that the element does not exist.

Running a trace I can see the dynamic id for each element is being generated.

The code itself works as expected as the other 9/10 times it renders as expected.

notes

  1. The random errors apply to different elements each time. no particular logic on what element fails.
  2. I have separated the ajax calls from the dom element creation so there should be no bottleneck on the element creation
  3. All ajax calls are initiated as expected in the correct order. Some take longer but the other elements generate as expected without waiting. All data is successfully returned.

Is there any know issues with generating multiple dom elements by calling the same function repeatedly OR is there a listener I could add to ensure the element is correctly generated in the desired position before proceeding to the next call via a callback.

UPDATE

After adding logging of the id1,id2,id3, the logs confirm that the correct dynamic ids are being assigned. It seems however that either the var in memory is being replaced with a previous value or the js engine is placing in the wrong generated position due to timing.

UPDATE 2

After some more debugging, we changed the random string and upped the number from

return baseID+"_"+Math.round(new Date().getTime() + (Math.random() * 555));

to

return baseID+"_"+Math.round(new Date().getTime() + (Math.random() * 99999));

and the problem has not reoccurred. So it looks like it could be either a random ID collision with the same string being generated twice or somehow reused when the function is reinitialised. The interesting thing is the ID's are not sequential, it will often skip several rows before reusing the same ID.

So we have cured the problem, but still do not understand what caused the issue, any thoughts are welcome.

Upvotes: 2

Views: 222

Answers (1)

Greg
Greg

Reputation: 2600

If you want a unique value, then we're talking about GUID's.

Create GUID / UUID in JavaScript?

However, if you would have placed an underscore or other value between the time and random number, I'd suspect you'd have seen fewer collisions.

time + random = some future period in time.

Imagine getting a random 100 and then 100 ms later getting a random 0.

"abc1506110581013_100" != "abc1506110581113_0"

while

"abc1506110581113" == "abc1506110581113"

Upvotes: 2

Related Questions