web-dev-qa-db-de.com

RxJS 6 erhält eine gefilterte Liste von Observable-Feldern

In meiner ThreadService-Klasse habe ich eine Funktion getThreads(), die mir einen Observable<Thread[]> mit allen meinen Threads zurückgibt.

Nun möchte ich eine andere Version meiner Funktion haben, in der meine Threads nach einem ausgewählten Thema gefiltert werden: Funktion getSelectedThemeThreads(theme: Theme).

Ich habe es mit den Operatoren map und filter versucht, aber ich habe die folgende Fehlermeldung Property 'theme' does not exist on type 'Thread[].

Unter dem Code, an dem ich arbeite:

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)
  );
}

Vielen Dank im Voraus für Ihre Hilfe.

3
Johan Rin

Ich habe ein Beispiel für dieses StackBlitz/angle6-filter-result gemacht

Die Hauptidee besteht darin, in map() zu filtern, da der Filter ein Array von Objekten erhält.

getSelectedThemeThreads(theme: string): Observable<Flower[]> {
    return this.http.get<Flower[]>(this.threadsUrl).pipe(
      map(result =>
        result.filter(one => one.theme === theme)
      )
    )
  }
1
hamilton.lima

Ändern Sie einfach map(threads => threads) in mergeAll()

0
Fabricio

Versuchen Sie es mit folgendem Code.

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

Ich denke, Sie suchen nach grupobyoperator :

getSelectedThemeThreads(): Observable<Thread[]> {
  return this.http.get<Thread[]>(this.threadsUrl).pipe(
    groupby(thread => thread.id),
    mergeAll(group$ => group$.pipe(
      reduce((acc, cur) =>[...acc, cur], [])
    )
  );
}

Lassen Sie mich wissen, wie dieser Code für Sie funktioniert. Auf jeden Fall, wenn Sie damit spielen müssen, kam vor einiger Zeit mit diesem Beispiel e, ich hoffe, es hilft Ihnen bei der Klärung.

0
Luillyfe

Du warst fast da. Die Verwendung dieser map(threads => threads) bewirkt nichts, aber Sie möchten wahrscheinlich stattdessen Folgendes verwenden:

mergeMap(threads => threads) // will turn Observable<Thread[]> into Observable<Thread>

concatMap oder switchMap funktionieren ebenfalls. Der Operator mergeMap durchläuft das Array und gibt jedes Element separat aus, sodass Sie filter() wie bereits verwendet verwenden können.

Sie könnten natürlich auch folgendes verwenden:

map(threads => threads.find(thread => thread.theme.id === theme.id)),
filter(thread => thread !== undefined),
0
martin