"this" is undefined in ngOnDestroy

736 views Asked by At

I'm trying to unsubscribe in ngOnDestroy method of the component, but instance of this is already undefined.

import { Component, OnDestroy, OnInit } from '@angular/core';
import { SomeService} from 'somewhere';
import { Subscription } from 'rxjs';

@Component({
  ...
})
export class SomeComponent implements OnInit, OnDestroy {
  subscription: Subscription | undefined;

  constructor(
    private someService: SomeService
  ) {}

  ngOnInit(): void {
    this.subscription = new Subscription();
  }

  ngOnDestroy(): void {
    console.log(this);  // **log shows that 'this' is 'undefined'**

    if (this?.subscription) 
      this.subscription.unsubscribe();
  }
   
  onNextClick() {
    this.subscription = this.someService
      .getSomething()
      .subscribe({
        next: (res) => {
          console.log('HTTP response', res);
        },
        error: (err: unknown) => {
          console.log('HTTP Error', err);
        },
        complete: () => console.log('HTTP request completed.'),
      });
  }
}

getSomethig method of the service returns an Observable, that I subscribe to. I want to close that subscription in OnDestroy event, but by then this object is already undefined and subscription does not exist anymore.

Lots of examples online show this way of unsubscribing, however the subscription is usually done in OnInint event. In my case, the event happens after a button click.

How should I unsubscribe in this case?

1

There are 1 answers

3
anis On

try this way with TakeUntil:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { SomeService} from 'somewhere';
import { Subscription } from 'rxjs';

@Component({
  ...
})
export class SomeComponent implements OnInit, OnDestroy {
   destroy$: Subject<boolean> = new Subject<boolean>();
  constructor(
    private someService: SomeService
  ) {}

  ngOnInit(): void {
  }

  ngOnDestroy(): void {
   this.destroy$.next(true);
   this.destroy$.unsubscribe();
  }
   
  onNextClick() {
     this.someService
      .getSomething().pipe(
      takeUntil(this.destroy$)
    ).subscribe({
        next: (res) => {
          console.log('HTTP response', res);
        },
        error: (err: unknown) => {
          console.log('HTTP Error', err);
        },
        complete: () => console.log('HTTP request completed.'),
      });
  }
}