Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap an API function in an RxJs Observable

I am a newbie to RxJs and I have an API that I am using for geocoding that provides a function like the following:

simpleGeocode(options)
* where options = { address: {addr: ... }, success: Function, failure: Function}. The success function returns the geocoded LatLon object.

I am using this in Angular app with NGRX Effects and so I would like it to have it as an Observable so I can use the standard Effect setup like:

@Effect()
public calculateLocation: Observable<void> = this.actions
    .ofType(actions.CALCULATE_LOCATION)
    .switchMap((action) => {
        let location = action.payload;

        let options = {
            address: location.address
        };
         // ...

        this.geocodeService.simpleGeocode(options)
            .map(latLon => new actions.CalculateLocationSuccessAction(latLon);
            .catch(error => new actions.CalculateLocationFailureAction(error);
        },

But I am totally clueless as to how I would wrap that library call to make it into an Observable. I have read some information about bindCallback() from http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-bindCallback but I don't fully understand it. I did understand it requires a callback method to be the last parameter of the function so it doesn't look like it would work for my situation since both the success and failure functions are passed into the function as part of an object.

How would I make an Observable out of this API method that would map the success callback to the Observable's next and the failure to Observable's error?

like image 782
Mike Avatar asked Aug 31 '17 21:08

Mike


1 Answers

You can use Observable.create to wrap an external library with callback interface.

Something like that should work:

Observable.create(observer => {
  geocoder.geocode({'address': address}, function(results, status) {
   if (status === 'OK') {
     observer.next(results);
     observer.complete();
   }
   else {
     observer.error(status);
   }
  });
});
like image 111
Julia Passynkova Avatar answered Oct 17 '22 01:10

Julia Passynkova