Angular2 Observable - how to wrap a third party ajax call
Asked Answered
M

2

5

I'm using Google's places api - getPlacePredictions.

Here is my code on my input keyup event:

My template:

<input type="text" (keyup)='search()'>
<div *ngIf="searching">Searching ... </div>

My Class:

private autocomplete;

ngAfterViewInit () {
    this.autocomplete = new google.maps.places.AutocompleteService();
}

search(){
    this.searching = true;
    this
    .autocomplete
    .getPlacePredictions( option , ( places , m )=> {
        console.log( 'onPrediction' , places ); 
        this.searching = false;
    } ); 
}

Is there any practicable way to wrap getPlacePredictions, inside a rxjs observable so I can take advantage of subscribing to this function ?

What I'm trying to do eventually here is to create a loading icon visible and invisible, but I can't make it properly with the google's api itself, I guess if I could wrap it inside an Observable, it would become easy.

Margerymarget answered 4/6, 2016 at 6:17 Comment(1)
See angular.io/docs/ts/latest/cookbook/…. It explains how to use an RxJS5 Subject inside a service (it is a bit more Angular than what @Jigar presents). Put your Google maps interaction into a service, and use next() to emit data. Have components subscribe to changes.Fulkerson
Q
9

You could wrap the call to the getPlacePredictions method within a raw observable this way:

search(option) {
  return Observable.create((observer) => {
    this.autocomplete
      .getPlacePredictions( option , ( places , m )=> {
        observer.next(places);
      }); 
  });
}

Then you will be able to subscribe to it:

this.searching = true;
this.search(option).subscribe(places => {
  this.searching = false;
  this.places = places;
});

As of later Angular versions https://mcmap.net/q/335342/-angular-create-is-deprecated-use-new-observable-instead

Use:

return new Observable((observer) => {
  this.autocomplete
    .getPlacePredictions( option , ( places , m )=> {
       observer.next(places);
     }); 
  });
}
Quarters answered 4/6, 2016 at 12:20 Comment(1)
see resource for update #55539603Questioning
S
0

You can create an RxJS Subject in an Angular Service that wraps the 3rd party ajax call. For example:

@Injectable()
export class PredictionService {
  public Prediction: rx.Subject();
  private autocompleteService: new google.maps....
  constructor() { 
  this.Prediction = new rx.Subject();
  }

  getPredictions(options: any) {
    this.autocompleteService.getPlacesPrediction(options,(places, m)=>{
      this.Prediction.onNext(places); // pass appropriate predictions
   });        
  }    
}

You can then request data by calling a method of service and get response via subscription of the RxJS Subject.

@Component() //configuration avoided for brevity
class Component 
{
 constructor(private PredictionService) {
 this.PredictionService.Prediction.subscribe((placesResult)=>{
   ... //This is where you get your data.
 });
  }

  search(){
   this.PredictionService.getPredictions(options);
  }
}

Within your function that is subscribing to the Observable, you can toggle visibility of loading image.

Salvia answered 4/6, 2016 at 11:1 Comment(1)
( is that Persian ? ) , can you elaborate with an example please.Margerymarget

© 2022 - 2024 — McMap. All rights reserved.