Обратный вызов и наблюдаемый в угловом резольвере - PullRequest
0 голосов
/ 21 декабря 2018

Я использую угловые преобразователи для предоставления данных для моих маршрутов.Для одного из них мне нужно получить lat и long для заданной строки адреса.Чтобы сделать это, я использую giq gocode api:

service.geocode({address: params.address}, results => {
  params.lat = results[0].geometry.location.lat();
  params.lon = results[0].geometry.location.lng();
});

Так что в моем сервисе мне нужно дождаться срабатывания обратного вызова, прежде чем вызывать мой apiService, поэтому основная идея заключается в достижении этого:

search(params): Observable<Calendar[]> {    
    return service.geocode({address: params.address}, results => {
          params.lat = results[0].geometry.location.lat();
          params.lon = results[0].geometry.location.lng();
          return this.apiService.get('/api/v1/website/' + environment.web_id + '/calendar/_search', params)
          .pipe(map(
            data => {
              return data;
            }
          ));
    });
}

Но мне нужно вернуть Observable, чтобы это не сработало.Есть ли способ получить наблюдаемый для обратного вызова геокода и затем использовать операторы rxJs для их цепочки?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Конечно, есть способ.Самый простой шаг - обернуть все это в наблюдаемое.Наивным подходом было бы сделать это:

search(params): Observable<Calendar[]> {
  // First, an observable. We get the observer back.
  return Observable.create(observer => {
    // Now go call your service.geocode (whatever that might be)
    service.geocode({address: params.address}, results => {
      // extend your params with the extra information.
      params.lat = results[0].geometry.location.lat();
      params.lon = results[0].geometry.location.lng();

      // shot the http request
      this.apiService.get('/api/v1/website/' + environment.web_id + '/calendar/_search', params)
        .pipe(
          map(data) => {
            // When the data is back, resolve it.
            observer.next(data);
            observer.complete();
          }),
        );
    });
  });

Теперь мы могли бы сделать лучше и извлечь часть этого.

/** Make just the non-observable part observable. Then we can simply add it to the chain */
getLatLon(address): Observable<{lat: any, lon: any}> {
  return Observable.create(observer => {
    service.geocode({address: params.address}, results => {
      // avoid side effects extra information.
      const lat = results[0].geometry.location.lat();
      const lon = results[0].geometry.location.lng();
        observer.next({ lat, lon });
        observer.complete();
  });
}
// Also

// Now you can use it in a regular chain.
search(params): Observable<Calendar[]> {
  return this.getLatLon(params)
    .pipe(
      map(coords => {
        // Again, we will avoid side effects.
        const fullParams = Object.assign({}, params, coords)
        return fullParams;
      }),
      map(fullParams => this.apiService.get(`/api/v1/website/${ environment.web_id }/calendar/_search`, params)),
    );
}

Вы могли бы пойти дальше с этим, но это основной.

0 голосов
/ 21 декабря 2018

Есть несколько способов, которыми вы можете достичь этого, (rxjs6)

import { of } from 'rxjs';

и затем создать наблюдаемое из значения, как показано ниже:

of(someValue);

, если вы напрямуювернуть someValue это будут нормальные данные, но если вы используете оператор из rxjs, вы можете преобразовать эти данные в наблюдаемые и подписаться на них, когда это необходимо. Пожалуйста, измените свой код соответствующим образом, надеюсь, это поможет

...