From 9433550d9917f166a1ffa3e0cd71d1914d908561 Mon Sep 17 00:00:00 2001 From: Mark Berry Date: Fri, 18 Sep 2020 03:51:05 -0500 Subject: [PATCH] Unsubscribe prop subscriptions --- .../angular/components/app.component.ts | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/angular/src/client/preview/angular/components/app.component.ts b/app/angular/src/client/preview/angular/components/app.component.ts index f0a094788c9d..81d2cada177c 100644 --- a/app/angular/src/client/preview/angular/components/app.component.ts +++ b/app/angular/src/client/preview/angular/components/app.component.ts @@ -33,6 +33,8 @@ export class AppComponent implements OnInit, OnDestroy { subscription: Subscription; + propSubscriptions = new Map(); + constructor( private cfr: ComponentFactoryResolver, private changeDetectorRef: ChangeDetectorRef, @@ -64,6 +66,13 @@ export class AppComponent implements OnInit, OnDestroy { if (this.subscription) { this.subscription.unsubscribe(); } + + this.propSubscriptions.forEach(v => { + if (!v.sub.closed) { + v.sub.unsubscribe(); + } + }) + this.propSubscriptions.clear(); } /** @@ -93,7 +102,7 @@ export class AppComponent implements OnInit, OnDestroy { } } } else if (typeof value === 'function' && key !== 'ngModelChange') { - instanceProperty.subscribe(value); + this.setPropSubscription(key, instanceProperty, value); } }); @@ -123,4 +132,26 @@ export class AppComponent implements OnInit, OnDestroy { instance.registerOnChange(props.ngModelChange); } } + + /** + * Store ref to subscription for cleanup in 'ngOnDestroy' and check if + * observable needs to be resubscribed to, before creating a new subscription. + */ + private setPropSubscription(key: string, instanceProperty: Observable, value: any): void { + if (this.propSubscriptions.has(key)) { + const v = this.propSubscriptions.get(key); + if (v.prop === value) { + // Prop hasn't changed, so the existing subscription can stay. + return; + } + + // Now that the value has changed, unsubscribe from the previous value's subscription. + if (!v.sub.closed) { + v.sub.unsubscribe(); + } + } + + const sub = instanceProperty.subscribe(value); + this.propSubscriptions.set(key, { prop: value, sub }); + } }