javascriptasynchronous

Javascript dynamic javascript file loading then execution


here is the execution of my javascript:

ee_btn.addEventListener('click', () => {
        //Ajax GET request to get data form and rendering it
        RequestEEFormData(container, bounds).then(()=>{
            // Loading a javascript file. it get loaded.
            // I can call function from this file then.
            loadScript('/static/js/locationConverterWidget.js');
        });
        
    });
function loadScript(url) {
    const script = document.createElement('script');
    script.src = url;
    script.async=false;
    script.onload = function(){
        //trying to querySelector newly added content
        console.log(document.querySelector('#id_item);
    }
    document.head.appendChild(script);
  }

in case:


async function RequestEEFormData(container, bounds) {
    $.ajax({
        type: 'GET',
        url: 'someURL/',

        success: function (response) {
           container.innerHTML=response;
           someFunction(bounds)
        },
        error: function(response){
          console.log(response);
        },
        cache:false,
        contentType: "application/json",
        processData: false
     });
}

the console.log return an empty Nodelist.

if I do call the same consol.log from a button 1sec later. It work.

Clearly there is something with the async I dont understand.

Can anyone explain my what I'm doing wrong ?

the purpose is I want the newly downloaded javascript file to querySelector newly added content but It seems to be executed prior the html is completely rendered.

thank you


Solution

  • requestEEFormData() is not returning the promise returned by $.ajax(), so the caller's .then() is not waiting for the AJAX request to finish.

    Since $.ajax() returns a promise explicitly, you don't need to use async. But you have to return its value.

    function RequestEEFormData(container, bounds) {
      return $.ajax({
        type: 'GET',
        url: 'someURL/',
    
        success: function(response) {
          container.innerHTML = response;
          someFunction(bounds)
        },
        error: function(response) {
          console.log(response);
        },
        cache: false,
        dataType: "json",
      });
    }
    

    Also, the contentType option is irrelevant for GET requests, since they don't send any content. To specify that the server returns JSON, use dataType: "json". But I wonder if it really does, since you're assigning the response to container.innerHTML, which implies that it returns HTML. If that's the case you should use dataType: "html".

    Similarly, processData: false is unnecessary because there's no data to process.