A little decorator to move Ionic Page events from callback pattern to observable pattern.
Source code
import { Observable, Subject } from "rxjs"; import { filter, map, tap } from "rxjs/operators"; export function IonPageEvent(event: "ionViewWillEnter" | "ionViewDidEnter" | "ionViewDidLeave" | "ionViewWillUnload" | "ionViewWillLeave" | "ngOnDestroy") { return (target: object, propertyKey: string) => { let subjectName = event + "_as_subject"; let obs = () => { return target[propertyKey] as Observable<string>; }; let sub = () => { return target[subjectName] as Subject<string>; }; Object.defineProperty(target, propertyKey, { get: () => sub().asObservable() }); if (!target[subjectName]) { Object.defineProperty(target, subjectName, { value: new Subject<string>() }); let orig = Object.getOwnPropertyDescriptor(target, event); obs() .pipe( filter(() => orig && typeof orig.value == "function"), tap(() => { console.log("CALLING ORIGINAL", target); }), map(() => orig.value as Function), tap(f => f.apply(target, [])) ) .subscribe(); //override native method target[event] = () => { console.info(IonPageEvent.name, event, "from", target.constructor.name); sub().next(event); }; console.assert(target[subjectName] instanceof Subject); console.assert(target[propertyKey] instanceof Observable); console.assert(target[event] instanceof Function); console.info(IonPageEvent.name, event, "config done on page", target.constructor.name); } }; }
Usage example
import IonPageEvent from "./pageEventsAsObservable.ts"; export class HomePage { ngOnInit(){ this.OnDidEnter.subscribe(()=>{ console.log("enter"); }); this.OnWillLeave.subscribe(()=>{ console.log("will leave"); }); } @IonPageEvent("ionViewDidEnter") OnDidEnter:Subject<any>; @IonPageEvent("ionViewWillLeave") OnWillLeave:Subject<any>; }
Todo
- NPM package
- Move from Subject Type to Observable Type
- Do not use console API