0

I have a code that is leaking and I need to know why or how to unsubscibe correcly . since even when I added an array that is all objects subscibed are being deleted it still leaks

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  postId;
  
  callOmni = () => of(this.pollOmni()).pipe();
  display = response => {};
  poll = of({}).pipe(
  mergeMap(_ => this.callOmni()),
  tap(this.display),
  delay(10),
  repeat()
);

  constructor(private http: HttpClient) { } 
  pollOmni() {      
    // Simple POST request with a JSON body and response type <any>
    this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
      data => {
        this.postId = data;
        console.log(this.postId);
        }),
        error => {
          console.log('oops', error)
        }
     
   
  }

  ngOnInit() {      
    // Simple POST request with a JSON body and response type <any>
   
    this.poll.subscribe();
  }

}
mark
  • 13
  • 4
  • Does this answer your question? [Angular/RxJS When should I unsubscribe from \`Subscription\`](https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-unsubscribe-from-subscription) – kvetis Jul 03 '23 at 12:07

3 Answers3

1

In your code, it seems that you have a subscription inside the pollOmni() method, which is called multiple times. This can lead to multiple active subscriptions that are not unsubscribed, causing a memory leak.

To fix this, you need to make sure that you unsubscribe from the subscription when it's no longer needed. One way to achieve this is by storing the subscription in a variable and unsubscribing from it when necessary.

Here's an updated version of your code that implements the necessary changes:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of, Subject } from 'rxjs';
import { delay, tap, mergeMap, repeat, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  postId;
  private ngUnsubscribe = new Subject<void>(); // Subject for unsubscribing

  constructor(private http: HttpClient) { }

  callOmni = () => of(this.pollOmni()).pipe();

  display = response => {
    // Display logic here
  };

  poll = of({}).pipe(
    mergeMap(_ => this.callOmni()),
    tap(this.display),
    delay(10),
    repeat(),
    takeUntil(this.ngUnsubscribe) // Unsubscribe when ngUnsubscribe emits
  );

  pollOmni() {
    return this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' });
  }

  ngOnInit() {
    this.poll.subscribe();
  }

  ngOnDestroy() {
    this.ngUnsubscribe.next(); // Emit value to unsubscribe from ongoing subscriptions
    this.ngUnsubscribe.complete(); // Complete the subject
  }
}
  • thanks so much!!!! it seems not to leak . I have one issue I wish to print the response or cast it to an object that can show the json .display = response => { console.log(response); }; it shows me the observable instead . is there a way to do this ? – mark Jul 03 '23 at 12:33
  • MauriceMoss - Your seven answers this month appear likely to have been entirely or partially written by AI (e.g., ChatGPT). Please be aware that [posting AI-generated content is not allowed here](//meta.stackoverflow.com/q/421831). If you used an AI tool to assist with any answer, I would encourage you to delete it. We do hope you'll stick around and be a valuable part of our community by posting *your own* quality content. Thanks! – NotTheDr01ds Jul 12 '23 at 16:09
  • **Readers should review this answer carefully and critically, as AI-generated information often contains fundamental errors and misinformation.** If you observe quality issues and/or have reason to believe that this answer was generated by AI, please leave feedback accordingly. – NotTheDr01ds Jul 12 '23 at 16:09
0

Something like that:

export class AppComponent implements OnInit, OnDestroy {    
  ...

  ngOnDestroy(): void {
    this.poll.unsubscribe();
  }
}
Evgeny Gurevich
  • 475
  • 3
  • 5
0

In your code implement the OnDestroy Life cycle hook in angular and unsubsribe it in ngOnDestroy mehthod like below:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { delay, tap, mergeMap, repeat } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {

  postId;
  private unsubscribe = new Subject<void>();
  callOmni = () => of(this.pollOmni()).pipe();
  display = response => {};
  poll = of({}).pipe(
  mergeMap(_ => this.callOmni()),
  tap(this.display),
  delay(10),
  repeat(),
  takeUntil(this.unsubscribe)
);

  constructor(private http: HttpClient) { } 
  pollOmni() {      
    
    this.http.post<any>('http://127.0.0.1:8084/api', { call: 'getinfo' }).subscribe(
      data => {
        this.postId = data;
        console.log(this.postId);
        }),
        error => {
          console.log('oops', error)
        }
     
   
  }

  ngOnInit() {      
    this.poll.subscribe();
  }

ngOnDestroy(): void {
    this.unsubscribe.next(); 
   this.unsubscribe.complete();
  }
}

If the above does not works for you I suggest to implement the template mechanism in Angular Angular Async Pipe Please refer the below sample on usage of pipes in Angular. Please note that Below is sample implementaions:

  @Component({
      selector: 'app-stock',
      template: `
        <div *ngIf="stocks$ | async as stocks">
          <ul>
            <li *ngFor="let stock of stocks">
              {{ stock.symbol }}
            </li>
          </ul>
        </div>
      `,
      styleUrls: ['./stock.component.scss'],
    })
    export class StockComponent implements OnInit {
      stocks$: Observable<Stock[]> = this.stockService.getStocks();
    
      constructor(private stockService: StockService) {}
    
      ngOnInit(): void {}
    }
Selaka Nanayakkara
  • 3,296
  • 1
  • 22
  • 42