Angular 9 observable unsubscribe using @ngneat/until-destroy npm package
Asked Answered
G

4

12

I am using @ngneat/until-destroy this npm package to auto unsubscribe observables. I have used checkProperties: true to auto unsubscribe observables.

But, I am not getting how to test it. Whether observable is getting unsubscribed or not?

My question is simple. Does this code work or do I have to use pipe like this before subscription

.pipe(untilDestroyed(this))

Thank you in advance

import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';

@UntilDestroy({ checkProperties: true })

@Component({
  selector: 'app-view-all-purchase',
  templateUrl: './view-all-purchase.component.html',
  styleUrls: ['./view-all-purchase.component.scss']
})

export class ViewAllPurchaseComponent implements OnInit, OnDestroy  {

  
  ngOnInit() {

 this.subscibe1 =  this.vendorService.five_vendors().subscribe(data => {
    if(data){
      console.log(data)
       this.vendor_list = data
    }})

}

ngOnDestroy() {
 
 }
 
}
Gernhard answered 4/5, 2020 at 13:48 Comment(5)
Why do you want to unsubscribe from the observable? When do you want to unsubscribe from it?Diallage
Actually, I have gone through some articles stating memory leaks due to observables. So it is important to unsubscribe observable when component is destroyed i.e. ngOndestroy() methodGernhard
That is true for some observables, mostly custom ones. If you don't unsubscribe those during ngOnDestroy(), they'll stay. The ones that make http requests using HttpClient do not need to be unsubscribed as they are automatically unsubscribed when the request has finished.Diallage
Okay thanks. Have you used until destroy npm package? Does checkproperties : true works or I have to use pipe(untildestroyed(this)) .Gernhard
@Diallage please don't perpetuate wrong information, ALL observables need to be unsubscribed, even the ones from the HttpClient: github.com/angular/angular/issues/46542Avelar
O
3

To check if your observable is unsubscribed, you can add a console.log to your subscription (you already have that but put if outside of the if(data){} ) and then change the observable in another component after the ViewAllPurchaseComponent should have been destroyed. If you get a console.log from the ViewAllPurchaseComponent when changing the observable in another component, it was not unsubscribed.

I don't know about the '@ngneat/until-destroy', I usually use

ngOnDestroy(){ 
   this.subscibe1.unsubscribe();
}

Hope that helps!

Outdate answered 4/5, 2020 at 14:11 Comment(6)
I know this approach, but I am not looking for it. I want to auto unsubscribe observables using above npm package.Gernhard
Ok, but now you can check if the observable is unsubscribed with the console.log.Outdate
I'm also looking for the same. They example that they gave in github repo works.Luannaluanne
Even without using the package related to OP's question, unsubscribing manually is prone to mistakes and oversight. You should use rxjs takeUntil learnrxjs.io/learn-rxjs/operators/filtering/takeuntilApparently
@Apparently takeUntil is unnecessary if you use the pipe from this package, that's what it's all about, replacing takeUntil, take(1), and other similar pipes.Avelar
That's precisely the point of my comment : should anyone refuse to use until-destroyed for whatever reason, the solution of unsubscribing manually is still to avoid. I agree that package is imho the best solution, but here we're commenting on a answer which displays an out-of-date alternative.Apparently
E
2

I usually use untilDestroyed this way:

this.subscibe1 =  this.vendorService.five_vendors()
**.pipe(untilDestroyed(this))**
.subscribe(data => {
if(data){
  console.log(data)
   this.vendor_list = data
}})
Emalee answered 3/9, 2021 at 9:32 Comment(0)
U
1

I use it like this

import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
    
@UntilDestroy()
@Component({
  selector: 'app-view-all-purchase',
  templateUrl: './view-all-purchase.component.html',
  styleUrls: ['./view-all-purchase.component.scss']
})

export class ViewAllPurchaseComponent implements OnInit {
  ngOnInit() {
    this.subscibe1 = this.vendorService.five_vendors().pipe(
      untilDestroyed(this)
    ).subscribe(data => {
      if (data) {
        console.log(data)
        this.vendor_list = data
      }
    })
  }
}
Ulterior answered 9/6, 2023 at 15:57 Comment(0)
E
0

The best pattern is to use the async pipe

export class ViewAllPurchaseComponent {
  vendor_list$ = this.vendorService.five_vendors();

  constructor(private vendorService: VendorService) {}
}

and in the template use

<ng-container *ngIf="vendor_list$ | async as vendor_list">
  Vendor list is available here {{ vendor_list | json }}
</ng-container>
Erne answered 13/2, 2023 at 8:16 Comment(1)
This is irrelevant. The user may not want to unsubscribe in the template, in which case the async pipe is useless.Avelar

© 2022 - 2024 — McMap. All rights reserved.