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

Utilizing Angular's directive-based *ngIf syntax instead of passing a string parameter

Currently, I'm studying the article on reactive forms by PluralSight to brush up on my knowledge and I'm having trouble understanding the syntax provided below. <div *ngIf courseForm.get('courseName').valid && courseForm.get ...

Error message: The iOS system was unable to open the backing store due to a QuotaExceeded

Our Web-Application is quite large and is built on Angular with PWA capabilities enabled. Everything runs smoothly, including the offline mode functionality. We utilize PDFTron-Webviewer, which is cached by the Service-Worker to ensure availability in Off ...

Angular 2 Demonstrate Concealing and Revealing an Element

I am currently facing an issue with toggling the visibility of an element based on a boolean variable in Angular 2. Below is the code snippet for showing and hiding the div: <div *ngIf="edited==true" class="alert alert-success alert-dismissible fade i ...

Is it feasible to amalgamate the states of several child components into a single parent component state in NextJS/React?

Issue I am faced with the challenge of handling multiple Child components that can pass their state to a Parent component. Now, I am looking to render several Parent components within a Grandparent component and merge the states of each Parent into a sing ...

Converting a string to Time format using JavaScript

I am working with a time format of 2h 34m 22s which I need to parse as 02:34:22. Currently, I am achieving this using the following code: const splitterArray = '2h 34m 22s'.split(' '); let h = '00', m = '00', s = &a ...

Variables for Angular Material themes

My app has multiple theme files, and I select the theme during runtime. .client1-theme{ // @include angular-material-theme($client1-theme); @include all-component-colors($client1-theme); @include theme-color-grabber($client1-theme, $client1-a ...

Enhancing Readability of Public Static Member Variables in Typescript

In my node application, I am utilizing typescript and winston for logging purposes. One key element of my setup is the "Logger" class which consists of a "logger" member and an "init()" function. By exporting this class, I understand that the "logger" memb ...

Tips on how to create a loop without using a collection in Angular 2

I have a specific quantity and I need to repeat an action that many times. for (var _i = 0; _i < length; _i++) I am trying to replicate this logic in the html template. If I use ngFor, I would typically require a collection, but in this case I only ha ...

A guide on updating a MySQL table using a JSON object in Node.js

I have a JSON Object and need to UPDATE a mySQL table without listing all of the keys individually For an INSERT operation, I use the following code: var arrayValue = Object.keys(obj).map(function(key) { return String("'"+obj[key]+"'"); ...

Waiting for an async method in an Angular test: Tips and tricks

When working on an Angular application, I utilize various tools libraries and some of my code that involve: Declarations with asynchronous behavior The use of setInterval within which I do not want to wait. While attempting to implement solutions like fa ...

Exploring Angular 4: Leveraging mockRespond in Conjunction with RxJS Observables

I recently completed the development of an application that is functioning smoothly. Now, I am in the process of creating a test for it. The core functionality involves fetching items from an API backend: export class CatfactService { constructor(p ...

Creating a custom Higher Order Component to seamlessly connect react-relay and react-router using TypeScript

Hey there! So, my Frankenstein monster project has decided to go rogue and I'm running out of hair to pull out. Any help would be greatly appreciated. I've been working on setting up a simple app with React, React-Router, React-Relay, and Typesc ...

Creating Meta tags for Dynamic Routes in a Nuxt 3 Build

I recently encountered an issue when trying to implement dynamic OpenGraph meta tags on a dynamically generated route in Nuxt 3 (and Vue 3). I attempted to set the meta tags dynamically using Javascript, as it was the only dynamic option supported by Nuxt ...

Creating a Higher Order Component (HOC) for your Next.js page

Upon running the following code, I encountered an error message Error: The default export is not a React Component in page: "/" pages/index.tsx import React, { useState, useRef } from "react"; import type { NextPage } from "next&q ...

How can you line up various form elements, like pickers, in a row using Material UI?

As someone new to material ui, I haven't come across a solution for my specific issue yet. While there are similar questions, none seem to address the problem of aligning different form field types. My observation is that the material ui date picker ...

Testing the Angular router-outlet using Jasmine

When testing web-app navigation using Jasmine spec with RouterTestingModule, I am facing challenges with nested fixture.whenStable().then(() => {}). For instance: After clicking on multiple links where the router-outlet changes the displayed component ...

When iterating through a list of strings using ngFor, I am unable to directly access or manipulate the individual items

Within my model, I have a list of strings. <span *ngFor="let item of model; let i = index"> <input #inputField type="text" [name]="name + '_' + i" [(ngModel)]="item" /> </span> The code snippet ab ...

Is there a way to simulate AWS Service Comprehend using Sinon and aws-sdk-mock?

As a newcomer to Typescript mocking, I am trying to figure out how to properly mock AWS.Comprehend in my unit tests. Below is the code snippet where I am utilizing the AWS Service Comprehend. const comprehend = new AWS.Comprehend(); export const handler ...

The TypeScript compiler throws an error when encountering nulls in conjunction with the isNull function

Whenever I set strictNullChecks: true in tsconfig.json and utilize the isNull function for null checks, the compiler throws the error TS2531: Object is possibly 'null'. Interestingly, isNull doesn't trigger any errors in VsCode, however, the ...

The error message "Type 'Dispatch<SetStateAction<undefined>>' cannot be assigned to type 'Dispatch<SetStateAction<MyType | undefined>>'" appears in the code

I'm encountering challenges while creating a wrapper for useState() due to an unfamiliar error: Type 'Dispatch<SetStateAction>' cannot be assigned to type 'Dispatch<SetStateAction<VerifiedPurchase | undefined>>' ...