Is there a way for me to come back after all child http requests have finished within a parent http request?

I am currently utilizing an API that provides detailed information on kills in a game. The initial endpoint returns an ID for the kill event, followed by a second endpoint to retrieve the names of both the killer and the killed player.

Due to the structure of this API, I need to first request the event ID and then wait for all IDs in the returned array to fetch results before processing the entire kill array:

    requestify.get(url).then(function (response) {
        var events = [];
        if (response.body && response.body.length > 0) {
            data = JSON.parse(response.body);
            if (data.hasOwnProperty('events')) {
                events = data.events.map(function(event) {
                    return this.getDataForHeroKillId(event.id, function(killInfo) {
                        return { killer: killInfo.killer, killed: killInfo.killed, timestamp: event.time };
                    });
                }.bind(this));
                console.log('events is: ', events);
            }
        }
        return Promise.all(events);
    }.bind(this));

The getKillInformation function is structured as follows:

KillFeed.prototype.getKillInformation = function(id, cb) {
var data = null;
    requestify.get(url).then(function (response) {
        var event = {};
        if (response.body && response.body.length > 0) {
            data = JSON.parse(response.body);
            if (data.hasOwnProperty('Killer')) {
                event = { killer: data.Killer, killed: data.Killed};
            }
        }
        cb(event);
    });
};

In my attempt with the second method, I intended to callback the result of each individual request, and once they had all been executed, the new array would hold the data. However, due to the asynchronous nature of JavaScript, my code block continues to return an empty events array. This non-blocking behavior is understandable, as blocking the event queue while making an HTTP request is not ideal. How can I address this issue?

Answer №1

To achieve this, one can utilize promises.

requestify.get(url).then(function (response) {
    var events = [];

    if (response.body && response.body.length > 0) {
        var data = JSON.parse(response.body);
        if (data.hasOwnProperty('events')) {
            // Processing the kill information begins here
            events = data.events.map(function(event) {
                return this.obtainKillInfo(event.id).then(function(killInfo) {
                    return { killer: killInfo.killer, killed: killInfo.killed, timestamp: event['time1'] };
                });
            }.bind(this));
        }
    }

    return Promise.all(events);
});

KillFeed.prototype.obtainKillInfo = function(id) {
    var url = 'internal_url';
    return requestify.get(url).then(function (response) {
        if (response.body && response.body.length > 0) {
            var data = JSON.parse(response.body);
            if (data.hasOwnProperty('killer')) {
                return { killer: data.Killer, killed: data.Killed };
            }
        }
    });
};

Answer №2

One option is to utilize the async library with its waterfall method. Although primarily a NodeJS module, it can also be adapted for use in the browser.

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

What is the best way to reposition a column as a row when the user interface transitions to a different screen or

Welcome to my UI experience! https://i.stack.imgur.com/gOwAn.png Check out how the UI adapts when I resize the browser: https://i.stack.imgur.com/MyxpR.png I aim for the left component to be visible first, followed by scrolling to see the right compone ...

What is the best way to set up jest to generate coverage reports for Selenium tests?

I recently made the switch to using jest for testing my JavaScript project after encountering coverage issues with mocha and chai. While my unit tests are providing coverage data, my Selenium tests are not. I've tried various solutions found in outdat ...

You are unable to use multiple background colors on a material UI snackbar

Is there a way to apply multiple background colors to a material UI snackbar? I attempted using linear-gradient as shown below, but it didn't work. import Snackbar from 'material-ui/Snackbar'; const bodyStyle = { border: `2px solid ${co ...

What is the best way to determine if a radio button has been chosen, and proceed to the next radio button to display varied information?

The goal is to display the <div class="resp"> below each radio button when it is selected, with different content in each <div class="resp">. The previously selected <div class="resp"> should be hidden when a new radio button is chosen. O ...

"Optimize Magellan Sidebar for Mobile Devices by Relocating it to the Bottom of the Page

After spending a week working with Foundation 5 framework, I'm curious if there is a straightforward way to make my magellan sidebar shift to the bottom of the page when viewed on mobile or tablets. <div data-magellan-expedition="fixed"> <di ...

Troubleshooting: Issue with binding nested data property using bracket access in Vue3 v-model

Having an issue in Vue3 where I am unable to bind a nested property to v-model correctly. Check out the source code below: Template: <div id="app"> <span>{{level1.level2.level3}}</span> <br/> <span>{{level1[&ap ...

Update an existing item or add a new one if it is not already present

I am attempting to create a functionality similar to canva.com, where users can select images from the sidebar and drop them anywhere in the "div", allowing multiple images with individual positions. However, when I use setState(prevState=>{return [...p ...

Generating PDF files from HTML documents using Angular

I am currently working on an Angular 11 application and I have a specific requirement to download a PDF file from a given HTML content. The challenge is that the HTML content exists independent of my Angular app and looks something like this: < ...

The database server is not appearing on the main.js page of the client

My client's main.js file contains code that is meant to display previous form entries on the webpage, but after submitting the form, no entries appear on the HTML page. My server is running on port 7777 and the root route works in Postman, as does the ...

Is there a way to extract the query string from a file in order to query the database using ExpressJS?

I am having trouble with this code snippet as it doesn't seem to be working properly. var content = fs.readFileSync('/home/diegonode/Desktop/ExpressCart-master/views/partials2/menu8xz.hbs', 'utf8' ); req.db.products.find( co ...

Issue with Typescript Application not navigating into the node_modules directory

After attempting to load the app from the root directory of our server, it became clear that this was not a practical solution due to the way our application uses pretty URLs. For instance, trying to access a page with a URL like http://www.website.com/mod ...

What is the process for syncing ng-model with external data sources?

Here is a question that I have pondered: Let's consider the HTML code snippet below: <div id="container" ng-controller="Controller"> <my-tag ng-model="values"></my-tag> </div> Now, take a look at the controller defined a ...

Configuring Vuex State

Currently, I have a prop that is being bound to a child component. My goal is to eliminate this binding and instead assign the value to a data property in a vuex global state. <VideoPip :asset="asset" v-show="pipEnabled === true" /&g ...

Why is the reference of `this` pointing to `o` in this scenario (o.method)() rather than the global object?

Let's consider the scenario with an object: var o = { prop: 3, method: function() {return this.prop} } My expectation was that calling (o.method)() would result in undefined, but instead it returned 3, indicating that the reference of this ...

Conceal or remove disabled years in Angular Material datepicker

I previously disabled years prior to 2018, but now I would like to hide or delete them. The year selection range currently starts from 1998, but it should begin at 2018 instead. Is there a way to display only 3-4 years instead of the current 24-year rang ...

I am experiencing issues with my JavaScript not functioning properly in conjunction with my HTML and CSS. I am uncertain about the root cause of the problem (The console is displaying an error message:

I am facing challenges in creating a content slider and encountering issues with its functionality. Specifically, when testing locally, I noticed that the current-slide fades out and back in upon clicking the arrows left or right, but the slide content is ...

Changing the position of the icon in the bootstrap validator

I'm currently attempting to validate form fields in a web project. The goal is to achieve a specific result, similar to the image below: https://i.stack.imgur.com/EVeJf.png While I have made progress with a simple solution that almost meets the requi ...

The React component fails to render on the screen

Upon retrieving data from the database server, attempts to render it result in the data being shown in the console log but not displayed in the component. What could be causing this issue? useEffect(() => { readRequest().then(setTodos); c ...

Create a basic cache within an AngularJS service to store data retrieved from HTTP requests, ensuring that the cache returns an object

Looking to implement a simple caching mechanism in an AngularJS service for data retrieved from HTTP requests. The goal is to always reference the same object to avoid duplicating requests. Below is an example code snippet showcasing the issue at hand. Li ...

Using Angular 4 to import an HTML file

I am trying to save test.svg in a component variable 'a' or svgicon.component.html. To achieve this, I have created the svgicon.component.ts file. However, it's not working. What steps should I take next? svgicon.component.ts import ...