From a4b303e1338a35756a9cf7f67508d24d2f8537a2 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 25 Oct 2023 09:55:38 -0700 Subject: [PATCH] fix(angular): run platform subscriptions inside zone (#28404) Issue number: #19539 --------- ## What is the current behavior? When an app uses Capacitor, then the platform subscriptions will run outside of the Angular Zone. ## What is the new behavior? - The platform subscriptions will run inside of the Angular Zone regardless if it uses Capacitor or not. Added an extra `zone.run` within the event listener. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `npm install @ionic/angular@7.5.2-dev.11698187124.1b7ea660` --- .../angular/common/src/providers/platform.ts | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/angular/common/src/providers/platform.ts b/packages/angular/common/src/providers/platform.ts index 50b4083f65..e01c6edb77 100644 --- a/packages/angular/common/src/providers/platform.ts +++ b/packages/angular/common/src/providers/platform.ts @@ -68,12 +68,12 @@ export class Platform { }); }; - proxyEvent(this.pause, doc, 'pause'); - proxyEvent(this.resume, doc, 'resume'); - proxyEvent(this.backButton, doc, 'ionBackButton'); - proxyEvent(this.resize, this.win, 'resize'); - proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow'); - proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide'); + proxyEvent(this.pause, doc, 'pause', zone); + proxyEvent(this.resume, doc, 'resume', zone); + proxyEvent(this.backButton, doc, 'ionBackButton', zone); + proxyEvent(this.resize, this.win, 'resize', zone); + proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow', zone); + proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide', zone); let readyResolve: (value: string) => void; this._readyPromise = new Promise((res) => { @@ -262,12 +262,20 @@ const readQueryParam = (url: string, key: string) => { return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null; }; -const proxyEvent = (emitter: Subject, el: EventTarget, eventName: string) => { +const proxyEvent = (emitter: Subject, el: EventTarget, eventName: string, zone: NgZone) => { if (el) { el.addEventListener(eventName, (ev) => { - // ?? cordova might emit "null" events - const value = ev != null ? (ev as any).detail : undefined; - emitter.next(value); + /** + * `zone.run` is required to make sure that we are running inside the Angular zone + * at all times. This is necessary since an app that has Capacitor will + * override the `document.addEventListener` with its own implementation. + * The override causes the event to no longer be in the Angular zone. + */ + zone.run(() => { + // ?? cordova might emit "null" events + const value = ev != null ? (ev as any).detail : undefined; + emitter.next(value); + }); }); } };