typescript loop with a callback function executed at the conclusion

I am struggling with this code and it's driving me crazy.

addUpSpecificDaysOfWeek(daysInMonth: any, callbackFunction: any){
    var data = [];
    var that = this;
    daysMonth.forEach(function(day){
      that.statsService.fetchData(that.userid, day).subscribe(async (res: any) => {
        data = JSON.parse(JSON.stringify(res));
        console.log(that.data);
        that.data = that.data.map( function(value, index) {
          return value + data[index];
        });
      });
    });
    callbackFunction("this should be at the end");
  }

In this piece of code, I am fetching arrays from a server and adding them together into 'that.data' element by element. The process is working as expected, but I intend to calculate an average of the final result. Currently, I'm just using the callback function to display a message and check if it reaches the end, however, "this should be at the end" is being displayed before the summation loop begins.

  myCustomCallback(argument: any){
    console.log(argument);
  }

This is where the main method is called:

this.addUpSpecificDaysOfWeek(daysInMonth, this.myCustomCallback);

Answer №1

Here is another approach using RxJS in a more elegant manner:

sumOfSpecificDaysInMonth(daysOfMonth: any, completionCallback: any){
    var values = [];
    var self = this;
    let observablesArray = []; 

    daysOfMonth.forEach(function(day){
      const obs = self.statsService.getData(self.userid, day);
      observablesArray.push(obs); 
      obs.subscribe(async (result: any) => {
        values = JSON.parse(JSON.stringify(result));
        console.log(self.values);
        self.values = self.values.map( function(val, index) {
          return val + values[index];
        });
      });
    });

    Observable.forkJoin(...observablesArray).subscribe(results => {
      completionCallback("this should be at the end");
    });
}

Answer №2

Unfortunately, handling this type of scenario in JavaScript can be quite tricky. Essentially, what this code does is initiate a request for each item in daysMonth in the background, and then execute your callback function once all the asynchronous requests have been completed.

The key is to track when all the tasks have finished executing before triggering your callback function. A possible solution could look something like this:

var numDone = 0;

daysMonth.forEach(function(day){
  that.statsService.getData(that.userid, day).subscribe(async (res: any) => {
    numDone++;

    data = JSON.parse(JSON.stringify(res));
    console.log(that.data);
    that.data = that.data.map( function(v, i) {
      return v + data[i];
    });

    if(numDone == daysMonth.length) {
      callback("All done!")
    }
  });
});

This approach allows us to process the data within the getData() callback and call the outer callback function with the desired data only when all tasks have been completed.

It's worth noting that managing multiple asynchronous operations can quickly become complex. The async library provides a more structured solution for handling such scenarios, offering functions like async.map that might simplify your implementation.

Answer №3

it's crucial to handle the observable in a different manner

you should run an array of asynchronous operations and then execute a callback function

your code ought to be structured like this

getTotalForSpecificDayOfMonth(daysInMonth: any, callback: any){
    var data = [];
    var self = this;
    Observable.mergeArray(daysInMonth.map(day=> self.statisticsService.fetchData(self.userId, day)).subscribe((responses)=>{

// process the data accordingly
  callback("this must be placed at the end"); })


  }

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

Is it possible to implement a feature in Angular and Bootstrap where the toggle menu can be closed by clicking anywhere on the page, rather than just the toggle button

I'm working on an Angular project where I've implemented a navbar component. The navbar is responsive and includes a toggle button that appears when the browser window is resized. This button allows users to hide or display the menus. One issue ...

How can you transform the outcome of a TYPO3 repository search into a JSON format?

Is it possible to convert the outcome of a "findAll()" function on a Repository into a JSON object, make changes to specific properties in JavaScript, and then send it back to the Action, converting it again for use by the Action to persist it in the datab ...

Storing and Retrieving User Identifiers in Next.js

Currently, I am developing a project using Next.js and I have the requirement to securely store the userId once a user logs in. This unique identifier is crucial for accessing personalized user data and creating dynamic URLs for the user profile menu. The ...

Is there a replacement for findIndex in Internet Explorer?

I am currently working on a code snippet for smooth navigation scroll to different sections. var lastId; var topMenu = $(".community-nav"); var topMenuHeight = topMenu.outerHeight() - 19; if(window.matchMedia("(max-width: 768px)").matches) ...

Fixing the "Package Manager Not Found" Issue when Deploying a Next.js Project on Vercel

Having created a website using Next.js and aiming to deploy it on Vercel, I encountered an error during the deployment process despite meticulously following the configuration steps. The error message displayed was: "Unable to determine package manage ...

Understanding Angular's transclusion functionality and how it interacts with scopes

I've been working on creating a directive for click-to-edit input fields. My goal was to make it an attribute type directive that can work with various types of input fields by simply transcluding the input field itself. However, I've encountere ...

Transferring Data from Python Script to Browser (with an xserver running on a Linux system)

Looking for suggestions on how to efficiently transfer data from a Python script to a web browser. The Python script, as well as the browser, are operating under an xServer environment in Linux (specifically Raspbian on Raspberry Pi). The script is respon ...

Trouble with apostrophes rendering in JavaScript on WordPress posts

My current challenge involves adding a post to Wordpress using an external script. This post includes a JavaScript section that contains an iframe for displaying movies. Knowing that Wordpress splits default tags, I have implemented a special plugin to han ...

Converting an HTML ul-li structure into a JavaScript object: Steps to save the structure

My HTML structure uses ul and li elements as shown below: <ul class="treeview" id="productTree"> <li class="collapsable lastCollapsable"> <div class="hitarea collapsable-hitarea lastCollapsable-hitarea"></div> <span ...

Step-by-step guide to implementing a Form filter in your Angular application

I am trying to create a filter with two main input types, text and Date. I have created an array: arr = [1, 2, 3] which represents the number of rows in the filter. However, when I loop through and change the label to dateOfBirth, all input rows are being ...

Is there a way to adjust the parameters of objects within my scene that were loaded using OBJMTLLoader?

I am working on a scene that includes 3 cubes and a DAT.GUI menu. My goal is to switch any cube to wireframe mode when it is selected in the menu individually. Although my code is successful for 2 out of the 3 cubes, I am facing an issue where the first c ...

Navigating through an array of latitude and longitude pairs during an AJAX request

Just starting out with PHP/AJAX and I could use some guidance. Currently, I have a leaflet map where I'm attempting to link two AJAX calls together. The initial AJAX call retrieves data based on a selected country ISO code. Subsequently, I've ut ...

showing the upload preview and disabling automatic uploading in Dropzone with React

Currently, when the user clicks the upload button and selects a file, it automatically uploads the file. However, I do not want this automatic upload to happen. Instead, I want to display the selected files to the user first before uploading them. I need ...

Can you provide guidance on how to successfully transfer an array of JSON objects from the script section of an HTML file to the JavaScript

My webpage contains an array of JSON objects that I need to send to the server. The array, stored in a variable called results, appears normal when checked in the console before trying to POST it. Here is a sample of the data: 0: {id: 02934, uName: "Ben", ...

Display a pop-up window using window.open and automatically print its contents using window.print upon loading

I am trying to open a new window with some HTML content and then automatically print it. Here is the code snippet I have: var windowObject = window.open('','windowObject','arguments...'); windowObject.document.write("<html ...

Is it achievable to animate dynamic height using CSS? Open to JS alternatives as well

I am currently utilizing AngularJS, which enables me to utilize ng-show and ng-hide in order to display or hide elements based on a logical condition. My goal is to animate the size changes of the container when the child objects are shown or hidden, creat ...

Three Divs stacked on top of each other, with varying heights based on

I am seeking a solution for creating a layout with three vertically stacked divs. The top div must have a fixed height of 60px. The middle div might contain content exceeding its height, therefore we've set it to overflow: auto. But regardless of th ...

Firebase cloud function encountered an issue: Error: EISDIR - attempting to perform an unauthorized operation on a directory

I am currently working on a task that involves downloading an image from a URL and then uploading it to my Firebase cloud storage. Below is the code I have implemented for this process. import * as functions from 'firebase-functions'; import * a ...

Adding elements to my state array - Utilizing Nextjs/React/Javascript

After fetching data from 2 different APIs that each return an object, I have stored them in separate states. Now, I want to merge these two objects into a single state that contains both of them as an array. However, when I try to do this, the second obj ...

Set the position of a div element to be fixed

I am currently working on a straightforward application that requires implementing a parallax effect. Here are the methods I have experimented with so far: - Inserting an image within a div with the class parallax. - Subsequently, adding an overlay div ...