В моем классе ThreadService у меня есть функция getThreads(), которая возвращает мне Observable<Thread[]> со всеми моими потоками.
Теперь я хотел бы иметь другую версию моей функции с моими потоками, отфильтрованными по выбранной теме: функция getSelectedThemeThreads(theme: Theme).
Я пробовал с операторами map и filter, но у меня появляется следующее сообщение об ошибке Property 'theme' does not exist on type 'Thread[].
Ниже кода, над которым я работаю:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Thread } from '../models/thread.model';
import { Theme } from '../models/theme.model';
@Injectable({
providedIn: 'root'
})
export class ThreadService {
private threadsUrl = 'api/threads';
constructor(private http: HttpClient) { }
getThreads(): Observable<Thread[]> {
return this.http.get<Thread[]>(this.threadsUrl);
}
getSelectedThemeThreads(): Observable<Thread[]> {
return this.http.get<Thread[]>(this.threadsUrl).pipe(
map(threads => threads),
filter(thread => thread.theme.id === theme.id)
);
}
Заранее спасибо за вашу помощь.
filter может быть starndar js (затем использовать внутри карты) или Rxjs learnrxjs.io/operators/filtering/filter.html. Но .. Что такое theme.id в thread.theme.id === theme.id?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Попробуйте использовать следующий код.
getSelectedThemeThreads(theme): Observable<Thread[]> {
return this.http.get<Thread[]>(this.threadsUrl)
.map(res => res)
.filter(thread => thread.theme.id == theme.id);
}
уловка в том, что поток в "filter (thread" - это Thread [], а не Thread: |, похоже, это не сработает
Я сделал пример этого StackBlitz / angular6-фильтр-результат
Основная идея заключается в фильтрации в map(), поскольку фильтр получает массив объектов.
getSelectedThemeThreads(theme: string): Observable<Flower[]> {
return this.http.get<Flower[]>(this.threadsUrl).pipe(
map(result =>
result.filter(one => one.theme === theme)
)
)
}
примечание: этот ответ основан на методе фильтрации собственного массива javascript, а не на фильтре в rxjs.
Вы были почти у цели. Использование этого map(threads => threads) ничего не дает, но вы, вероятно, хотели бы использовать это вместо этого:
mergeMap(threads => threads) // will turn Observable<Thread[]> into Observable<Thread>
concatMap или switchMap также подойдут. Оператор mergeMap будет перебирать массив и выдавать каждый элемент отдельно, так что вы можете использовать filter(), как вы уже делаете.
Конечно, вы также можете использовать это:
map(threads => threads.find(thread => thread.theme.id === theme.id)),
filter(thread => thread !== undefined),
Просто замените map(threads => threads) на mergeAll()
Думаю, вы ищете grupobyоператор:
getSelectedThemeThreads(): Observable<Thread[]> {
return this.http.get<Thread[]>(this.threadsUrl).pipe(
groupby(thread => thread.id),
mergeAll(group$ => group$.pipe(
reduce((acc, cur) =>[...acc, cur], [])
)
);
}
Сообщите мне, как этот код работает для вас. В любом случае, если вам нужно поиграть с этим, недавно появился этот примерe, надеюсь, это поможет вам уточнить.
Я думаю, что потоки - это массив, который вы должны сделать, как фильтр map (thread => threads.filter), в этом случае стандартный js