Tips for efficiently waiting and receiving responses for every HttpClient service call within a loop in Angular 4

I am facing a situation where I must iterate through a loop to retrieve the descriptions of respective items. These descriptions need to be included in a datatable along with the item Ids and other details.

addDescription(){
this.arrayOfItems.forEach(element => {

   // CALL a function for making a service call
   this.fetchDescription(element);

   //CODE TO DECLARE AN INTERFACE FOR ASSIGNING VALUES, e.g.

   // ITEM_ID : element.id,
   // ITEM_DEF : this.fetchedDescription.join("\n")
}

Function body:

fetchDescription(elementToFetchDesc){

 //Declare HTTPPARAMS in PassingParams variable

 this.componentService.getDesc(PassingParams)
         .subscribe((response: HttpResponse<any>) => {
                if(response.status ==200){
                    this.fetchedDescription = reponse.body.output.slice(6,-1);
                }
                //Code if response status is NOT 200
}

In componentService Service:

construcutor(private httpConn: HttpClient){}

getDesc(Params){
    // Declare URL
    return this.httpConn.get(URL, {params: Params, observe: 'response'});
}

The challenge:

Due to the asynchronous nature of the subscription within the loop, the description is not being assigned to the variable (ITEM_DEF) in the interface after running the loop using forEach.

To address this issue, I made a slight modification by implementing the use of promise. In the service, I added:

 import 'rxjs/add/operator/toPromise';

And updated the service method as follows:

 return this.httpConn.get(URL, {params: Params, observe: 'response'})
                     .toPromise();    // converted observable to promise

Also, I made a change in the component: Within the fetchDescription function:

replaced .subscribe with .then

However, the issue still persists. I would appreciate any insights on where I may have gone wrong in implementing this logic.

Answer №1

To solve this issue, you need to convert observables into promises without relying on the 'then' method.

For example:

Here is a service function that sends the request:

sendMyRequest(num) {
   return this.http.get('http://anotherUrl.com/' + num).toPromise(); 
}

This function can be used to send multiple requests in a component class:

 async sendAllRequests() {
    let responses = [];
    for(let i = 0; i < 5; i++) {
        responses[i] = await this.myService.sendMyRequest();
    }
  // All results have been retrieved!
 }

Answer №2

Solution:

Function Body:

fetchingDescriptionData(dataToRetrieve):  Observable<string> {

  //Setting HTTP parameters in postData variable

  return this.componentService.retrieveDesc(postData)
      .map((response: HttpResponse<any>) => {
          if(response.status ==200){
             return reponse.body.result.extract.slice(6,-1);
          }
       });
     }
  }

Call:

this.fetchingDescriptionData(content).subscribe((details: string) => {
   ITEM_NUMBER : content.number,
   ITEM_DETAILS : details
});

Answer №3

To achieve this functionality, it is recommended to utilize the rxjs library.

checkConnectionStatus(url: string, id: string): Observable<string> {
const trigger$ = new Subject<string>();
const time = Date.now();

return trigger$.asObservable().startWith(url).concatMap((u) => {
  return this.sendRequest(u).map(() => {
    trigger$.complete();

    return id;
  }).catch((err) => {
      trigger$.next(u);

    return Observable.empty<any>();
  });
});
}


protected sendRequest(url: string): Observable<any> {
return this.http.get(url)
  .catch(err => Observable.throw(err));
}

The key concept in this code snippet is the usage of the concatMap operator, which ensures that the next observable is fired only after the completion of the first one, meaning that the response from the initial API call is received. By invoking the method complete() on the trigger$ subject, you can effectively end the observable and any ongoing API calls. It may be necessary to adjust how you handle calling complete() based on your specific requirements.

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

Utilizing Enum Lowercase as Index Key Type in TypeScript

Is there a way in TypeScript to use the lower case of an enum as an index key type? I have an enum defined as: export enum NameSet { Taxi = 'Taxi', Bus = 'Bus', Empty = '', } I want to define an object with keys based o ...

the "then" function is causing issues in my TypeScript Node code

My code looks like this: var fs = require('fs'); var util = require('util'); var files = fs.readdirSync('*/path to my folder that contains subfolders*/') async function getfilenum(){ var files_v_num = [] for(const i in fi ...

Angular 6 Bootstrap Fixed Positioning

Looking to implement affix or scrollspy functionality from Bootstrap 4 into Angular 6, I've been searching for existing libraries. Came across JonnyBGod's scrollspy, but it appears to be designed for Angular 5 and uses rxjs 5. Does anyone know of ...

What could be causing this issue of the Angular Material table not displaying properly?

I have been developing a Contacts application using Angular 9 and Angular Material. The goal is to display contact information and an image for each contact in a table row within the list component. Within my app.module.ts, I have imported various modules ...

What steps can I take to improve my code and fix lint errors?

I've been working on creating test cases for a switch case scenario, and so far I have two test cases in place. However, I'm encountering a lint error that requests me to update or refactor the function in order to avoid duplicating code. Since m ...

Tips for resolving the issue: Encountered an unexpected token < when parsing JSON data at position 0 using the JSON.parse function

I encountered an error when working on the code mentioned in this post. After removing .json() from response.json() in my code snippet below, the error message changed: return this.http.post('http://localhost:3000/sign-up', body, {headers: head ...

Adjust the size of an event in the Angular Full Calendar with Chronofy, while utilizing constraints to control the drag and drop functionality

I'm currently in the process of developing an availability calendar for scheduling meetings during open times. If a time slot is unavailable, users should not be able to place an event there. While I have successfully implemented this feature, I am ...

Issue with md-sidenav not opening in the correct direction from right to left

I am struggling to get the side navigation to open from right to left. Despite using the align property and setting it to "rtl", I can't seem to make it work properly. <md-sidenav-container class="example-container"> <div class="example-si ...

Ways to obtain the component reference when clicking in Angular 2?

<!--snippet from template file--> <custom-element ... other attributes (click)="handleClick()" </custom-element> @Component({ //selector and templateUrl }) class MainComponent{ handleClick(){ // Obtaining the re ...

Using TypeScript's Non-Null Assertion Operators in combination with square brackets []

One way to assert that an object has a certain property is by using the `!.` syntax as shown below: type Person = { name: string; age: number; gender?: string; } const myPerson: Person = { name: 'John Cena', age: 123, gender: 's ...

How can we prevent transform Omit into Pick in Typescript when utilizing generics?

Is there a way to prevent this behavior? It's crucial when compiling type declarations solely for libraries. I specifically require it for compiling declarations only: tsc --declaration true --emitDeclarationOnly true Here is a minimal example of t ...

Navigating between primary and named routes in Angular using RouterLink

After struggling for a while, I finally managed to get this code working: this.router.navigateByUrl('/live-chat(subnav:subnav)'); However, I am facing difficulty in replicating the same behavior using a [routerLink]='' directive. The m ...

Do not consider node_modules folder in the list of "issues"

Currently, I am executing the following task: { "taskName": "tsc watch", "command": "tsc -w", "type": "shell", "problemMatcher": "$tsc-watch" } using this specific tsconfig setup: { "compileOnSave": true, "files": ...

What is the method for passing an element in Angular2 Typescript binding?

Is there a way to retrieve the specific HTML dom element passed through a binding in Angular? I'm having trouble figuring it out, so here is the relevant code snippet: donut-chart.html <div class="donut-chart" (donut)="$element"> ...

An unusual situation occurs in Angular 2 when using Zone.js and CommonJS modules: the code within an IF statement is executed even when the condition

After numerous checks, I have come across a peculiar anomaly. Within my Angular 2 service, I am loading a @type definition (typescript 2) that in turn loads a commmon.js module (visionmedia/debug). Inside this common.js module, there is a simple if stateme ...

Lazy Loading Angular Components from a Separate Directory Beyond the App Folder

Having issues with lazy loading a module in my Angular project. Here is the current directory structure and code: I'm attempting to Lazy Load this module "tsdmns-modules/loader-module/tsdmns-loader-module.module" from "app/app-routing.module" an ...

Determining the optimal size for the thumb on a mat slider

Currently, I have incorporated a mat slider into my Angular application. For reference, you can view the Stackblitz link here: https://stackblitz.com/edit/angular-material-custom-slider?file=app%2Fslider-overview-example.ts The issue I am encountering is ...

The Date Filter is causing a glitch in formatting the date value

I have a variable called dateSubmitted with the value of "dateSubmitted": "07-09-20:11:03:30" Currently, I am utilizing Angular Version 7 Within my HTML code, I am using the date filter to format the date like so: <td> {{element.dateSubmi ...

Are there any alternative methods to define a constructor function in TypeScript that do not involve utilizing classes? Upon researching on this subject, it appears that all sources suggest using classes

Is it possible to transform this class declaration into a constructor function without losing TypeScript compatibility? class Animal { constructor(public name: string, public energy: string) {} } ...

Guide for creating a function that accepts an array containing multiple arrays as input

I am working with a function called drawSnake and it is being invoked in the following manner: drawSnake( [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], ] ); How should I format the input for this function? I have attempted using Array<Array<[numb ...