1

I'm pretty new to Angular and my question may seem basic but some guidance would be appreciated. I am currently writing an app to teach myself some real development skills. In my app I have an Angular Component that imports a service that I wrote that provides data.

This is my component

@Component({
  selector: 'music-instrument-list',
  templateUrl: './instrument-report.component.html',
  styleUrls: ['./instrument-report.component.css']
})
export class InstrumentReportComponent implements OnInit, OnDestroy {
    
    constructor(public apiService: ApiService) {}
    public availableInstruments: any[];

    ngOnInit() {
        this.apiService.getInstruments().subscribe((result) => {
            this.availableInstruments = result;
        });
    }

    ngOnDestroy() {
    // how do I unsubscribe?
    }
}

This is pretty simple but should I try to add this.apiService.getInstruments.unsubscribe() to the ngOnDestroy block I get the error that Property 'unsubscribe' does not exist on type => Observable'. I even considered add .unsubscribe() after the .subscribe() like chaining but this just makes my page hang. I get no error either. Can someone please tell me how to best unsubscribe? Do I need to assign the api call to a variable and then use .unsubscribe() on the varable name in the ngOnDestroy block

raaaay
  • 496
  • 7
  • 14
NewToAngular
  • 975
  • 2
  • 13
  • 23

4 Answers4

5

To avoide memory leaks you can unsubscribe from Observable through Subscription. For example:

    subscription: Subscription;

    ngOnInit() {
        this.subscription = this.apiService.getInstruments().subscribe((result) => {
            this.availableInstruments = result;
        });
    }

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

or using async pipe:

TypeScript:

    instruments$;

    ngOnInit() {
        this.instruments$= this.apiService.getInstruments().subscribe((result) => {
            this.availableInstruments = result;
        });
    }

HTML:

    <li *ngFor="let instr of instruments$ | async">
        {{ instr | json }} 
    </li>
raaaay
  • 496
  • 7
  • 14
StepUp
  • 36,391
  • 15
  • 88
  • 148
2
@Component({
  selector: 'music-instrument-list',
  templateUrl: './instrument-report.component.html',
  styleUrls: ['./instrument-report.component.css'],
})
export class InstrumentReportComponent implements OnInit, OnDestroy {
  subscription: Subscription;
  constructor(public apiService: ApiService) {}
  public availableInstruments: any[];

  ngOnInit() {
    this.subscription = this.apiService.getInstruments().subscribe((result) => {
      this.availableInstruments = result;
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Bharat Chauhan
  • 3,204
  • 5
  • 39
  • 52
0

You shouldn't unsubscribe from observables that complete automatically (e.g Http, calls). But it's necessary to unsubscribe from infinite observables like Observable.timer(). unsubscribe from Angular HTTP calls

as for unsubscribing in general, it is a duplicate question and it is answered here How to unsubscribe for an observable

Basel Issmail
  • 3,847
  • 7
  • 20
  • 36
0

The newest and the cleaner way to handle an observer in angular is to use an async pipe in template component, its delegate the subscription and the destruction of the observable to the container framework. You can find more detailed example here(angular doc) : https://angular.io/api/common/AsyncPipe

AYOUB_MA
  • 48
  • 5