-1

I have a report component which have Behavior Subject subscription and it pull data from web api after .next call. When I am move to another page after report page, report component still alive and keeps sending calls to webApi.

How to destroy components after navigate to another or unsubscribe Behavior Subjects. More details. I have few report components, it renders different type of reports. One of the component is below

@destroyAllSubscribers()
    export class StandardReportComponent implements OnInit {

    public subscriptions: Subscription[] = [];
    reportData = [];
    showReport=false;
    constructor(private reportService: ReportService)
    {

        this.subscriptions.push(this.reportService.chartType.subscribe(chartType => {

        if (this.currentChart != ReportChartType.None){

         this.showReport=false;  //Used in *ngIf to show report HTML template
            this.reportService.getReportData().subscribe(result=>{
        this.reportData=result; 
        this.showReport=true; //Used in *ngIf to show report HTML template


    }

    }

    }
    }

I have destroy subscriber decorator which gets executed when component destroys,

Code:

export function destroyAllSubscribers() {
    return (targetComponent: any) => {
      targetComponent.prototype.ngOnDestroy = ngOnDestroyDecorator();

      function ngOnDestroyDecorator() {
        return function () {
          if (this.subscriptions != undefined)
          {
            this.subscriptions.forEach(subscription => {
              if (subscription instanceof Subscriber) {
                subscription.unsubscribe();
              };
            });
          }
        };
      }
    };
}

It should unsubscribe; however all subscription gets executed after navigate to other page as well.

dilipkumar katre
  • 128
  • 1
  • 12

4 Answers4

0

You can unsubscribe the Behavior Subjects at page destroy using OnDestroy life cycle hook like this

this.sub_State = this.stateService.showStateBehaviorSubject.subscribe((state: boolean) => {
            this.showState = state;
        });
ngOnDestroy() {
        this.sub_State .unsubscribe();
    }
Hana Wujira
  • 870
  • 7
  • 17
0

Create a Subject property and take the subscription until it's destroyed in ngDestroy

class MyComponent {
  destroyed$ = new Subject();

  ngOnDestroy() {
    this.destroyed$.next();
  }

  myMethod() {
   this.apiHelper.get('some/url')
     .pipe( takeUntil(this.destroyed$) )
     .subscribe(()=> {
       // do things
     });
  }
}
Baruch
  • 2,381
  • 1
  • 17
  • 29
0

Simply use async pipe to display the data on the template without having to subscribe to the BehaviorSubject.

this.data$ = this.reportService.behaviourSubjectObj

In your template:

{{ data$ | async | json }}
SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
  • This won't close the subscription. It also limits what you can do, for example, if you have to map the data or store a property in your component, this won't allow you to do either. – Baruch Sep 19 '18 at 06:38
  • Nobody's stopping him from calling map on the `behaviorSubjectObj` in the Component. And you sure about the first point? – SiddAjmera Sep 19 '18 at 06:42
  • I guess you're right, forgot about operators for a second. My bad. – Baruch Sep 19 '18 at 12:53
0

Use ComphonentRef , if you want to destroy it from parent then follow the below code

@ViewChild(ChildComponent, { read: ComponentRef }) childComponentRef: ComponentRef;

the call

this.childComponentRef.destroy()

function in an event of parent .

refer this link

Sunny Goel
  • 1,982
  • 2
  • 15
  • 21