Displaying information before it is fully loaded due to asynchronous calls

Having an issue where data from a JSON file is loading after a function has completed in JavaScript, causing it to not display properly in the browser. I've been researching alternative solutions through this stackoverflow post which offers some workarounds, but my challenge lies in implementing these without relying on JQuery. While JQuery would simplify the process, I'm restricted to using pure JavaScript only.

To retrieve the JSON information:

// Function to fetch 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();
    }

Next, the JSON data is transformed into a JavaScript object:

this.GetQuiz = function () {
        var thisQuiz = this;
        // Retrieve quiz information from the JSON folder
        app.getJSON('json/demo.json', function(err, data) {
            if (err != null) { // Handle errors
                console.log('Unable to load quiz: ' + err);
            } else {
                // Assign data to object properties
                this.Title = data.title;
                this.Introduction = data.longtitle;
                this.HeroImage = imgBase + 'products/' + data.img;
                this.About = data.extra;
                // Set How To Play text based on quiz type
                if(this.Type == 'Knowledge') {
                    this.HowToPlayText = "Knowledge, how to play text...";
                } else if (this.Type == 'Identity') {
                    this.HowToPlayText = "Identity, how to play text...";
                } else if (this.Type == 'TrueFalse') {
                    this.HowToPlayText = "True/false, how to play text...";
                }
                console.log('Loading quiz for ' + this.Title + ' range');
               
                thisQuiz.GetQuestions(); // Load Questions
            }
        }.bind(this));
    }.bind(this);

A separate function is called to display parts of the object in the browser:

this.QuizSelection = function () {
        // Update elements with quiz 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);
       
        app.ShowSection('head'); // Show Quiz Selection and Heading
        app.ShowSection('quizSelection');
        console.log('Quiz Selection');
    }.bind(this);

Both functions are triggered upon page load:

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

The main goal is to execute quiz.QuizSelection(); only after quiz.GetQuiz(); has finished processing.

Answer №1

Start by enabling the option to pass a callback function as an argument of GetQuiz

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

Next, within the callback of getJSON(), after verifying for if (err != null) in the following else section, verify if your callback is defined and if it is, execute it:

if (typeof callback === 'function')  {
  callback();
}
// another way to achieve this efficiently:
callback && callback();

Now you can simply use

quiz.GetQuiz(quiz.QuizSelection);

in order to maintain the desired sequence.

You may need to apply the same process to your thisQuiz.GetQuestions() method, if that also needs to occur before running

QuizSelection()</code. In such cases, you would pass on the callback from <code>quiz.GetQuiz()
to thisQuiz.GetQuestions().

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for transferring data from one asynchronous function to another in AngularJS

How to transfer a global variable value between two Angular functions? Here are the two global variables: $scope.genewtId = null; $scope.data1 = null; The two Angular functions in question are: $scope.getID = function() { Service1.getId("abc").then(f ...

What is the best way to iterate through an ID using jQuery?

After pulling the list of doctors in my area from the database and displaying it on my webpage, I now want to load each doctor's "About" content inside a Bootstrap modal. I added an "about" column within the same database table where the doctors' ...

Exploring the proper syntax of the reduce() method in JavaScript

Here are two codes that can be executed from any browser. Code1: let prices = [1, 2, 3, 4, 5]; let result = prices.reduce( (x,y)=>{x+y} ); // Reduces data from x to y. console.log(result); Code2: let prices = [1, 2, 3, 4, 5]; let result = prices.red ...

The method request.getParameter in Servlet may sometimes result in a null

My website utilizes JQuery to make an Ajax call to a servlet. function sendAjax() { $.ajax({ url: "/AddOrUpdateServlet", type: 'POST', dataType: 'json', ...

Can child components forward specific events to their parent component?

I created a basic component that triggers events whenever a button is clicked. InnerComponent.vue <template> <v-btn @click="emit('something-happened')">Click me</v-btn> </template> <script setup lang=" ...

Arranging array positions in ThreeJS

My BufferGeometry contains an array of x/y/z positions with almost 60,000 points (18,000 values), [3, 2, 1, 3, 2, 1, 3, 2, 1, ...] To obtain random points, I am considering shuffling these positions and then selecting the first 30,000. One idea is to fir ...

Stuck with the same icon even after a successful AJAX call

I am currently working on implementing a 'add to my list' function in my web app. The goal is to change the color of an icon when a user clicks on it, after sending the necessary data to the server. Despite successfully sending the data to the s ...

Bootstrap not recognizing jQuery despite jQuery being present

I'm currently working on an HTML project that involves using jQuery, Bootstrap, and jQuery easing. However, I've encountered some errors while testing the code: bootstrap.min.js:6 Uncaught TypeError: Bootstrap's JavaScript requires jQuery. ...

Jackson encounters difficulty when trying to serialize Joda DateTimeFormatter

I'm having trouble returning a JSON response in my Spring MVC 3 application, specifically with Joda's DateTimeFormatter. com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.joda.time.format.DateTimeFormat$Style ...

Creating a Custom Hot Module Replacement Hook for Vue.js and Webpack

Is there a way to create a hook that triggers when a Vue component is updated using hot module replacement? [HMR] App is up to date. Now I want to execute a specific method after the update. ...

Cannot work on repl.it; it seems to be incompatible with the freeCodeCamp - JavaScript Algorithms and Data Structures Projects: Roman Numeral Converter

Recently completed my Roman Numeral Converter and it functions correctly on repl.it. However, when testing it on freecodecamp, the output displayed: // running tests convertToRoman(2) should return "II". convertToRoman(3) should return "III". ... // tests ...

Output JSON in PHP with key-value pair

Why is this code not functioning as expected? What mistake have I made? $json = json_encode($myInstance->getData($id)); $result = json_decode($json,true); $i = 0; foreach ($result as $value) { echo '<div>'.$value[$i] ...

Issue: The initial parameter should be a File or Blob object

Hey there! I'm currently utilizing the compressorjs plugin for compressing images, but I'm encountering an issue when selecting images. You can find out more about the plugin here. Here is my code snippet: window.resolveLocalFileSystemURL( ...

Issue with mouseover in the jQuery area

As I navigate through a WordPress website, I am attempting to create a mandala using dynamic images. Utilizing jQuery and CSS areas, I aim to display the corresponding image when hovering over a specific section. However, I am facing an issue where there ...

Tips for managing content and tables that exceed their container's boundaries

On my webpage, I have a slide-out sidebar that shifts the other contents and causes overflow with a scrollbar. I want the content to remain inside the window and adjust according to the available space. Image of Slide-out Sidebar As seen in the image, t ...

What is the best way to retrieve the current value of a React useState hook within a setInterval function while using Highcharts

import Error from 'next/error' import React, { useState, useEffect } from 'react' import Highcharts from 'highcharts' import HighchartsReact from 'highcharts-react-official' function generateChart() { const [co ...

Unable to Interpret JSON in Universal Windows Platform

I developed a UWP application that parses data to JSON format. The JSON data can be found here. However, I am facing issues with parsing the "jawaban" section of the JSON data which is causing an error message to appear like this: https://i.stack.imgur.co ...

Tips for modifying JSON property names during the parsing process

As outlined in the JSON.parse documentation, a reviver function can be utilized to modify the value of each property within the JSON data. Here is an example: JSON.parse('{"FirstNum": 1, "SecondNum": 2, "ThirdNum": 3}', function(k, v) { return ...

Creating TypeScript Classes - Defining a Collection of Objects as a Class Property

I'm trying to figure out the best approach for declaring an array of objects as a property in TypeScript when defining a class. I need this for a form that will contain an unspecified number of checkboxes in an Angular Template-Driven form. Should I ...

Modifying an Object within a for-in loop

Hi there, I'm facing a challenge with updating an object that has child properties in my Angular application. Here is the initial object: $scope.osbStep = { test0Nav : { current : false, comp ...