Ensuring Angular 7 Waits for Http Network Call Completion Prior to Initiating the Next One

In my data service, I have a mechanism that initiates http calls periodically and on demand by other services. The challenge is that these services operate asynchronously, creating the possibility of overlapping http calls where a new call is made before the previous one completes.

I am exploring the use of rxjs to determine if there is an ongoing call when a new http call needs to be made.

Data Service:

constructor(private http: HttpClient){}

// If a request is made while another is in progress, wait for it to finish before triggering the next call
public request(method, url, options): Observable<any>{
    return this.http.request(method, url, options);
}

Service A:

public syncA(){
    setTimeout(() => {
       this.dataService.request('GET', 'someUrl', someOptions).subscribe((response) => {
        console.log('periodic call returns ', response});
    }, 45000);
}

Service B:

public doB(): Observable<any>{
 return this.dataService.request('GET', 'someUrl', someOptions)
}

The potential issue arises when service B calls doB while syncA has initiated a request that is still pending.

Answer №1

If you want to implement this in a rxjs manner, consider using the concatMapTo function.

An interesting demonstration can be found in this StackBlitz example.

const fakeRequest = of('Network request complete').pipe(delay(3000));
//wait for first to complete before next is subscribed
const example = sampleInterval.pipe(concatMapTo(fakeRequest));
//result
//output: Network request complete...3s...Network request complete'
const subscribe = example.subscribe(val => console.log(val));

Answer №2

If you want to handle loading in an efficient way, consider using a BehaviorSubject to manage the loading state and only proceed with the request when it's false. Here's an example implementation:

private loading = new BehaviorSubject<boolean>(false);

constructor(private http: HttpClient){}

// Wait for previous requests to complete before triggering the next one
public request(method, url, options): Observable<any>{
    return this.loading.pipe(
        filter(value => value === false),
        take(1),
        tap(() => this.loading.next(true)),
        mergeMap(() => this.http.request(method, url, options)),
        tap(() => this.loading.next(false))
    );
}

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

I am encountering an issue where the JSON data is not being properly loaded into my Angular 8 application

Here is the structure of my JSON data: { "content": [ { "id": 1, "name": "test name", "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cbbfaeb8bf8bbfaeb8bfe5a8a4a6"&g ...

Unable to use URL navigation with webpack in angular2 production

I have been working on an angular2 application that utilizes angular2 route. The webpack configuration for both the development and production versions are in line with the guidelines outlined in this tutorial. When I run the application using the develop ...

"Exploring the methods to retrieve Firebase authentication error details and outputting the console log message along with

When I encounter an error in Firebase authentication, I want to display it in the console log. However, nothing is being logged and the catch block is not even getting executed. I am unsure about why this is happening and how to retrieve the error code and ...

Issue with Node.js: Interface array not correctly populated

Having trouble reading and storing 4 files into an array of objects. The objects in the array all end up being the same as the last object. Looking for guidance on what I did wrong. Here is the simplified code snippet: import * as fs from "fs"; interfac ...

Retrieve the state using a custom hook in a different location

My custom hook is designed to retrieve and parse a JSON object from the DOM like this: export const useConfig = () => { const [config, setConfig] = useState<Config>(); useEffect(() => { if (document) { const config ...

Challenge with Angular dependencies: Transitioning from Windows to Linux

I'm facing a challenge with hosting an Angular application on Linux for a client. The application runs smoothly on Windows where the customer develops it. My NodeJS version is 19. Upon running npm install, I encountered this error message: npm notice ...

What is the best way to transform this string into a Luxon Datetime object using Typescript?

Here is a snippet of Javascript/Typescript code that I have for converting a string into a Luxon DateTime: import { DateTime } from 'luxon'; const x = '2023-10-27T01:00:57.830+00:00' const y = DateTime.fromFormat(x, 'yyyy-MM-dd ...

Exploring NPM and package.json: Adding a dependency containing "@" symbol in the name

Recently, I've been attempting to update my project with the latest Angular 2 RC version. The module name in NPM has now changed from angular2 to @angular/core. However, when I add it to my package.json, it seems to be trying to install a module named ...

Implementing shared element route transitions using framer-motion and NextJS (written in typescript)

I'm having trouble implementing animated routing using the <AnimateSharedLayout /> component from framer-motion. What I'm trying to achieve in the code below is to show a list of images and, upon clicking on them, navigate to /images/[image ...

The Ion-item-option button requires two clicks to activate

Within my ion-list, I have sliding items that are dynamically created using a for loop. Interestingly, when clicking on an item to navigate to another page, everything works fine. However, upon sliding an item, a button is revealed but it requires two clic ...

Transform a string into a boolean value for a checkbox

When using v-model to show checked or unchecked checkboxes, the following code is being utilized: <template v-for="(item, index) in myFields"> <v-checkbox v-model="myArray[item.code]" :label="item.name" ...

What is the best way to adjust the font size for my entire website using either bootstrap or CSS?

Encountering a strange issue here. While working on an Angular 8 MVC C# application, everything is running smoothly with the default browser fonts. However, when integrating a department Nuget package for headers, footers, and menus, all fonts across the w ...

How to dynamically update Angular6 query parameters without changing routes

Lately, the project I've been focused on involves managing numerous lists with search, sort, and pagination functionalities. I have successfully implemented data fetching from an API based on these criteria. Recently, a new requirement emerged - the ...

Can you explain the significance of <: in TypeScript?

Query: Can you clarify the significance of the char at <:? Where is the official documentation on this available? How can I comprehend it better? Resource Link. ...

Troubleshooting challenges with Angular login and HTTP interceptor functionality during runtime

I have implemented a login function that utilizes this code snippet: login() { this.authService.login(this.ngForm.value).subscribe({ next: (response) => { const loginData = response; this.user = loginData.user; this.authService.setToken(loginD ...

Creating fixtures with Playwright is a simple process that can greatly enhance

I have a requirement to set up fixtures where the first fixture is always available (acting as a base class) and the second fixture will vary in different test files (like a derived class). I've implemented the following code which seems to be working ...

Encountering issues with Google authentication functionality while using AngularFire2

Currently in the process of setting up Google Authentication with Firebase and AngularFire2. The setup seems to be partially functional, however, there are some unusual behaviors that I am encountering. Upon the initial loading of the app, the Login button ...

Adjust the background color of a list item using Typescript

At the top of my page, there's a question followed by a list of answers and the option to add new ones. You can see an example in the image below. https://i.stack.imgur.com/NPVh7.jpg The format for each answer is "(username)'s response: at this ...

Closing a popover in NG-bootstrap from its container

I'm working on a container component named file-container, which includes an ngbPopover button. Inside the popover, there is another component used for selecting a file to upload. <button type="button" class="btn btn-secondary popover-btn ...

Simulate error handling in NgRX createEffect function

I am currently in the process of creating a test scenario for a dispatch event. Below is the code snippet I am working on: @Injectable() export class AuthEffects { signIn$ = createEffect(() => this.actions$.pipe( ofType(AuthActions.signIn), ...