Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use Observable.bindCallback()

How do I use Observable.bindCallback() with a callback that returns 2 args, callback(results, status)? The example is with google.maps.places API below:

  const service = new google.maps.places.PlacesService(map);
  // service.nearbySearch(request, callback);


  function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        createMarker(results[i]);
      }
    }
  }

I want to do something like this:

const handleError = err=>console.error(error);

const nearbyAsObservable = Observable.bindCallback(service.nearbySearch)
nearbyAsObservable(request)
   .subscribe( 
     (results,status)=>{
       if (status!="OK") handleError(results);
       callback
     }
     , handleError
   )

but I am unsure about the following:

1) is the best practice to "throw" an error from the next handler and catch it in the error handler, or just call the method handleError()?

2) I am getting Cannot read property 'nearbySearch' of undefined(…) error. But when I call const nearbyAsObservable = Observable.bindCallback( service.nearbySearch.bind(service) ) I get a TS error:

// const nearbyAsObservable = Observable.bindCallback(service.nearbySearch.bind(service) )
// nearbyAsObservable(request)
[ts] Supplied parameters do not match any signature of call target.
const nearbyAsObservable: () => Observable<{}>

update it looks like this hack will fix the TS error

const nearbyAsObservable : any = Observable.bindCallback(service.nearbySearch.bind(service) )
nearbyAsObservable(request)
   .subscribe( 
     (results,status)=>{
       if (status!="OK") handleError(results);
       callback
     }
     , handleError
   )

but the next handler complains if I give it a (result, status)=>void

3) how do I transform the Observable return from Observable<[result, status]> to Observable<PlaceResult[]>?

like image 568
michael Avatar asked Nov 08 '16 07:11

michael


1 Answers

The answer is the following:

1) bind the scope to your callback, as necessary (see comment)

2) if you bind the scope, then use let nearbyAsObservable : any; to fix a TS bug how do I use `Observable.bindCallback()` with typescript

3) use a selector function in Observable.bindCallback() to map multiple return args into a single response for the subscribe function, and also to throw errors. How do I use the RXJS selector function in the Observable.bindCallback method?

let nearbyPlaces = function(position: google.maps.LatLng) : Observable<google.maps.places.PlaceResult[]> {  
  const service = new google.maps.places.PlacesService(map)
  // 1) bind scope
  const nearbySearchCallback = service.nearbySearch.bind(service)

  let nearbyAsObservable : any;
  // 2) type any fixes: 
  //    [ts] Supplied parameters do not match any signature of call target. 
  //    const nearbyAsObservable: () => Observable<{}>  

  nearbyAsObservable = Observable.bindCallback( 
    nearbySearchCallback        // with bound scope
    , (results, status) => {    // 3) selector function
        if (status != google.maps.places.PlacesServiceStatus.OK) throw {status, results};
        return results  
      }
  );
  const placeRequest = {
    location: position,
    radius: 25,
    rankBy: google.maps.places.RankBy.PROMINENCE,
  }
  return nearbyAsObservable(placeRequest) as Observable<google.maps.places.PlaceResult[]>
}


// usage example:
nearbyPlaces(position).subscribe(
  (results:google.maps.places.PlaceResult[])=>console.log(results)
  , err=>console.error(err)
)
like image 136
michael Avatar answered Oct 03 '22 03:10

michael