Consolidate and arrange the results of several HTTP requests to a single endpoint

My goal is to send multiple requests to an API, merge and sort the results, and then assign them to the this.products$ observable. The current code mostly accomplishes this by combining all the results into one list.

The fetchIds() method retrieves parameters from a store. sliceToArrays(any[], number) takes these parameters and divides them into smaller chunks. I do this to prevent the URL from becoming too long for the GET request with this.api.listProducts([], ''), as URLs have a maximum character limit that can be exceeded with too many IDs.

However, I'm facing an issue where the merged results are not sorted properly; it sorts two lists separately before merging them, resulting in [A, B, C, A, B, C] instead of the desired [A, A, B, B, C, C].

ngOnInit() {
this.pageSize = 100;

this.products$ = this.fetchIds().pipe(
  mergeMap(ids =>
    forkJoin(this.sliceToArrays(ids, this.pageSize).map(idsList => this.api.listProducts(idsList, 'watchlist'))).pipe(
      mergeMap(products => merge(...products)),
      toArray(),
      map(products => sortBy(products, ['inventoryStatus', 'authorLastFirst']))
))); }

sliceToArrays(input: any[], maxSliceSize: number): any[][] {
const slices = Math.floor((input.length + maxSliceSize - 1) / maxSliceSize);
const collection: any[][] = [];
for (let i = 1; i <= slices; i++) {
  collection.push(input.slice((i - 1) * maxSliceSize, i * maxSliceSize));
}
return collection; }

fetchSkus() {
return this.watchListStore.items.pipe(
  filter(watchlist => watchlist !== null),
  map(watchlist => watchlist.map(i => i.id))
); }

I'm seeking guidance on how to resolve this issue. I've been experimenting with different solutions for days, but Angular and TypeScript are not my areas of expertise.

Answer №1

I am facing an issue with sorting the merged result; it seems to sort two lists individually before combining them, resulting in the output [A, B, C, A, B, C] instead of the desired [A, A, B, B, C, C].

I believe you can simplify your stream a bit and also ensure proper error handling. You may consider a technique like this:

this.products$ = this.fetchids().pipe(
  map(ids => this.sliceToArrays(ids, this.pageSize)),
  switchMap(idLists => combineLatest(...idsList.map(ids => this.api.listProducts(ids, 'watchlist')))),
  map(productLists => productLists.reduce((acc, curr) => ([...acc, ...curr]), [])),
  map(products => products.sort((a, b) => a.inventoryStatus.localCompare(b.inventoryStatus))),
  catchError(error => of([])) // also handle errors gracefully for UI
)

For complex logic like this, I prefer creating a more readable layer and encapsulating the intricate details within functions:

this.products$ = this.fetchids().pipe(
  map(ids => splitIdsIntoQueriableChunks(ids, this.pageSize)),
  switchMap(idLists => fetchAllProducts(idLists)),
  map(productLists => mergeProducts(productLists)),
  map(products => sortProducts(products)),
  catchError(error => notifyError(error))
)

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

Methods for hiding and showing elements within an ngFor iteration?

I am working on an ngFor loop to display content in a single line, with the option to expand the card when clicked. The goal is to only show the first three items initially and hide the rest until the "show more" button is clicked. let fruits = [apple, o ...

Error message: Ionic 3 Angular Native Screenshot encounters a TypeError Issue

i am currently utilizing https://ionicframework.com/docs/native/screenshot/ here is how my code appears: app.module.ts import { Screenshot } from '@ionic-native/screenshot'; providers: [ StatusBar, ThemeProvider, OpportunityServic ...

Do not overlook any new error messages related to abstract classes

One of the challenges I'm facing is creating an instance of an abstract class within one of its functions. When using new this() in inherited classes, a new instance of the child class is created rather than the abstract class. Typescript throws erro ...

Explore the functionalities of RxJS filter operators by applying them to a stream of arrays

Is it possible to work with a stream of arrays, such as filtering, and then emit the arrays again without concatenating the elements of the arrays or using regular array operators? For example, if I have an observable containing a single array, I can perfo ...

Installing npm creates a whopping 267 sub-folders when following the Official Angular2 Quickstart Tutorial

I am new to learning Angular and Node.js, so I decided to follow the official Angular2 documentation. Following Step 1 of the guide, I created package.json, tsconfig.json, and systemjs.config.js by copying the provided sample code. Then, as instructed, I ...

Stop the print dialog box from appearing when using the Ctrl + P shortcut

I'm working on an Angular app and I want to prevent the print dialog from opening when pressing "Ctrl + P". To address this issue, I have implemented the following code: window.onbeforeprint = (event) => { event.stopPropagation(); cons ...

What is the best way to execute code after an element has been included in ngFor in Angular 2+?

Within my component, there is a function that adds an element to an array displayed using *ngFor in the view. After adding the element to the array, I want to target it by ID and scroll to it. However, the issue is that this code runs before the element a ...

The input field cannot be accessed via touch on mobile devices

<div class="form-group row pswrd" style="padding: 0px 10px"> <div id="email" class="col-md-12 col-xs-12"> <input type="password" class="form-control c_fname" id="c" #pswd name="password" placeholder="password" [(ngModel)]="user.passwor ...

Get a single object from an array with .single method provided by @ngrx

Seeking to retrieve an Observable containing a single object from an array of objects in my store. I aim to utilize the .single operator, which should throw an exception if there is not exactly 1 object present. However, I'm struggling with this as my ...

Error: Syntax error - there was an unexpected token '.'

An error occurred with SyntaxError: Unexpected token '.' in the file path C:\Users\bruno\OneDrive\Área de Trabalho\DEV Bruno\devapi\node\src\views\layouts\layout01.ejs while compiling ejs I ...

challenge communicating between Angular and Node using CORS plugin

I've been researching how to enable CORS in node/express and have tried implementing various solutions, but without any success. Here is my angular request: function getPhotos(location) { var url = 'https://api.instagram.com/v1/media/sear ...

The error message "Can't resolve all parameters for CustomerService" is preventing Angular from injecting HttpClient

I have a customerService where I am attempting to inject httpClient. The error occurs on the line where I commented //error happens on this line. Everything works fine until I try to inject httpClient into my service. The error message is: `compiler.js: ...

Is it possible for TypeScript to manage a dynamic return type that is not determined by a function parameter?

I am facing a challenge with dynamic type checking using a param type and seeking help to solve it. Even though it might be a difficult task, any assistance would be greatly appreciated! Consider the following code: class DefaultClass { defaultProp: n ...

What is the best way to retrieve the final entry from a JSON file while using json server with Angular?

I'm currently working with a JSON file where I am making post requests followed by get requests. My goal is to retrieve the latest record in each get request after submitting a post request. For example: [ { "id": 1, "title&qu ...

The compilation error in Visual Studio 2015 is indicating that the VS 11 Common tools cannot be located

While developing an Angular 2 application in Visual Studio 2015, I encountered a compile error after installing Npm through NuGet. Severity Code Description Project File Line Suppression State Error The command " IF EXIST "%VS110COMNTOOL ...

Having trouble connecting my Node.js server to my Angular application

I encountered an issue while trying to upload an image using Angular and Node.js on the server-side. Unfortunately, when attempting to view the webpage, I am unable to see anything. Here is the browser output: https://i.stack.imgur.com/t9MrF.png Below is ...

Event when a panel menu in PrimeNG is clicked

<p-panelMenu [model]="items" [style]="{'width':'300px'}" (click)="clicked($event)"></p-panelMenu>`<p-dialog header="Title" [(visible)]="display"> page 1 ` this is my ts ` click: any; display: boolean = false; ...

Believed I had a clear understanding of the situation

Within the following code snippet, I am utilizing a service (Angular) to extract text using a fileReader and implementing a promise for the asynchronous part. However, I am encountering an issue that appears to be related to scope, which is causing confusi ...

Grouping Columns in an HTML Table using Angular 4

I'm currently faced with the task of retrieving flat data from an API and presenting it in an HTML table using Angular 4. I'm a bit unsure about how to iterate over the data, possibly using a for-each loop. I have attempted to utilize ngFor but I ...

Connecting the SignalR client to various servers

I am currently incorporating SignalR version 2.x into my ASP.Net MVC application, which is also using the same version of SignalR in my Angular client app. The ASP.Net MVC application is hosted at http://localhost:42080, while the Angular app is hosted at ...