Chartjs-AJAX request not working unless alert() is used

1đź‘Ť

âś…

The reason it doesn’t work without the alert is because the GitHubService calls are async so the data isn’t there by the time you render your chart.

The reason it works with alert is because alert pauses the execution (which to be fair is a little magic) so by the time you dismiss the alert the requests have completed.

You’ll need to wait for the three GitHub service calls to complete before rendering the chart.

This could be achieved like this:

function tryRender() {
    if (getFollowedTmp && getFollowersTmp && getStarredTmp) {
         var myChart = new Chart(...);
    }
}

GitHubService.getFollowed(function (data) {
    getFollowedTmp = data.length;
    tryRender();
});
GitHubService.getFollowers(function (data) {
    getFollowersTmp = data.length;
    tryRender();
});
GitHubService.getStarred(function (data) {
    getStarredTmp = data.length;
    tryRender();
});

However that isn’t overly elegant. If your GitHubService calls return promises (Many ajax libraries do) you could do:

Promise.all([
    GitHubService.getFollowed(),
    GitHubService.getFollowers(),
    GitHubService.getStarred()
]).then(function(result) {
    var getFollowedTmp = result[0].length;   
    var getFollowersTmp = result[1].length;
    var getStarredTmp = result[2].length;
    var myChart = new Chart(...);
});

3đź‘Ť

methods in GitHubService are async. When you call alert(“”), you’re blocking execution from going to the next line and thus giving the git hub service time to run and return.

Here’s an example of chaning with Jquery. Other js frameworks, will have similar concepts.

var task1  = $.getJSON("http://resourceUri");
var task2  = $.getJSON("http://resourceUri2");

$.when(task1, task2).done(function(task1Response, task2Response){
   var task1Result = task1Response[0];
   var task2Result = task2Response[0];

   //Do something with the data. Charting?
});

0đź‘Ť

One of the usual reasons that “removing blocking calls breaks my code” is because the blocking call gives time for the browser to load resources.

In your case I believe that getFollowersTmp, getFollowedTmp, getStarredTmp are not initialized in time.

One of the ways to solve it is to use AngularJS’s $q to make sure all dependencies are loaded before continuing.

Leave a comment