jQuery.getScript working on local but not on GitHub Pages

293 views Asked by At

I'm building a website with Jekyll. A lot of people will contribute on different javascript sketches that will be displayed on the home page randomly: some of them will be written with P5.js, other with other libraries.

Since I didn't want to load all the libraries on page load I generate a JSON with one object per script:

[
   {
      "title":"Title to display",
      "author":"Author",
      "description":"javascript, Processing",
      "kind":"javascript",
      "href":"link to the js hosted on GitHub Pages",
      "includes":[
         "link to external library hosted on CDN",
         "link to external library hosted on CDN"
      ]
   }
]

Then, using jQuery, I'm loading everything with this script:

var loadedData;

$(function() {
    // Load all the scripts in an array
    $.getJSON("{{ site.url }}/homepage.json", function(data) {
      loadedData = data;
      randomPost();
    });

    $("#jsRefresh").click(function() {
      $("canvas").remove();
      randomPost();
    });
});

function randomPost() {

  $("#loading").show();

  item = loadedData[Math.floor(Math.random() * loadedData.length)];

  var defer = $.Deferred();

  $.each(item.includes, function(index, value){
    defer.then(function() {
      $.getScript(value)
    });
  });

  defer.then(function() {
    $.getScript(item.href)
  });

  defer.resolve();

  $.when(defer).done(function() {
    $("#loading").hide();
    $(".item-title").html(item.title + ' | ' + item.author);
    $(".item-description").html(item.description);
  })
}

This code is working on my local server but when I upload it on GitHub Pages it doesn't load properly on page load.

If I click the refresh link that fires randomPost() again it loads the previous script.

The live example is currently hosted here

1

There are 1 answers

7
charlietfl On

Your whole $.when is only using one promise and you resolve it immediately , not based on any of the getScript completing. Since you resolve it immediately it is virtually the same as using no promise at all.

Also note that $.getScript is a $.ajax shortcut and $.ajax itself returns a promise

The norm for something like this would be to make an array of promises and $.when would not resolve until the array of promises all resolve

Something like:

 // library script promises
 var requests = item.includes.map(function(value) {
   return $.getScript(value)
 });
 // `$.when` doesn't accept array in jQuery versions <3
 $.when.apply(null, requests).then(function() {
   //want this to only load after include requests have loaded
   var mainScriptPromise =  $.getScript(item.href);           
    // return it to the next then() 
    return mainScriptPromise;
 }).then(function() {
   // fires after the main script promise resolves
   $("#loading").hide();
   $(".item-title").html(item.title + ' | ' + item.author);
   $(".item-description").html(item.description);
 });

Note that you will also need to add your own error handling if any of the promises don't resolve

Demo using $.get

Note you might want to look into using a load manager like Require.js