Wrap an API function in an RxJs Observable

3.6k views Asked by At

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?

1

There are 1 answers

0
Julia Passynkova On BEST ANSWER

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);
   }
  });
});