0

I'm having trouble getting jquery's $.getScript to work. Here's a test file, demo.html:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    function wow() { return 3; }
</script>

<h1>Demo</h1>

<script>
    console.log(wow);
    console.log(wow());
</script>

When I browse to this in Chrome on Windows 10, the following is displayed in the console:

Navigated to https://example.org/xyz/tools/demo.html
demo.html:11 ƒ wow() { return 3; }
demo.html:12 3

which is correct.

Then I move the function definition to a file called myModule.js:

function wow() { return 3; }

and create demo2.html, which is demo.html with the function definition replaced by a getScript call:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    $.getScript("myModule.js");
</script>

<h1>Demo</h1>

<script>
    console.log(wow);
    console.log(wow());
</script>

This time I get

Navigated to https://example.org/xyz/tools/demo2.html
demo2.html:11 Uncaught ReferenceError: wow is not defined
at demo2.html:11

Am I misunderstanding what $.getScript is for or how it's used?

Addendum

In response to the suggestion to wrap my console.log calls in a $.ready wrapper, I tried the following:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    $.getScript("myModule.js");
</script>

<h1>Demo</h1>

<script>
$.ready(function() {
    console.log(wow);
    console.log(wow());
});
</script>

This time I got no error message but, also, the values of wow and wow() weren't written to the console.

9
  • 2
    It's because getScript is asynchronous. Your console.logs are executing before getScript is done. Commented Jan 15, 2019 at 20:54
  • Then what good is it? Less dismissively, I do see that there's a parameter for a callback function where the rest of the code in the page can be executed, but what if I'm using getScript to load a dozen modules or more, each with its own success callback, and I need many of them in place before I start running the code that these modules are meant to support? Commented Jan 15, 2019 at 20:58
  • Why do you feel you need to use getScript rather than <script src= ? Commented Jan 15, 2019 at 20:59
  • For the "loading many scripts and wait for them" scenario, take a look at this question. Commented Jan 15, 2019 at 21:01
  • 2
    @freedomn-m and also Kevin B: I'm trying to use getScript so scripts can load their own dependencies instead of their client HTML pages having to know what they are. In other words, encapsulation, hiding implementation details. Commented Jan 16, 2019 at 3:31

4 Answers 4

1

$.getscript

https://api.jquery.com/jquery.getscript/

This is a shorthand Ajax function, which is equivalent to:

$.ajax({
  url: url,
  dataType: "script",
  success: success
});

so $.getscript makes an asynchronous call, so your code is the equivalent of:

  • $.getscript - start loading the script
  • console.log(wow) - can't find it yet as script not yet loaded
  • ... finish loading script

You can use the callback to execute code when the script has loaded:

$.getScript("myModule.js", function() {
    console.log(wow);
    console.log(wow());
});
Sign up to request clarification or add additional context in comments.

3 Comments

I did see that callback parameter, but its utility seems limited to cases where I'm loading only one external script file, which is a special case.
Ok, wasn't clear from the question. As it's a shortcut for $.ajax it also returns a Promise, so you can determine when they have all loaded.
Ah! I had to look that up promises, and then I finally came across a solution that had eluded my searches, at stackoverflow.com/questions/11803215/…. I'll give the answer that worked. Thanks!
0

The call to getScript() is an asynchronous operation, it does not block the rest of javascript from being executed. You have two options:

1) Wrap the script requiring the content of getScript() in a $(document).ready() to delay execution until everything is loaded.

2) Pass a callback as the second argument to getScript. This callback will be executed if getScript() succeeds.

2 Comments

I knew about solution 2 but it's good only for the special case where only one external module is being loaded, so I consider it a weak solution. But now I'm wrapping the calls to console.log() inside a $.ready(function() { ... }); wrapper, and while now I'm getting no error, I'm also getting nothing written to the console. I replaced console.log with alert and still no luck.
I've appended the updated code to my original post for reference.
0

getScript is asynchronous method, so you need access its variables in the callback like that:

$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
  console.log( data ); // Data returned
  console.log( textStatus ); // Success
  console.log( jqxhr.status ); // 200
  console.log( "Load was performed." );
});

Your console.log(wow); was executed before the script fully load.

Comments

0

Thanks to @freedomn-m, who mentioned Promises in a response follow-up comment, I came upon a previous post discussing $.when().done() at How to include multiple js files using jQuery $.getScript() method. This led to script that worked:

<!DOCTYPE html>

<script src="/xyz/scripts/jquery-1.11.0.min.js"></script>
<script>
    $.when(
        $.getScript("myModule.js")
    ).done(function() {
        console.log(wow);
        console.log(wow());
    });
</script>

<h1>Demo</h1>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.