RxJS 6 получает отфильтрованный список массива Observable

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

Заранее спасибо за вашу помощь.

Я думаю, что потоки - это массив, который вы должны сделать, как фильтр map (thread => threads.filter), в этом случае стандартный js

Whisher 02.06.2018 19:24

filter может быть starndar js (затем использовать внутри карты) или Rxjs learnrxjs.io/operators/filtering/filter.html. Но .. Что такое theme.id в thread.theme.id === theme.id?

Eliseo 03.06.2018 16:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
2
12 690
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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: |, похоже, это не сработает

hamilton.lima 03.06.2018 00:57
Ответ принят как подходящий

Я сделал пример этого 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.

sarora 07.03.2019 16:18

Вы были почти у цели. Использование этого 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, надеюсь, это поможет вам уточнить.

Другие вопросы по теме