HTTP-запрос задерживает один пользовательский ввод в angular

#angular

#angular

Вопрос:

Я нахожу некоторые трудности со следующей проблемой.

У меня есть 2 выпадающих меню:

 <h1>Change the inbound rates</h1>
<mat-form-field floatLabel="never" appearance="outline">
  <mat-label>Carriers</mat-label>
  <mat-select (selectionChange)="setCarrier($event.source.value)">
    <mat-option matInput required placeholder="label" *ngFor="let carrier of rateCards" [value]="carrier.carrierId">
      {{carrier.carrierName}}</mat-option>
  </mat-select>
</mat-form-field>

<mat-form-field floatLabel="never" appearance="outline">
  <mat-label>Ledger</mat-label>
  <mat-select [(value)]="ledgerName">
    <mat-option (onSelectionChange)="setLedger(ledgerName)" matInput required placeholder="label" *ngFor="let ledger of nameDefinitions" [value]="ledger.id">
      {{ledger.name}}</mat-option>
  </mat-select>
</mat-form-field>
  

Первый, который пользователь должен выбрать носитель. Моя цель состоит в том, чтобы в тот момент, когда пользователь выбирает носитель, идентификатор носителя передается в качестве параметра этой функции:

 setCarrier(id: number){
    console.log(id);
    this.ratecardService.getSelectedRatecard(id).subscribe(data => this.selectedRatecard = data);
    console.log(this.selectedRatecard);
    //this.updateCurrentValue();
  }
  

Это работает нормально. Консоль печатает выбранный идентификатор в первой строке этой функции.
Далее я ожидаю, что selectedRatecard ему будет присвоен объект JSON, который возвращается из:

 this.ratecardService.getSelectedRatecard(id).subscribe(data => this.selectedRatecard = data);
  

Вызываемая функция класса обслуживания выглядит следующим образом:

 getSelectedRatecard(id: number): Observable<Ratecard[]>{
        console.log(id);
        return this.http.get<Ratecard[]>('http://localhost:8080//shipmentRate/'   id)

      }
  

Снова печатается правильный номер (carrierId).

Но почему-то после первого выбора пользователя в строке console.log(this.selectedRatecard); выводится «undefined».

Только после другого выбора консоль напечатает правильную оценочную карту, которая была выбрана при первом выборе. Итак, допустим, я выбираю 1, ничего не происходит (не определено). Затем я выберу 2, и console.log(id) печатается 2, но console.log(this.selectedRatecard); будет напечатан рейтинг с идентификатором 1.

Комментарии:

1. http-вызов является асинхронным, поместите журнал в subscribe

2. Итак, как я могу убедиться, что http-вызов не является асинхронным. Другими словами, вызов выполняется немедленно?

Ответ №1:

Поскольку http-вызов является асинхронным, вы могли бы переписать setCarrier это:

 setCarrier(id: number){
    console.log(id);
    this.ratecardService.getSelectedRatecard(id)
      .pipe(tap(t => console.log(t))
      .subscribe(data => this.selectedRatecard = data);
  }
  

Затем вы можете просмотреть зарегистрированную дату в tap и по-прежнему назначать selectedRatecard

вы также могли бы использовать async/await :

 async setCarrier(id: number) {
    const data = await this.ratecardService.getSelectedRatecard(id).toPromise();
    console.log(data);
}
  

Комментарии:

1. Спасибо, теперь я понимаю проблему. Нет необходимости регистрировать идентификатор, но я хочу, чтобы карточка this.ratecard назначалась, когда пользователь выбирает опцию. Так что не асинхронный. Но я не знаю, как это сделать.

2. наблюдаемые всегда асинхронны, такова их природа, по сути, вы можете создать более синхронизированный подход, используя promises… однако он все еще асинхронный 🙂