Angular HttpClient Observables failing to auto-unsubscribe

When I make an http call and subscribe to it, I notice that even after closing the component, the subscription is not destroyed and continues to run once. Shouldn't the http subscriptions be automatically removed when a component is destroyed?

Below is the method that is being called:

getCubes() {
    this.loading_cubes = true;
    this.urlService.getCubes().subscribe({
      next:(data:any) => {
        if (data.success) {
          this.cubesDataArray = data.data[0].response;
        } else {
          Swal.fire(data.status_message);
          console.log(data.error_message);
        }
        this.loading_cubes = false;
      },
      error:(err:any) => {
        console.log(err);
        Swal.fire('Opps an error occured');
        this.loading_cubes = false;
      }
    });
  }

And here's the service function that returns the http observable:

 getCubes() {
    return this.http.get(this.serviceURL + '/cubes', this.options);
  }

This issue is not isolated to just one case—it happens with every request I make. The pop-ups keep appearing even after I've closed the component.

Could it possibly be related to a setting in the tsconfig.json file?

Answer №1

To properly clean up your subscription, make sure to utilize the onDestroy method:


class MyComponent {
    mySubscription = null
    ...

    loadData() {
        this.mySubscription = this.dataService.getData().subscribe({
            ...
        });
    }
    ngOnDestroy() {
        this.mySubscription.unsubscribe();
    }   
}

Answer №2

Matthew provided you with a comprehensive answer already. However, there are alternative options to consider in addition to his explanation.

  1. If you want RxJS to only retrieve one result, you can use the following code:

    this.urlService.getCubes().pipe(take(1)).subscribe({ ... });

The pipe(take(1)) method ensures that only one result is obtained from the observable.

  1. Another approach is to convert the observable to a promise using the firstValueFrom function from RxJS. This would look like:

    firstValueFrom(this.urlService.getCubes()).then({ ... });

You might be wondering why HttpClient behaves in this particular way. Allow me to provide some insight into it.

Methods such as get, put, post, delete, etc. of HttpClient return what is known as 'cold observables.' These observables are not executed unless there is a consumer at the end. If you do not subscribe to them, no request will be made.

This feature also allows you to create a 'paused request' and make multiple calls to it - for example, with multiple subscriptions.

Why would you need this? Let's take a look at this code snippet:

this.urlService.getCubes()
  .pipe(retry(3))
  .subscribe({
    ...
  });

In this scenario, I am utilizing the retry operator which catches errors and retries the request. It will attempt the request three times before giving up. If the first or second attempt is successful, it will not retry again.

This behavior is facilitated by HttpClient returning 'cold observables,' which necessitates the implementation of these solutions.

Additionally, this setup allows for the utilization of a 'cancelation token' mechanism, but that is a discussion for another time.

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

Incorporating a minute interval in Angular Material's time picker feature

In my Angular 15 project, I am working with this material component. <mat-form-field appearance="outline"> <mat-label>{{'DOCTOR_AREA.START_TIME' | translate}} </mat-label> ...

The issue with the meta tag not updating in the view source seems to be related to

I'm facing an issue with updating the meta tag in Angular 6 and Angular Universal. When I make changes, they only reflect in the inspect element and not in the view page source, where it remains the same as the homepage. Homepage.ts . . . import { S ...

Troubleshooting Angular: Investigating why a component is failing to redirect to a different route

I am currently implementing a redirect to a new route upon logging in using the following code: this.router.navigate(['/firstPage']); Oddly enough, when my application is initially loaded, this redirection does not occur automatically after logi ...

Getting an error in React when using Typescript with a functional component? The issue might be that you are trying to assign a type 'boolean' to a type 'ReactElement<any, any>'

Recently, I set up a project that utilizes TypeScript in conjunction with React. As part of the project, I created a Layout component that relies on the children prop. Below is the current code snippet: import React from 'react'; type LayoutProp ...

Is it possible to extract a single element from an array that is stored as a standard Observable?

Currently, I am using a regular observable instead of an observableArray. This observable keeps an array of elements which is defined as follows: public arrayOfItems: IArrayItem[]; public arrayOfItems$: BehaviorSubject<IArrayItem[]> = new BehaviorSu ...

'map' is not defined in the current Typescript scope

As a newcomer to AngularJS, I am encountering an error when attempting to send a post request to my localhost server. The error message states [ts] cannot find name 'map' and cannot find name 'subscribe'. Any assistance in understanding ...

MatDialog displaying no content

I found this tutorial on how to implement a simple dialog. The issue I'm facing is that the dialog appears empty with no errors in the console. Even after making changes to my dialog.component.html or dress-form.ts, nothing seems to reflect in the o ...

What is the best way to access a value from a settings.json file in an Angular .ts file?

I am working on implementing debounceTime to allow the user to finish typing before suggestions are generated. I want to give the user the ability to customize how much time is given before suggestions appear. To achieve this, I have added a configuration ...

There are occasional instances of phone skipping functions within a loop in Ionic 4

My POS app is designed to work with a thermal printer using the Bluetooth Serial plugin. The issue I am facing is that when the order is too long, I divide the invoice into 300-bit chunks. This process works flawlessly on my phone every time, but when I at ...

Oops! An unhandled promise error occurred when trying to fetch a URL with a status of 0. The response received has a status code of

I keep encountering an error whenever I try to hit a post request URL: Error: Uncaught (in promise): Response with status: 0 for URL: null at c (http://localhost:8100/build/polyfills.js:3:19752) at c (http://localhost:8100/build/polyfills.js:3:1 ...

I am having trouble retrieving child interface data from API using Angular. Can someone help me figure out what I am doing

Recently started with Angular 7 and could use some guidance. I have a JSON stream that appears as follows: { "Id": 25, "Name": "XYZ Corp", "CompanyAddresses": [ { "Id": 39, "CompanyId": 25, "Address1 ...

The Angular 2 HTTP GET method is throwing a type 3 error when trying to access the

i am encountering an issue while trying to retrieve a response from my asp.core api within Angular 2. The error message received is: "Object { _body: error, status: 0, ok: false, statusText: "", headers: {…}, type: 3, url: null }" Component: import { C ...

Display permanent components in Angular while nesting components

Currently, I am incorporating the admin module within the main app module in my project Within the admin module, there are 2 components - register and login. Additionally, the admin module has its own routing module. Now, my task is to create a navbar sp ...

Adding a new row to an existing formArray in Angular: A step-by-step guide

Can someone help me figure out how to add a new row and remove a row on this form? editCity() { this.form = this.fo'',))), recepieType: } createForm() { this.form = this.formBuilder.group({ }); } I am looking to implement ...

In Angular, the text box in a dropdown will be enabled or disabled based on the chosen selection values

I have written code for a dropdown with two values - Enabled and Disabled. Depending on the selection, I want the textbox to be enabled or disabled. Can someone help me with how to achieve this? import { Component, OnInit } from '@angular/core'; ...

Tips for passing a usestate via props using interfaces in TypeScript and react?

I am currently working on implementing a light/dark theme and I have 2 components involved in the process. The first component code snippet is shown below, where I have successfully implemented a boolean to toggle between styles: export interface Props ...

Using TypeORM: Incorporating sub queries with queryBuilder

I need assistance with converting the following PostgresSQL query into TypeORM's queryBuilder syntax: SELECT symbol, created_at FROM ( SELECT DISTINCT ON (symbol) symbol, created_at FROM update_history WHERE exchange = 'TEST' AND data_ ...

Tips for integrating the react-financial-charts library into your React and JavaScript project

While exploring the react-financial-charts library, I discovered that it is written in TypeScript (TS). Despite my lack of expertise in TypeScript, I am interested in using this library in my React+JS project due to its active contributions. However, I hav ...

Ignoring lines in code coverage using Istanbul is not an option that can be overlooked

I have come across many examples of code that utilize /* istanbul ignore next / / istanbul ignore start / / istanbul ignore end */ There are certain parts in the codebase that cannot be covered by unit tests, and it would be beneficial to employ these Is ...

What is the reason behind the varying display of values?

When trying to set a value using the input tag, I encountered an issue. For example, if I type 1000.0009 into the input text, the valid value should be 1000.0001. However, the value displayed in the input tag is incorrect, while the value outside the tag i ...