angular4 async template binding don't unsubscribe with zip

Viewed 703

I have an async template binding such as:

[binding]="polling$ | async"

In my code, polling$ is derived from a bunch of initial promise like observables combined into a single zipObs$ for convenience:

let a$: AsyncSubject<any>, b$: AsyncSubject<any>;
// ... init a$ and b$
let zipObs$ = Observable.zip(a$, b$);

Up to this point everything is fine. That's what the polling logic looks like (not so sure about this..):

function poll() {
    let current$ = getSomeObservable();
    let next$ = current.delay(5000).concatMap(poll);
    return Observable.merge(current$, next$);
}
this.polling$ = zipObs$.concatMap(poll);

It kind of works as expected, the only problem being that the polling doesn't stop when the component is destroyed, i.e angular doesn't seem able to automatically unsubscribe all the observables. I managed to work around that issue by tracking the Observable.zip subscription and manually unsubscribing on destroy:

private _sub: Subscripton;
// ... constructor or ngOnInit
let a$: AsyncSubject<any>, b$: AsyncSubject<any>;
// ... init a$ and b$
let zipObs$ = Observable.create(obs => {
    this._sub = Observable.zip(a$, b$).subscribe([a,b] => obs.next([a,b]))
});
// ...
ngOnDestroy() { this._sub.unsubscribe(); }

Now it stops polling when the component is destroyed but I can't figure what is stopping angular from doing that all by itself. I suspect it is because of the static operator but I'm not sure. Can you tell me why this is?

We're still using angular 4.4.4

EDIT: couldn't reproduce https://jsfiddle.net/RFontana/q6xwzhbk/ :thinkingface:

0 Answers
Related