web-dev-qa-db-fra.com

RxJS 6 obtenir une liste filtrée de tableau de Observable

Dans ma classe ThreadService, j'ai une fonction getThreads() qui me renvoie un Observable<Thread[]> avec tous mes threads.

Maintenant, j'aimerais avoir une autre version de ma fonction avec mes threads filtrés par un thème sélectionné: function getSelectedThemeThreads(theme: Theme).

J'ai essayé avec les opérateurs map et filter mais j'ai le message d'erreur suivant Property 'theme' does not exist on type 'Thread[].

Ci-dessous le code sur lequel je travaille:

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

Merci d'avance pour votre aide.

3
Johan Rin

J'ai fait un exemple de ceci StackBlitz/angular6-filter-result

L'idée principale est de filtrer dans map() car le filtre obtiendra un tableau d'objets.

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

Il suffit de changer map(threads => threads) en mergeAll()

0
Fabricio

Essayez en utilisant le code suivant.

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

Je pense que vous recherchez 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], [])
    )
  );
}

Faites-moi savoir comment ce code fonctionne pour vous. En tout cas, si vous avez besoin de jouer avec cela, il y a un moment, un exemple est arrivé e, j'espère que cela vous aidera à clarifier.

0
Luillyfe

Vous étiez presque là. Utiliser map(threads => threads) ne fait rien mais vous avez probablement voulu l’utiliser à la place:

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

concatMap ou switchMap fonctionnera également. L'opérateur mergeMap itérera le tableau et émettra chaque élément séparément afin que vous puissiez utiliser filter() comme vous le faites déjà.

Vous pouvez bien sûr utiliser aussi ceci:

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