Наблюдаемые, асинхронные и другие - PullRequest
0 голосов
/ 16 сентября 2018

После одного целого дня, ломающего мою голову, пытаясь найти подходящее решение, я наконец-то пришел сюда за помощью.

ЧТО МНЕ НУЖНО В сервисе я должен предоставить функцию, возвращающую массив объектов; В первый раз эти объекты извлекаются из веб-службы с помощью HttpClient, но затем я хотел бы сохранить их в локальной переменной, чтобы избежать затрат времени и трафика при каждом вызове этой сервисной функции.
Наконец, я должен показать эти объекты в теге <select *ngFor и установить значение по умолчанию после установки значений.

ПЕРВАЯ ПОПЫТКА

service.ts

  stati = null;

    getStati() {
      if (this.stati) return this.stati;
      return this.http.get<ApiResponse>(this.apiUrl + 'lists/stati')
        .pipe(
          retry(3),
          map(data => {
            if (data.status === 0)
              this.stati = data.response; // <-- this is an array
            return this.stati;
          }
      ));
    }

request.component.ts

this.svcApi.getStati()
  .subscribe((stati) => {
    this.stati = stati;
    this.request.nascita.stato = 'IT';
    this.request.residenza.stato = 'IT';
  });

request.component.html

<select class="form-control"
        [(ngModel)]="request.nascita.stato" name="stato">
  <option *ngFor="let stato of stati" 
      [value]="stato.codice">{{stato.nome | uppercase}}</option>
</select>

Это работает ТОЛЬКО в первый раз, но когда мой маршрутизатор (пере) активирует маршрут, я получаю ошибку в компоненте, утверждающую, что svcApi.getStati().subscribe не является функцией; естественно, я понимаю это, потому что на этот раз я не возвращаю Observable, а вместо этого массив!

ВТОРАЯ ПОПЫТКА
Поэтому я попытался изменить сервисную функцию:
if (this.stati) return Observable.from(this.stati);

Но когда я возвращаюсь к маршруту, я получаю эту ошибку в консоли:

Ошибка: не удается найти другой поддерживающий объект '[объект объекта]' типа «объект». NgFor поддерживает только привязку к Iterables, таким как Массивы.

ТРЕТЬЯ ПОПЫТКА
Моя последняя попытка была также изменить

<option *ngFor="let stato of stati | async"

но я получаю эту ошибку

ОШИБКА TypeError: Невозможно прочитать свойство 'dispose' из null в AsyncPipe.push

Я почти уверен, что простое решение должно существовать, но, будучи новичком, я не могу думать об этом.

1 Ответ

0 голосов
/ 16 сентября 2018

Как упомянуто в комментарии:

Вместо if (this.stati) возвращает Observable.from (this.stati) try: if (this.stati) возвращает Observable.of (this.stati)

Чувствуется немного коротким для фактического ответа, поэтому даст немного больше контекста:

of(x) эквивалентно from([x]).

of в основном оборачивает все, что передано без каких-либо изменений - of(of) глупо, но совершенно нормальноfrom с другой стороны предполагает, что значение имеет тип ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;, и попытается преобразовать исходную оболочку в наблюдаемую.Например, from(42) неверно, но from('42') - последний издает 4, 2 и completes.string - это действительно ArrayLike, что может сбить с толку, если кто-то думает, что from ведет себя как of.from кажется немного перегруженным - лично я никогда не использую SubscribableOrPromise<T>.

Интуитивно from можно легко интерпретировать как эквивалент of.Imho должна быть такая функция, как fromArray - тем более, что есть fromPromise, которая вряд ли полезна, поскольку не ленива.В моем случае почти всегда массив передается from.

Некоторые дополнительные отзывы

В чистом состоянии, если getStati вызывается несколько раз, будет несколькозапросы к серверу и кешу никогда не истекает.

...