My goal is to use RxJs switchMap
in an Ionic 3 project, to cancel any ongoing login attempts if a server is offline, and use latest request only. Otherwise I can get some unwanted asynchronous side effects later.
In my view layer, I'm using submitStream$
to capture a button clickstream, then passing that to the service layer as a method argument.
In the service layer, I'm creating response$
via a switchMap
, combining, the passed parameter submitStream$
, with an Observable<Response>
that comes back from this.webServiceUtil.testLogin()
.
I tried implementing this code:
HTML markup
<button #submit type="submit">Submit</button>
Typescript : View Layer
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { ElementRef, ViewChild } from '@angular/core';
export class LoginPage {
@ViewChild('submit') button: ElementRef
submitStream$:any;
...
ionViewDidLoad() {
this.submitStream$ =
Observable.fromEvent(this.button.nativeElement, 'click')
}
...
}
Typescript : Service Layer (submitStream$ comes in as method argument)
this.response$ = submitStream$.switchMap(click =>
this.webServiceUtil.testLogin())
I've also tried creating this.submitStream$
in ngAfterViewInit()
When things didn't work I also tried appending this to the Observable.fromEvent:
.subscribe(ev => {
console.log('LoginPage: ionViewDidLoad() submitStream$.subscribe(): ev:', ev);}
)
How do I overcome the 'ERROR TypeError: Invalid event target'?
It seems that you have to do some funky stuff to make what you subscribe to, look correct in RxJs's eyes...
So this is what I did to solve the ERROR TypeError: Invalid event target:
In AuthService, passing either the
submitClickStream$
, or the button element from @ViewChild, and doing Observable.fromEvent on it from within AuthService, I was unable to get the subscribe with the console logging of events, to ever fire.So, I introduced a BehaviourSubject intermediary.
I could just use regular
(click)='onSubmit()'
again in the<button>
element of LoginPage.html.In the onSubmit() method of LoginPage.ts, I could directly use the BehaviourSubject with
this.clickStream$.next('');
.This did away with the complexities of Observable.fromEvent, and ViewChild.
switchMap finally worked, cancelling earlier ongoing requests without messy unsubscribe logic.
LoginPage.ts
AuthService
WebServiceUtil