Асинхронный канал и ngFor не отображают элементы

#angular #rxjs

#angular #rxjs

Вопрос:

Я ожидаю *ngFor перебора результатов http.get , которые становятся доступными через асинхронный канал. Элементы не отображаются, как и загрузочный div.

Обслуживание:

 public getKeywords = () =>  {
   return this.http.get<getKeywords>(`${this.uri}/keywords`);
}
  

Интерфейс:

 interface getKeywords {
  keywords: Array<object>;
}
  

TS:

 export class KeywordsSettingsComponent implements OnInit {

  public currentKeywords$: any;

  constructor(private profileProvider: ProfileProvider) { }

  ngOnInit() {
    this.currentKeywords$ =
      this.profileProvider.getKeywords().pipe(map(({ keywords }) => keywords));
  }
}
  

Шаблон:

 <div class="row">
  <ng-template *ngIf="currentKeywords$ | async as currentKeywords ; else loading">
    <div class="keyword" * ngFor="let keywordObj of currentKeywords">
      {{ keywordObj.keyword }}
      <span class="icon-close"> </span>
    </div>
  </ng-template>
  <ng-template #loading> Loading keywords...</ng-template>
</div>
  

Тот факт, что загрузочный div не отображается, указывает на то, что значение не передается. Если я подпишусь в ngOnInt вот так:

  this.currentKeywords$ = this.profileProvider.getKeywords().pipe(map(({keywords}) => keywords), share()).subscribe(res => res));
  

Загружаемый div отображается, но результат не отображается в *ngFor div. Однако я понимаю, что асинхронный канал управляет подписками / отменой подписки, поэтому подписка в ngOnInit должна быть ненужной.


Результат http.get: HTTP-вызов возвращает объект, который имеет несколько свойств, одним из которых является «ключевые слова», который содержит массив объектов. Я использую map() для сопоставления с одним свойством и доступа к массиву объектов.

 {..."keywords":[{"id":331,"keyword":"spam"},{"id":330,"keyword":"foo"},{"id":332,"keyword":"brexit"}]}
  

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

1. Я бы тоже проверил в инструментах разработчика, чтобы посмотреть, что возвращает ваш HTTP-вызов. Возможно, вы ожидаете массив, в то время как возвращаемый может быть просто объектом.

2. HTTP-вызов возвращает объект со свойством «keywords», который представляет собой массив объектов.

Ответ №1:

Исходя из того факта, что HTTP возвращает объект, вам нужно будет изменить это:

 <div class="keyword" * ngFor="let keywordObj of currentKeywords">
  

к этому:

 <div class="keyword" *ngFor="let keywordObj of currentKeywords.keywords">
  

и я бы также изменил это:

 this.currentKeywords$ =
      this.profileProvider.getKeywords().pipe(map(({ keywords }) => keywords));
  

к этому также:

 this.currentKeywords$ = this.profileProvider.getKeywords();
  

… поскольку эта карта на самом деле ничего не отображает.

Вам также может потребоваться изменить свой first <ng-template на e.g <div , поскольку я полагаю, что он не будет отображаться сам по себе.

Надеюсь, это поможет.

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

1. HTTP-вызов возвращает объект, который имеет несколько свойств, одним из которых является «ключевые слова», который содержит массив объектов. Я использую map() для сопоставления с одним свойством и доступа к массиву объектов.