Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I use `Observable.bindCallback()` with typescript

I've got a google maps direction service I'm trying to convert to an Observable pattern. Here is the example from https://developers.google.com/maps/documentation/javascript/examples/directions-simple:

  function calculateAndDisplayRoute(directionsService, directionsDisplay) {
    directionsService.route({
      origin: document.getElementById('start').value,
      destination: document.getElementById('end').value,
      travelMode: 'DRIVING'
    }, function(response, status) {
      if (status === 'OK') {
        directionsDisplay.setDirections(response);
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    });
  }

I tried the following:

import { Observable } from 'rxjs/Observable'; 
...
  // the callback version works
  getRoute (route: any) {
    const defaults = { 'travelMode': 'WALKING' };
    route = Object.assign(defaults, route);
    this._directionsService.route(
      route
      , (res:any, status:string) => {
          if (status == 'OK')
            this.displayRoute(res);
          else
            this.handleError(res)
       })
  }

  // the Observable version doesn't get past typescript
  getRoute$ (route: any) {
    const defaults = { 'travelMode': 'WALKING' };
    route = Object.assign(defaults, route);
    let route$ = Observable.bindCallback(
      this._directionsService.route
      , (res, status)=>{res, status}
    );
    // TS says, "Supplied parameters do not match any signature of call target
    route$( route ).subscribe(
      (resp:any)=>{
        // also, how do I throw an error from the selector func?
        if (resp.status == 'OK')
          this.displayRoute(resp.res);
        else
          this.handleError(resp.res)
      }
    )
  }

Why is typescript rejecting this pattern?

like image 574
michael Avatar asked May 16 '26 00:05

michael


2 Answers

I just dealt with the same error while trying to use bindCallback. I got around it by explicitly specifying the type of the var pointing to the result of bindCallback. I just used "any". In your case, try

let route$ : any = Observable.bindCallback(...)

This doesn't explain why Typescript rejects it though. I'd guess it's because the type definitions for the result of bindCallback are parameterized (i.e., they're generically typed). Look at BoundCallbackObservable.d.ts to see what I mean. Notice the multiple parameterized definitions for all those overloaded "create" methods (one of which is ultimately what gets invoked).

like image 105
Shawn Flahave Avatar answered May 17 '26 13:05

Shawn Flahave


In rxjs 5 you can fix this by fulfilling the following type signature.

static create<T, R>(callbackFunc: (v1: T, callback: (result: R) => any) => any, selector?: void, scheduler?: IScheduler): (v1: T) => Observable<R>;

Notice that it takes two types in order to return a callback with one parameter type T that returns Observable<R>.

Usage

type routeType = String

interface returnType = {
  res: any
  status: any
}

let route$: any = Observable.bindCallback<routeType, observableType>(this._directionsService.route, (res, status)=>{res, status})

Now the type of route$ is (v1: routeType) => Observable<observableType>

like image 29
epelc Avatar answered May 17 '26 14:05

epelc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!