Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert custom library events (ie. Google Maps events) into Observable stream in RxJS?

I want to create an RxJS observable stream from Google Map events. I know how to do this from native browser events, like so:

var result = document.getElementById('result');

var source = Rx.Observable.fromEvent(document, 'mousemove');

var subscription = source.subscribe(function (e) {
  result.innerHTML = e.clientX + ', ' + e.clientY;
});

The mousemove is a browser event, which leads me to believe that .fromEvent() recognizes mousemove as a hard-coded default. However, if I want to recognize custom events how can I create an observable stream? Take for example Google Maps:

var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: -25.363, lng: 131.044}
  });

  map.addListener('center_changed', function() {
    var center = map.getCenter()
    console.log(center)
  });

The reason why I want to convert these google map events into an observable stream is so that I can use RxJS debounce for performance improvements. That way center_changed is only recognized in batches (instead of firing 10x over 2 seconds, it just recognizes the last 1x in that same 2 seconds). My dilemma is converting that custom Google Maps event into an observable stream. Perhaps there is an easy way to continuously add to an observable, but from my search I have not found out how to do that.

I really appreciate your help in this matter!

like image 951
Kangzeroo Avatar asked Mar 10 '17 20:03

Kangzeroo


1 Answers

You should be able to use fromEventPattern to do what you want:

var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: { lat: -25.363, lng: 131.044 }
});

var source = Rx.Observable.fromEventPattern(
    function (handler) {
        return map.addListener('center_changed', handler);
    },
    function (handler, listener) {
        google.maps.event.removeListener(listener);
    }
);
source.subscribe(function () {
    console.log(map.getCenter());
});

fromEventPattern lets you provide the add and remove implementations, so it's easy to get an observable from most types of 'custom' event mechanisms. Note that the value returned by the add handler is passed to the remove handler as the second parameter. In this case, it's the listener - which is what's needed when removing Google Maps event listeners.

like image 103
cartant Avatar answered Oct 20 '22 02:10

cartant