webentwicklung-frage-antwort-db.com.de

Winkel 2: Verwendung des beobachtbaren Filters

Ich habe einen Dienst, der die API wie folgt aufruft:

return this._http
        .post(appSettings.apiUrl + 'SomeController/SomeAction', params, {withCredentials: true, headers: this.headers})
        .timeoutWith(appSettings.maxTimeHttpCalls, Observable.defer(() => Observable.throw(this._feedbackService.timeout())))
        .map((response: Response) => response.json().data);

Jetzt möchte ich eine Filterfunktion für diesen Aufruf mithilfe von rxjs/add/operator/filter implementieren, er kann jedoch nicht ordnungsgemäß funktionieren. 

Dies ist der Ansatz, den ich gewählt habe:

return this._http
        .post(appSettings.apiUrl + 'SomeController/SomeAction', params, {withCredentials: true, headers: this.headers})
        .timeoutWith(appSettings.maxTimeHttpCalls, Observable.defer(() => Observable.throw(this._feedbackService.timeout())))
        .filter(response => response.json().data.Type === 5)
        .map((response: Response) => response.json().data);

Aber egal was ich filtere, die ngFor-Schleife erzeugt nichts, solange der Filter da ist. Wenn ich es entferne, funktioniert alles wie erwartet. 

Soll ich den Filter vor oder nach der map hinzufügen?

Kann ich so nach der Antwort-JSON filtern oder muss ich eine andere Syntax verwenden?

Beispiel JSON

Hier ein Beispiel, wie die Antwort von JSON aussieht:

data: [
    {
        "Type": 5,
        "Description": "Testing",
        "ID": "001525"
    }
]
6
Glenn Utter

Ob filter() vor oder nach map() sein sollte, hängt davon ab, was Sie tun möchten.

Ich denke, in Ihrem Fall sollte map() vor filter() gehen, da Sie zunächst Daten von JSON dekodieren und dann filtern möchten. Die Art und Weise, wie Sie sie jetzt haben, gibt nichts zurück, wenn die Bedingung in filter() in false aufgelöst wird, da Sie die gesamte response verwenden. Vielleicht ist es das, wonach du strebst ...

Ich weiß nicht, wie Ihre Antwortstruktur aussieht, aber ich würde mit so etwas wie dem gehen, was mehr Sinn macht:

map((response: Response) => response.json().data),
filter(data => data.Type === 5),

Bearbeiten:

Ich würde concatMap() mit from() verwenden, um das Array in einen Observable-Stream zu transformieren:

pipe(
  map(content => response.json().data),
  concatMap(arr => Observable.from(arr)),
  filter(item => item.Type === 5),
).subscribe(val => console.log(val));

Live-Demo anzeigen: http://plnkr.co/edit/nu7jL7YsExFJMGpL3YuS?p=preview

Jan 2019: Aktualisiert für RxJS 6

13
martin

Hier ein weiteres Beispiel basierend auf @ martins Antwort:

  public searchMediData(searchtearm: string) : Observable<MediData[]> 
  {  

    return this.http
               .get(this.url)
               .map(response => { 
                  let data = response.json();
                  let medidata = data as MediData[];
                  return medidata;
                })
                .concatMap(array => Observable.from(array))
                .filter(medi => {
                        let searchTearmUpperCase = searchtearm.toUpperCase();
                        let mediNameUpperCase = medi.Name.toUpperCase();                       
                        return mediNameUpperCase.includes(searchTearmUpperCase);
                 })
                .toArray();
  }
2
yonexbat