#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() для сопоставления с одним свойством и доступа к массиву объектов.