Luke T O'Brien Luke T O'Brien - 4 months ago 23
AngularJS Question

How do you get an Observable of a Event?

I'm wondering how do you get an Observable of a Event in Angular 2?

For example I want to subscribe to a click event but only emit after two clicks? Is possible to get a Observable of

MouseClick
event objects?

Say if I wanted to filter by
button
or
ctrlKey
- Or a Observable of
KeyboardEvent
and filter by
key
\
keyCode
- Or any possible future scenario

I have read http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html but the
valueChanges
property is
Observable<string>


I have also seen on https://github.com/angular/angular/issues/5489 that it is possible to do something like:

this.clickStream = new Subject();
...
<button (click)="clickStream.next($event)">Click Me</button>


Is the
Subject
method above the correct way to do it? I am unsure.

I don't have much experience with Angular 2 or RxJS, but I am interested by both and am investigating them with the idea of using them in future projects

Edit

Here's my Plunker with a simple click use case http://plnkr.co/edit/u1A7ve2fAYigjwaZ0x1v?p=preview

Answer

Observable has a fromEvent operator, but to use it you'll need a reference to the native element. The way to get it is to use viewChild/contentChild to get an elementRef.

Next you can bind to its click like so:

var clickStream = Observable.fromEvent(btnRef.nativeElement, 'click');

If I understood the filtering thing properly, you want the stream to emit only after the click was pressed twice, or to be more precise, once for each 2 clicks, to do so, use the bufferWithCount operator:

var triggerFor2Clicks = clickStream.bufferWithCount(2);

This will emit an array of 2 events at a time, so your action handler can be:

triggerFor2Clicks.subscribe(() => my2ClicksHandler);

Note that the arguments are empty, notated as '()' since you don't really care for the events, just to the fact that they were 2 of them.