Angolare 2: Come utilizzare Osservabili filtro

Ho un servizio che si chiama l’API come questo:

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

Ora vorrei implementare una funzione di filtro su quella chiamata utilizzando rxjs/add/operator/filter, ma non riesco a farla funzionare correttamente.

Questo è l’approccio che ho preso:

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

Ma non importa quello che ho il filtro, il ngFor loop non produce nulla se il filtro è in là. Se lo rimuovi, tutto funziona come previsto.

Dovrei aggiungere il filtro prima o dopo il map?

Posso filtrare la risposta JSON così, o devo usare un’altra sintassi?

Esempio JSON

Ecco un esempio di cosa la risposta JSON, assomiglia a questo:

data: [
    {
        "Type": 5,
        "Description": "Testing",
        "ID": "001525"
    }
]
La più probabile spiegazione è che c’è il Tipo di campo del campo di dati json non è uguale a 5. Qual è il JSON?

OriginaleL’autore Glenn Utter | 2016-10-18

2 Replies
  1. 14

    Se filter() dovrebbe essere prima o dopo map() dipende da cosa si vuole fare.

    Credo che nel tuo caso map() dovrebbe andare prima di filter() perché si vuole prima di decodificare dati JSON e poi filtrare. Il modo in cui hai ora non restituisce alcun valore se la condizione in filter() risolve false perché si utilizza in tutta la response. Forse è per questo che si sta andando per…

    Non so che cosa la vostra struttura della risposta ma mi piacerebbe andare con qualcosa di simile a ciò che rende più senso:

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

    Edit:

    Mi piacerebbe utilizzare concatMap() con from() per trasformare la matrice Osservabili in streaming:

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

    Vedere live demo: http://plnkr.co/edit/nu7jL7YsExFJMGpL3YuS?p=preview

    Gen 2019: Aggiornato per RxJS 6

    Ho aggiunto qualche esempio JSON. Ho provato il tuo modo con il filtro scorso, e il filtro sia data.Type === 5 e data.ID === '001525' ma entrambi falliscono.
    Che è quello che ho pensato. data è un array di oggetti, ma map((response: Response) => response.json().data) restituisce questo come una matrice di grandi dimensioni che viene quindi passato al filtro. Così si desidera scorrere il risultato e tornare solo gli Oggetti in cui data.Type === 5?
    Che è un po ‘ più complicato. Vedere il mio aggiornati risposta con il demo.
    Grazie sir. Ho modificato il mio codice, ma mi da Property 'Type' does not exist on type '{}' quando si fa che all’interno del filtro istruzione.
    Ok, è che un Dattiloscritto errore di compilazione? È possibile utilizzare item['Type'] invece o definire il corretto tipo di .filter(item:Whatevertypeitis => ...

    OriginaleL’autore martin

  2. 2

    Qui un altro esempio basato su @martin risposta:

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

    OriginaleL’autore yonexbat

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *