0

I have a problem where information from a JSON file is being loaded after the function is completed to display it to the browser in JavaScript. I've been studying this stackoverflow post that explains how to get around the problem, but I'm having trouble figuring out how to do this without the use of JQuery. I know JQuesry would be the better way to do it, unfortunately I'm constrained to only using JavaScript.

First I get the JSON information:

// Generic Function to get JSON data
    this.getJSON = function (url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', url, true);
        xhr.responseType = 'json';
        xhr.onload = function() {
            var status = xhr.status;
            if (status == 200) {
                callback(null, xhr.response);
            } else {
                callback(status);
            }
        };
        xhr.send();
    }

Then I put it into a JavaScript object:

this.GetQuiz = function () {
        var thisQuiz = this;
        // Get the extract the quiz from the JSON folder
        app.getJSON('json/demo.json', function(err, data) {
            if (err != null) { // If there's a problem
                // Add a debug for getting the quiz JSON
                console.log('Unable to load quiz: ' + err);
            } else {
                // Load the quiz into the quiz base
                this.Title = data.title;
                this.Introduction = data.longtitle;
                this.HeroImage = imgBase + 'products/' + data.img;
                this.About = data.extra;
                // Set How To Play
                if(this.Type == 'Knowledge') { // Knowledge Quiz
                    this.HowToPlayText = "Knowledge, how to play text...";
                } else if (this.Type == 'Identity') { // Identity Quiz
                    this.HowToPlayText = "Identity, how to play text...";
                } else if (this.Type == 'TrueFalse') { // TrueFalse Quiz
                    this.HowToPlayText = "True/false, how to play text...";
                }
                // Make sure we can see what we are loading if nothing displays
                console.log('We are loading the quiz for the ' + this.Title + ' range');
                // Load Questions
                thisQuiz.GetQuestions();
            }
        }.bind(this));
    }.bind(this);

Then I call a function to display parts of this object to the browser:

this.QuizSelection = function () {
        // Fill the ID's with the right info
        app.SetBackground('head', this.HeroImage);
        console.log('1 ' + this.HeroImage);
        app.LoadInnerHTML('breadcrumbs', 'Home / ' + this.Title);
        app.LoadInnerHTML('quizSelectionTitle',this.Title);
        console.log('2 ' + this.Title);
        app.LoadInnerHTML('quizSelectionIntro',this.Introduction);
        console.log('3 ' + this.Introduction);
        // Show the Quiz Selection and Heading
        app.ShowSection('head');
        app.ShowSection('quizSelection');
        console.log('Quiz Selection');
    }.bind(this);

This is all wrapped into two functions that I call as the page loads:

window.onload = function () {
    var quiz = new QuizBase('Knowledge', 'Product');
    quiz.GetQuiz();
    quiz.QuizSelection();
}

I basically need a way to run quiz.QuizSelection(); after quiz.GetQuiz(); completes.

Community
  • 1
  • 1
Web Develop Wolf
  • 5,996
  • 12
  • 52
  • 101

1 Answers1

1

First, make it possible to pass a callback function as an argument of GetQuiz

this.GetQuiz = function (callback) {
  ...
}

And then inside the callback of getJSON(), right after checking for if (err != null) in the folling else block, check if your callback is set and if so, call it:

if (typeof callback === 'function')  {
  callback();
}
// or a shorter way of doing this:
callback && callback();

Then you can just use

quiz.GetQuiz(quiz.QuizSelection);

to achieve the desired order.

You might have to do the same with your thisQuiz.GetQuestions() method, if that also has to happen before QuizSelection() can be run. So you would just pass on the callback from quiz.GetQuiz() to thisQuiz.GetQuestions().

Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
  • Thanks - where would 'inside the callback of getJSON()' be? Is that in the success part? So if it manages to get the JSON? – Web Develop Wolf Feb 13 '17 at 10:58
  • Right, sorry, that was a bit ambiguous. Exactly, that is also a callback function. And inside that, after you check for `if (err != null)`, in the `else` block, is where you check for and execute *your* callback function. – Constantin Groß Feb 13 '17 at 10:59