Cancel local requests on component destroy

Viewed 515

Consider you have some component e.g. autocomplete that sends GET request to server:

...
someObject = create();
vm.search = someFactory.getHttp(params).then(result => {
  someObjet.prop = result;
});

vm.$onDestroy = () => {
  someObject = null;
}

If component is destroyed while request is pending, callback will throw js error. I know that in this concrete example I can solve this using simple If, however quite obvious that it is better to canel this request:

var canceler = $q.defer();
vm.search = someFactory.getHttp(params, canceler)...

vm.$onDestroy = () => {
      canceler.resolve();
      someObject = null;
}

This works perfectly, but having such code in each component seems weird. I would like to have something like:

vm.search = someFactory.getHttp(params, $scope.destroyPromise)

But such thing does not seem to exist...

Question: Is there any easy way to cancel requests on component destroy? both in Angularjs or in Angular

2 Answers

One thing I've done in Angular is use RXjs for requests, using subscriptions, and adding those subscriptions to an array that we iterate over and cancel on destroy, like this:

import { Component, OnInit, OnDestroy} from "@angular/core";
import { ActivatedRoute }              from "@angular/router";

export class AppComponent implements OnInit, OnDestroy {
    private subscriptions = [];

    constructor(private route AppRoute) {}

    ngOnInit() {
        this.subscriptions.push(this.route.data.subscribe());
    }

    ngOnDestroy() {
        for (let subscription of this.subscriptions) {
            subscription.unsubscribe();
        }
    }
}

Why not assign the created object to an object that doesn't get destroyed? This way your behaviour is maintained and the you can do a simple check to prevent any errors.

...
var baseObj = {};
baseObj.someObject = create();
vm.search = someFactory.getHttp(params).then(result => {
    if (baseObj.someObject != null) {
        baseObj.someObjet.prop = result;
    }
});

vm.$onDestroy = () => {
  baseObj.someObject = null;
}
Related