Pause and be patient while in the function that delivers an observable

I have a function that loads user details and returns an observable. This function is called from multiple places, but I want to prevent redundant calls by waiting until the result is loaded after the first call. Can anyone suggest how this can be accomplished using RxJs and Angular?

    getUser(): Observable<any> {
      return this.http.get('/userAuthenticated');
    }

One approach is to wait for the first call to complete and then save the result in a static variable:

    getUser(): Observable<any> {
      if(!this.userIsLoading) {
        this.userIsLoading = true;
        return this.http.get('/userAuthenticated').pipe(
          tap((res: any) => {
            this.userIsLoading = false;
            this.User = res.data;
        }));
      } else {
        // Wait for the first call to complete
        return of(this.User);
      }
    }

Another idea is to define a static variable for the observable.

Any help would be appreciated.

Answer №1

In order to accomplish this, follow these steps:

  • Establish a fresh Observable attribute within your service/component and utilize the shareReplay operator to prevent calling the API repeatedly and distribute the outcome among all new subscribers.
  • Have the getUser function return the new Observable (You cannot directly incorporate the shareReplay here as each time getUser is invoked, it generates a new Observable with shareReplay, failing to provide the same one).

Consider implementing the following code snippet:

// import { shareReplay } from 'rxjs/operators';

private userSource$ = this.http.get('/userAuthenticated').pipe(shareReplay());

getUser(): Observable<any> {
  return this.userSource$;
}

Answer №2

req$ = this.http.get('/userAuthenticated').pipe(shareReplay(1));

getUserInfo(): Observable<any> {
  return this.req$
}

Utilize the shareReplay function to store the response data from the server after the initial request. Any subsequent subscriber will receive the cached information.

For more details on how to use shareReplay, check out the official documentation: https://rxjs.dev/api/operators/shareReplay

Answer №3

One of the notable features of Rxjs is the firstValueFrom() function, which allows you to get a promise that can be awaited.

  async fetchUser(): Promise<Observable<any>> {
    if (!this.loadingUser) {
      this.loadingUser = true;
      return this.http.get('/userAuthenticated').pipe(
        tap((response: any) => {
          this.loadingUser = false;
          this.UserData = response.data;
        })
      );
    } else {
      await firstValueFrom(this.http.get('/userAuthenticated'));
      return of(this.UserData);
    }
  }

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

Issues with Angular 2 template not refreshing during testing

I'm struggling to get this to function properly. it('should have the expected <h1> text', async(() => { let fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const sectionEl = fixture.debugElement.que ...

"I am looking for a way to receive a response from a loopback in Angular7

Currently, I am utilizing angular7 with loopback. While I can successfully retrieve data, I am unsure how to receive error messages and response statuses. It would be helpful for me to understand what my response code is at the time of the request. Output ...

Tips for effectively managing components during navigation within dynamically loaded components

Our interface includes 3 main navigations for tab views: tab1, tab2, and tab3. Additionally, there is a navigation from the side menu. Each tab dynamically loads components, allowing seamless navigation between different parts of the application. When sw ...

Issue with React-Toastify not displaying on the screen

After updating from React-Toastify version 7.0.3 to 9.0.3, I encountered an issue where notifications are not rendering at all. Here are the steps I followed: yarn add [email protected] Modified Notification file import React from "react" ...

Is it possible to integrate the extension library of three.js (including OBJLoader, SceneUtils, etc.) with Angular 6?

Attempting to implement the below code, however, it is not functioning as expected. npm install --save three-obj-loader import * as ThreeObjLoader from 'three-obj-loader'; const OBJLoader = ThreeObjLoader(THREE); let loader = new OBJLoader(): ...

Transform the CSS to a Mat-Form-Field containing a search box within it

I am currently working with Angular, Angular Material, and SCSS for my project. Here is the front-end code snippet that I am using: <mat-form-field class="custom-form-field" style="padding-top: 5px;padding-bottom: 0px; line-height: 0px; ...

Having trouble getting Laravel and Angular to filter data by categories?

I am currently developing an ecommerce project using Laravel and Angular. I have products and brands associated with these products. In my function to retrieve the products in Laravel, I have used a nullable parameter like this: public function index($bran ...

What is the best way to decouple the data layer from Next.js API routes?

Currently, I am working on a project using Next.js with MongoDB. My setup involves using the MongoDB client directly in TypeScript. However, I have started thinking about the possibility of switching to a different database in the future and how that would ...

What is the best way to increase the size of an array and populate it with just one specific element in Types

If I want to create an array in Python, like [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], all I have to do is use [1] * 10. >>> [1] * 10 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] Is it possible to achieve the same result in TypeScript? ...

Can you explain the true meaning behind this specific type definition?

Since starting to dive into TypeScript recently, I came across an express server written in TS while browsing the Internet. However, I am struggling to comprehend the type definition of the 'middlewares' argument. Despite attempting to research i ...

Unable to loop through the Array

let Users = [ { name: 'John', id: '1', jp: 'USA' }, { name: 'Jane', id: '2', jp: 'Japan' }, ]; export function DisplayUsers(usersList) { return ( <div> {usersList?.map((user ...

Cell renderers in Angular do not receive the ICellRendererParams during initialization

I am currently working on creating a cell renderer in Angular that converts IP addresses into clickable SSH links. Below is the code for the renderer component: import { Component, OnInit, OnDestroy } from "@angular/core"; import { DomSanitizer, ...

Angular 5 dynamically updates its model after the completion of events

The issue at hand Currently, I am working with angular 5 and have created a component that consists of 3 controls. <ss-multiselect-dropdown id="type" formControlName="type" (ngModelChange)="onChange('type')"></ss-multiselect-dropdown&g ...

Configuring VS Code's "tasks.json" file to compile all .ts files can be done by following these steps

Apologies if this question has been asked before, but could someone please redirect me to the relevant thread if so. I am wondering if it is possible to set up VS Code's "tasks.json" to automatically compile all .ts files within a folder. Currently, I ...

What is the proper way to display the date and time 2021-11-14T18:30:00.000+00:00?

Here is my ts file code: mydate: Date = new Date('2021-11-14T18:30:00.000+00:00'); However, I want the date to be in this format:- 07-July-2022 If anyone can assist with achieving this format, it would be greatly appreciated. Thank you! ...

When you use array[index] in a Reduce function, the error message "Property 'value' is not defined in type 'A| B| C|D'" might be displayed

Recently, I delved deep into TypeScript and faced a challenge while utilizing Promise.allSettled. My objective is to concurrently fetch multiple weather data components (such as hourly forecast, daily forecast, air pollution, UV index, and current weather ...

Angular 6 - Only two columns in table sorting are functioning instead of sorting all columns as intended

I am attempting to utilize MatSort on a MatTable from Angular Material, but I'm facing an issue where only two columns in my MatTable can be sorted. My goal is to enable sorting for all columns, and I'm puzzled as to why it's not functioning ...

Exploring the benefits of using TypeScript with Angular2 for HTTP

I have a locally stored "region.json" file containing the following data: { "regionId":1, "region":"CAN" }, { "regionId":2, "region":"CEN" } Additionally, I have an "enviroment-app.component.ts" file structured as follows : import {Component, ...

I need assistance with the following issue: the type 'Observable<ArrayBuffer>' cannot be assigned to the type 'Observable<User[]>. Can anyone provide a solution for this problem?

Encountered an issue with the error message: Type 'Observable' cannot be assigned to type 'Observable<User[]>' while working on setting up Angular service.ts for implementing HTTP requests. ...

Focusing on the active element in Typescript

I am working on a section marked with the class 'concert-landing-synopsis' and I need to add a class to a different element when this section comes into focus during scrolling. Despite exploring various solutions, the focused variable always seem ...