Angular how do I filter the data from an observable using rxjs pipe

Sumchans picture Sumchans · May 17, 2018 · Viewed 23.9k times · Source

I make a call to a method called getWorkOrders() in my service file which in turn makes a call to the server to fetch the records.

Here is my service. I am using the new HttpClient.

export class BackendServices {
  private BASE_URL ='http://localhost:3000/backend';
  constructor(private http: HttpClient) {}
  getWorkOrders(){
    return this.http.get(this.BASE_URL + '/getworkorders/');
 }
}

Component.ts file

private woSubject = new BehaviorSubject<IWorkOrders[]>([]);
    getWorkOrders() {
        this.bs.getWorkOrders()
          .subscribe((data: any) =>
            this.woSubject.next(data),
        );
      }

From the component getWorkOrders method how do I filter the data from all the records that was fetched from the server. I understand that it is using pipe & the filter rxjs operators, but not sure how to put it together.

enter image description here

Answer

glendaviesnz picture glendaviesnz · May 17, 2018

If you want to filter the workorders that come from the server using an rxjs filter you will need to turn the array of workorders into an observable of workorders, eg.

export class BackendServices {
    private BASE_URL ='http://localhost:3000/backend';
    constructor(private http: HttpClient) {}

    getWorkOrders(){
        return this.http.get(this.BASE_URL + '/getworkorders/')
                   .pipe(map((data) => Observable.from(data));
    }
}

private woSubject = new BehaviorSubject<IWorkOrders[]>([]);
    getWorkOrders() {
        this.bs.getWorkOrders()
          .pipe(
              filter(data => data.timestamp > 123456786 ),
              toArray()
           )
          .subscribe((data: any) =>
               this.woSubject.next(data),
           );
        }

The alternative is just to filter the array in a map using the standard array filter, eg.

export class BackendServices {
    private BASE_URL ='http://localhost:3000/backend';
    constructor(private http: HttpClient) {}

    getWorkOrders(){
        return this.http.get(this.BASE_URL + '/getworkorders/');
    }
}

private woSubject = new BehaviorSubject<IWorkOrders[]>([]);
    getWorkOrders() {
        this.bs.getWorkOrders()
          .pipe(map(data => data.filter(workorder => workrder.timestamp > 123456786) )
          .subscribe((data: any) =>
               this.woSubject.next(data),
           );
        }

One question I would ask is why you are pushing the result of the observable subscription into the behavior subject? Generally if you are pushing results from a subscription into another observable you can achieve the same thing by combining observables instead