RxJS 6 получить отфильтрованный список массивов Observable - PullRequest
0 голосов
/ 02 июня 2018

В моем классе 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)
  );
}

Заранее благодарим за помощь.

Ответы [ 5 ]

0 голосов
/ 03 июня 2018

Я думаю, что вы ищете 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, надеюсь, это поможет вам уточнить.

0 голосов
/ 03 июня 2018

Просто измените map(threads => threads) на mergeAll()

0 голосов
/ 03 июня 2018

Я сделал пример этого StackBlitz / angular6-filter-result

Основная идея состоит в том, чтобы фильтровать в map(), поскольку фильтр получит массив объектов.

getSelectedThemeThreads(theme: string): Observable<Flower[]> {
    return this.http.get<Flower[]>(this.threadsUrl).pipe(
      map(result =>
        result.filter(one => one.theme === theme)
      )
    )
  }
0 голосов
/ 03 июня 2018

Вы были почти там.Использование этого 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),
0 голосов
/ 03 июня 2018

Попробуйте использовать следующий код.

getSelectedThemeThreads(theme): Observable<Thread[]> {
    return this.http.get<Thread[]>(this.threadsUrl)
    .map(res => res)
    .filter(thread => thread.theme.id == theme.id);
}    
...