0

I'm facing an issue with async java script. This is my html

<html>
   <head>
       <script src="/headScript.js"></script>
   </head>
  <body>
      <div id="inner_id" class="sample"> </div>
      ...
      <script src="/anOtherScript.js"></script>
  </body>
</html>

/headScript.js

  $(document).ready(function () {
  var target=$('#inner_id'); 
    $.ajax({                                                                 
        method: 'GET',
        url: '/example',
        success: function (result) {
                var el= document.createElement('span');
                el.id="new_element";              
                el.setAttribute('name', 'element');
                el.setAttribute('content', result);
                target.append(el)
        }
    });
  });

/anOtherScript.js

 $(document).ready(function () {
   console.log($('#new_element));
 });

the script from header create the new div but it seems that these two script are running asynchronously and at the console i get undefined. Is there any way that (anOtherScript) can wait the first one to be resolved first?

  • i cant change anything to html file
  • files that I'm able to make changes are the 2 scripts
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
Nakos Kotsanis
  • 180
  • 1
  • 15
  • Put the code from anOtherScript.js in headScript.js after you append the new element. – Heretic Monkey Jan 28 '21 at 14:24
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Jan 28 '21 at 14:25
  • can't do that. headScript.js is a file that is active in all of my html pages. Each of html page have different code inside. – Nakos Kotsanis Jan 28 '21 at 14:25
  • That's not mentioned in the question... In any case, try the techniques outlined in the answers to the linked questions. – Heretic Monkey Jan 28 '21 at 14:28
  • The DOM MutationObserver event might be helpful to you? https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver – Alex Mulchinock Jan 28 '21 at 14:30

2 Answers2

0

This happens because anOtherScript.js is executed right after you load it in your html - which means immediately. However you only create the #new_element element after you get a response from your example API.

To fix that: Make sure the code in anOtherScript.js runs after the code in headScript.js.

Put all anOtherScript.js content in a funciton

const anotherScript = () => {
    $(document).ready(function () {
        console.log($(`#new_element`))
    });
}

Then just call this funciton from the success callback of the headScript.js file:

success: function (result) {
                var el= document.createElement('span');
                el.id="new_element";              
                el.setAttribute('name', 'element');
                el.setAttribute('content', result);
                target.append(el)
                anotherScript();
        }
Ravid
  • 293
  • 2
  • 9
-1

Simplest and fastest solution is to use jQuery as an event bus:

/headScript.js

$(document).ready(function () {
  var target=$('#inner_id'); 
    $.ajax({                                                                 
        method: 'GET',
        url: '/example',
        success: function (result) {
                var el= document.createElement('span');
                el.id="new_element";              
                el.setAttribute('name', 'element');
                el.setAttribute('content', result);
                target.append(el)
                // this line
                $(document).trigger('NEW_ELEMENT_READY');
        }
    });
  });

/anOtherScript.js

// FYI, you don't really need document.ready in here 
// because this script is right before the closing body tag

// handle function to call when #new_element is available
const whenElementIsReady = () => ... do something


// register an event handler to call whenElementIsReady when the event is fired
$(document).on('NEW_ELEMENT_READY', whenElementIsReady);

// if the element is already present for some reason, then you can just call it immediately
if($('#new_element').length) whenElementIsReady();

Please note: this is a terrible long term solution and will get nasty fast unless you're dilligent about naming your events and keeping track of what you're doing but it doesn't appear like you're moving to webpack bundlers/react anytime soon, so in the mean time, an event bus is the solution.

Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100