"Angular application experiencing navigation blockage due to multiple concurrent HTTP requests using RxJS - Implementation of priority-based cancel queue

I've come across similar threads, but I have yet to find a suitable solution for my specific issue.

Situation: Currently, I'm navigating on both the server side and client side simultaneously. This entails that every frontend navigation using routerLink triggers an HTTP request call to the server alongside any route accessed.

Scenario: While in the process of opening a dialog to create a position, I need to display a list of elements fetched from the API. Each element also requires loading an additional thumbnail. This involves one API call to retrieve 86 elements followed by 86 requests for their respective thumbnails. To prevent redundant calls, I store these elements in a service and check for existing elements before making new requests. The API calls are initiated upon opening the dialog.

getElementsWithThumbnails() {
    if (this.elementsSource.value.length === 0) {
        this.apiService.getElements().subscribe(
            (next) => {
                this.elementsSource.next(next);
                this.elementsSource.value.forEach((epl, index) => {
                    const format = 'JPG';
                    this.apiService.getThumbnail(epl.id, format, '400', '400', 'true').subscribe(
                        (blob) => {
                            epl.thumbnail = blob;
                        }
                    );
                });
            }
        );
    }
}

ThumbnailRequestMethod:

getThumbnail(
    elementId: string, format: string, width: string,
    height: string, sameratio: string
): Observable<SafeUrl> {
    return this.httpClient.get(
        this.apiUrl +
        `/elements/${elementId}/thumbnail?format=${format}&width=${width}&height=${height}&sameratio=${sameratio}`
        , {
            responseType: 'blob'
        }).pipe(
        map(res => {
            return this.blobToSanitizedUrl(res);
        })
    );
}

Issue: An obstacle arises when a user chooses to cancel the form and attempts to navigate backward or forward - they encounter a delay due to the pending navigation request.

Is there a method available to assign a lower priority to the thumbnail calls for smoother handling under less load?

Your insights are greatly appreciated.

Answer №1

One issue that arises is the browser's limitation on simultaneous requests to a single endpoint. Is the api located in the same origin as the frontend? If not, the limitation might be even more restrictive.

My suggested approach:

  1. Opt for using URLs for the thumbnails instead of embedding them directly in img tags. By setting the href, you can allow the browser to manage the image loading process. Building on this concept, consider implementing an "inview" directive to delay the loading of images until they are within view (based on business needs and specifications).

  2. Restrict the number of simultaneous requests to getThumbnail. You can achieve this by employing the concurrent parameter in mergeMap like so:

const format = 'JPG';
this.apiService.getElements()
  .pipe(
    switchMap(items => {
      this.elementsSource.next(items);
      return from(items);
    }),
    mergeMap(item => {
      return this.apiService
        .getThumbnail(item.id, format, '400', '400', 'true')
        .pipe(
          tap(blob => item.thumbnail = blob)
        )
    }, 2) // limit to maximum of 2 concurrent requests
  )
  .subscribe();

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

Simulating TypeDI service behavior in Jest

My current setup includes Node with TypeScript, TypeDI and Jest. I've been working on creating services that have dependencies on each other. For example: @Service() export class MainService{ constructor(private secondService: SecondService){} public ...

"Comparing the use of single Angular libraries versus multiple libraries on npm

I am considering consolidating all my libraries (57 in total) into a single folder called @my-organisation/team. This is because each library has many dependencies on one another and managing versioning & dependencies separately would be difficult. After s ...

Using placeholders with inputs in an Angular2 table generated by ngFor

I have an array public example = [['hallo', 'fruit', 'rose'], ['apple','book']] Currently, I am working on creating a table of inputs. The values in this table depend on the specific part that I am usin ...

Ensuring that files adhere to the required format, whether they be images

Three separate input fields are being used, each with its own name for identification. A validation method is called to ensure that the files selected in these input fields are not duplicates and that they are either images or PDFs but not both. While thi ...

Generate an observable by utilizing a component method which is triggered as an event handler

My current component setup looks like this: @Component({ template: ` ... <child-component (childEvent)="onChildEvent()"></child-component> ` }) export class ParentComponent { onChildEvent() { ... } } I am aiming to ...

Interactive style sheet hyperlink

I have developed a feature that allows me to preview a Google Font by linking the font style sheet. Although the stylesheet is successfully loaded, the text does not appear in the chosen font family. import { Input, Component } from '@angular/core&ap ...

Insert placeholder text without access to the input field

Is it possible to activate a placeholder in a component that is outside of the current context? For example: <foreign-component [config]="someConfig" placeholder="somePlaceholder"></foreign-component> The <foreign-compo ...

What could be the reason behind my Vue file triggering a TS6504 error and suggesting to "allowJs"?

My Vue 3 project, which incorporates TypeScript, is encountering an issue when I attempt to execute vue-tsc --noEmit. error TS6504: File '/proj/src/pages/Index.vue.__VLS_template.jsx' is a JavaScript file. Did you mean to enable the 'allowJs ...

The functionality of the Drawer component in material-ui v1.0 seems to be incompatible with TypeScript

Every time I try to utilize Drawer from [email protected] using typescript, I encounter the following error: TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Re ...

Exploring Typescript: Combining types (rather than intersecting them)

Let's analyze the scenario below type MergeFn = <K1 extends string, V1, K2 extends string, V2>( k1: K1, v1: V1, k2: K2, v2: V2 ) => ??? let mergeFn: MergeFn // actual implementation doesn't matter for this question What should b ...

What is the best way to store a logged-in user's email in a React

I have implemented a login API and I would like to save the email of the logged-in user in the state or another variable, so that I can display it in the header after successful login. The user's email is located in the data.email. The following code ...

The behavior of Angular 4 router is causing components to accumulate on routerLink navigation rather than being properly removed

While transitioning from a submodule's child route to another sibling child route, the router does not destroy the previous component. Instead, it appends the new one on forward and backward navigation. What causes this behavior? It begins in /#/sub ...

Using Ionic2 to connect with PHP server APIs

I am fairly new to working with ionic, although I have a basic understanding of angular2. My goal is to access an API created in PHP using the combination of ionic2 and angular2. feed.php header('Access-Control-Allow-Origin: *'); $db_ ...

What is the best way to locate this particular element on the webpage?

After using the right-click and selecting inspect element, I located the code of the desired element on the webpage: <input type="text" ng-if="!editing" ng-model="item.Price" ng-click="inputFocus()" ts="" required="" placeholder="قیمت :" class="ng- ...

Issue encountered: Upon executing 'ng add @angular/fire', an error was detected in the node_modules/firebase/compat/index.d.ts file while attempting to launch the Angular application

Recently, I decided to integrate Firebase into my project, but encountered a persistent error after installing the firebase module 'ng add @angular/fire' and running it with 'ng serve': Error: node_modules/firebase/compat/index.d.ts:770 ...

Using React Native components from an external package leads to errors

I created a collection of React Native components by utilizing this template to seamlessly integrate Storybook. Additionally, I incorporated nativewind, which essentially serves as a React Native adaptation of Tailwind CSS. The structure of my components i ...

The process of expanding a nested node in the Angular Material tree with deeply nested data

Within my Angular 7 application, I am utilizing a mat tree structure that contains nested array objects. The goal is to automatically expand specific nested sections after users make changes to the data within those sections. While I have successfully exp ...

Utilizing the relativeTo method within a guard across various feature modules

I am facing a challenge with two lazily loaded Feature Modules that have a similar flow consisting of Select, Review, and Confirm steps. I want to create a single Guard for the Review step that can navigate back to Select based on the current Module contex ...

Utilize the class or interface method's data type

In the context of a child component calling a callback provided by its parent, this situation is commonly seen in AngularJS. As I am utilizing TypeScript, I aim to implement strong typing for the callback in the child component. Here is the initial stat ...

Allowing Cross-Origin requests in Spring BootLet's configure the

Every time I attempt to communicate with my backend using my Angular client, I encounter a common error message when trying to perform POST, PUT, and DELETE requests: Access to XMLHttpRequest at 'http://localhost:8087/categories' from origin &ap ...