tips on waiting for the outcome of an http request (synchronous http request, utilizing http request as a promise)

My TypeScript service loads base data through HTTP requests from a server. The requests are for various data, arranged in order from independent data to data that depends on other data. Due to the asynchronous nature of HTTP requests, there is no guarantee that loading data (such as customers in this case) will finish before loading the dependent data (such as devices) begins. I want the loading of dependent data (devices) to start only after the loading of referenced data (customers) has completed. I believe I need to use promises, but how do I implement this in the following code situation?

export class BaseDataService
{
  customers: Customer[] = new Array();
  devices: Device[] = new Array();

  // Loads the base data starting with independent data and then dependent data  
  loadBaseData() {
    this.loadCustomers();
    // This operation should start after loading customers has finished 
    this.loadDevices();
  }

  // Function to load customers and add them to the collection
  loadCustomers() {
    console.log("Load customers");

    var requestURL = 'https://myurl/customers_endpoint.php';
    var auth = window.localStorage.getItem('auth');
    var requestparam = "auth="+auth;

    var request = new XMLHttpRequest();
    request.open('POST', requestURL);
    request.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    request.send(requestparam);

    request.onload = () => {
      if (request.status === 200){ 
        console.log("Load customers response");
        var response = request.response;
        this.customers = this.parseCustomers(response);         
        console.log("Load customers complete");
    }
    else if (request.status === 401){
      alert("Unauthorized");              
    }
    else {
      alert("Unexpected error");
    }
  }
}

// Function to load devices and add them to the collection
loadDevices() {
  console.log("Load devices");

  var requestURL = 'https://myurl/devices_endpoint.php';
  var auth = window.localStorage.getItem('auth');
  var requestparam = "auth="+auth;

  var request = new XMLHttpRequest();
  request.open('POST', requestURL);
  request.setRequestHeader("content-type", "application/x-www-form-urlencoded");
  request.send(requestparam);

  request.onload = () => {
    if (request.status === 200){ 
      console.log("Load devices response");
      var response = request.response;          
      window.localStorage.setItem('devicesresponse', response);
      this.devices = this.parseDevices(response);          
      console.log("Load devices complete");
    }
    else if (request.status === 401){
      alert("Unauthorized");              
    }
    else {
      alert("Unexpected error");
    }
  }
}


// Function to parse JSON string into array of customers
parseCustomers(customersjson: string)
{
  let customerarray = JSON.parse(customersjson);
  let customers: Customer[] = [];
  for (let i = 0; i < customerarray.length; i++) {
      let customer: Customer = new Customer();
      customer.setId(customerarray[i]['id']);
      customer.setName(customerarray[i]['name']);
      customer.setPlace(customerarray[i]['place']);
      customer.setStreet(customerarray[i]['street']);

      customers[i] = customer;
  }
  return customers;
}

 // Function to parse JSON string into array of devices
 parseDevices(devicesjson: string)
 {
   let devicearray = JSON.parse(devicesjson);
   let devices: Device[] = [];
   for (let i = 0; i < devicearray.length; i++) {
      let device = new Device();
      device.setId(devicearray[i]['device_id']);
      device.setSerialnumber(devicearray[i]['serial_number']);
      device.setDescription(devicearray[i]['description']);
      device.setLocation(devicearray[i]['location']);

      devices[i] = device;
     }
    return devices;
  }
}

Answer №1

To utilize a callback with the 'load' functions, follow this example:

Instead of:

loadBaseData() {
    this.loadCustomers();
    // this operation should be started after loading customers has finished (the response json 
    //is parsed to an array of customers at set to the instance variable of this service class)
    this.loadDevices();
  }

Use this code:

loadBaseData() {
    this.loadCustomers(() => {
        this.loadDevices();
    });
  }

Incorporate the callback within request.onload:

// Loads the customers and adds them to the collection of customers.
// Also puts the response json string of the customers to the local storage.
loadCustomers(callback) { // <--- this is a callback passed to function
    // ... many code here ...
    request.onload = () => {
        // ... many code here ...
        console.log("Load customers complete");
        if (typeof callback === 'function') callback(); // <--- here we call it
    }
// ... many code here ...

Answer №2

To ensure that the response is received before proceeding with the next statements, you can perform a synchronous ajax call as demonstrated below:

xhr.open("POST",url,false);

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

Guide on executing dynamic queries with MySQL in Meteor

Attempting to execute dynamic queries against MySQL in Meteor using the numtel:mysql package has proven unsuccessful thus far. It seems that either I need guidance on passing dynamic arguments to the subscribe function, or I need to learn how to retrieve ...

focusing on the child element of the current event's target

As I was working on a project, I came across a tab-menu jQuery plugin that needed some modifications. The issue I encountered was that the tabs were absolutely positioned, causing them to be taken out of the flow and not contribute to the wrapping div&apos ...

Instructions on adding a file path to the package.json file

Is it possible to create a script in the package.json file that allows me to run a file located in the parent folder of the package.json file, rather than the same directory? I would like the syntax to be similar to this: "scripts": { "server": " ...

The NetSuite https.post() method is throwing an error that reads "Encountered unexpected character while parsing value: S. Path '', line 0, position 0"

I'm currently facing an issue when trying to send the JSON data request below to a 3rd party system using the "N/https" modules https.post() method. Upon sending the request, I receive a Response Code of "200" along with the Error Message "Unexpected ...

Leveraging jQuery to execute a post request and showcase the subsequent page seamlessly

I have set up a booking engine that utilizes a POST method. I incorporated the XDate library which is functioning perfectly. However, I am facing an issue where the booking engine is not displaying the new page from the booking engine website after executi ...

Retrieving precise information from a Json file with PHP

Hey there, I have a JSON file and I'm looking to extract certain data from it. Here's how the file appears: { "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, ...

Angularjs fails to refresh $scope changes

I'm facing an issue with my controller where the Gui $scope is not updating properly. After conducting some research, I discovered that using $timeout could potentially help. The service's processing time varies on different units and setting a ...

Clicking the delete button will halt the process once the user cancels the confirm alert

The website is now capable of extracting API data and displaying it in a table. Additionally, users can delete rows from the table by clicking on a button. (pic) Table and alert display after clicking the delete button Q: If I click cancel on the alert, ...

Tips for including subjects in JSON data

I am trying to include the subject in JSON data so that I can fetch it using $.each(data.subject). Below is my API code where I am retrieving all the data encoded in JSON format. Any assistance would be greatly appreciated. [{"id":"79","FirstName":"Elon", ...

Is there a workaround for the React useContext issue in Typescript aside from using <Partial>?

I am currently working on a React app that utilizes the useContext hook, but I am facing challenges with correctly typing my context. Here is the code snippet in question: import React, { useState, createContext } from 'react'; import endpoints f ...

The deployment is currently being carried out

Here is the javascript code snippet I am working with: $scope.fav_details = function(id1,id2,bio) { document.getElementById(id2).style.display="none"; document.getElementById(id1).style.display="block"; $scope.getLegislatorDeta ...

The act of composing a message for the alert

Can you provide some assistance with this particular issue? I am attempting to input text into a prompt alert, however, my current method involving switch_to.alert and send_keys is not working as intended. base_URL = "https://www.seleniumeasy.com/tes ...

Is there a way to adjust the quantity individually, both increasing and decreasing as needed?

I am currently working on implementing a shopping cart feature using pure JS that allows users to increase and decrease the quantity of items. When the + or - button is clicked, both items in the shopping cart will be affected simultaneously if there are 2 ...

Default parameter in Node.js is set when the callback function is the last parameter

Here's a simplified version of the function I'm working with: doSmthg (name, age, callback) { callback(name, age); } I want to set a default value for age if it's not provided. In ES6, I could do doSmthg(name, callback, age=42) {...}, b ...

Ways to link two PHP scripts

My code snippet below aims to select a location from a dropdown menu and generate a pie chart based on data fetched from a PostgreSQL database. However, I am facing an issue where the pie chart displays all column values instead of only the selected locati ...

Utilizing the "as" keyword for type assertion in a freshly created react application using create-react-app leads to the error message `Parsing error: Unexpected token, expected ";"`

After creating a new CRA project using yarn create react-app my-app --template typescript, I encountered an error when trying to run the development server with yarn start: src/App.tsx Line 5:24: Parsing error: Unexpected token, expected ";" ...

How can one retrieve the x and y coordinates from the client's browser and pass them to the server in a Bokeh server setup?

I'm currently working on a Bokeh server app called getcoords.py. To start the server, I use the command: bokeh serve getcoords.py. The app includes a HoverTool with a CustomJS callback function and a quad glyph configured to trigger a selected event o ...

What is the process for combining AngularJS filters?

I currently have a fragment object like this: [{id: 721, titulo: "Cotizador Gastos Médicos Bx+ 2019", descripcion: "Cotizador Gastos Médicos Bx+ Tarifas 2019", updateDate: "2020-03-25 14:30:22.0", idCategoria: "1", …}, {id: 88, titulo: "Cotizador GMM ...

Ag-Grid: Matching colors with filtering functionality

Can AG-Grid be configured to highlight matching cells during quick filtering? For example, if I have the following data: [ { firstName: 'Tom', lastName: 'Doe', company: 'Tesla' }, { firstName: 'Tim', lastName: & ...

What is the process for converting monthly data into an array?

I am working with an array of daily data that looks like this: var data = [{x: '2017-01-01', y: 100}, {x: '2017-01-02', y: 99}, /* entire year. */]; Each element in the array has an x field for date and a y field for a number. This ar ...