15

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

Sumchans
  • 3,088
  • 6
  • 32
  • 59
  • did you try with filter? – Sajeetharan May 17 '18 at 02:47
  • I get a squiggly when I try the filter. I have imported filter this way, import { filter } from 'rxjs/operators'; I have editted my post with the filter showing the squiggly. – Sumchans May 17 '18 at 02:53
  • See my answer - at the point here you are filtering an array, not an rxjs observable so you need to do const filterData = data.filter(data => data.crew === 'FFM') – glendaviesnz May 17 '18 at 03:10
  • also, just be careful in the filter to make sure you use an == or === comparison rather than the = assignment operator as you have in your example – glendaviesnz May 17 '18 at 03:11

1 Answers1

16

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

glendaviesnz
  • 1,889
  • 14
  • 12
  • Forgot in the first example that if you want the final result to still be an array you will have to use the toArray operator after the filter - have added this in – glendaviesnz May 17 '18 at 03:19
  • That was really nice of you, thanks for the detailed explanation. I have editted my picture again. I have imported the operators this way import { filter, map } from 'rxjs/operators';. Not sure still I get that red line. Check the picture – Sumchans May 17 '18 at 03:27
  • see if .pipe(map((data: IWorkOrders[] ) => data.filter(workorder => workrder.crew === 'FFM') ) fixes it – glendaviesnz May 17 '18 at 03:34
  • you are using the filter option from array.prototype here, which has nothing to do with rxjs, so you don't need to import it - but there was no type annotation so no indication to IDE that this was an array so I suspect that was the reason for the squiggly – glendaviesnz May 17 '18 at 03:37
  • This worked for me; However, make sure you use the correct map. I initially imported the wrong one. You want: import { map } from rxjs/operators; – Nabsta Jan 10 '19 at 23:41