Marcos
Marcos

Reputation: 231

Angular 4 rxjs: Filter data in observable array

I have an Observable of an array:

schools: Observable<SchoolVM[]>;

And I need to filter this observable into another for an Autocomplete select

filteredSchools: Observable<SchoolVM[]>;

I subscribe to the form.valueChanges

this.formChange = this.searchForm.valueChanges
  .debounceTime(300)
  .subscribe( value => {
    this.filteredSchools = this.schools.filter(s => s.SchoolName == value);
  });

I have an error: Property 'SchoolName' does not exist on type 'SchoolVM[]' How can I solve it? And also: I have to filter by 2 different criteria. It is correct to filter like

this.filteredSchools = this.schools.filter(s => s.SchoolName == value || 
    s => s.SchoolName == value);

I rewrote the function following Aakash Jain's answer, like that:

this.formChange = this.searchForm.valueChanges
      .debounceTime(300)
      .subscribe( value => {
        this.filteredSchools = this.schools.map(schools => {
          return schools.filter((school: SchoolVM) => (school.SchoolName === value) || (school.City === value));
          // this.logger.info(this.filteredSchools);
        });
      });

and now I get the error "schools.filter" is not a function.

The observable

schools: Observable<SchoolVM[]>;

is filled from an httpClient call:

this.schoolService.filterSchools(arg)
      .subscribe(d => {this.schoolsToFilter = d; })

And in the service:

filterSchools(arg: string): Observable<any> {
    return Observable.from(this.http.get('/api/school/find/' + arg));

Maybe their is a problem with Observable, but the schools observable is well filled:

{ "SchoolID": 13028, "SchoolName": "100% Conduite", "City": "MEUDON", "ZipCode": "92190", "Street": "17 rue des Gallons", "Phone": "01 49 66 06 02" }, { "SchoolID": 6803, "SchoolName": "100% PERMIS", "City": "BADONVILLER", "ZipCode": "54540", "Street": "25 rue du Maréchal Foch", "Phone": "" },...

Upvotes: 0

Views: 3145

Answers (1)

Aakash Jain
Aakash Jain

Reputation: 1973

schools and filteredSchools are Observables that each contain an array of SchoolVM objects.

So when you do this:

this.schools.subscribe(s => console.log(s));

You will find that an array of SchoolVM gets printed. So the value of s above is not a single SchoolVM but instead an SchoolVM[].

As such, when you write:

this.filteredSchools = this.schools.filter(s => s.SchoolName == value);
// this will not work since s is an array

Instead, what you want to do is:

this.filteredSchools = this.schools.map(schools => {
    return schools.filter((school: SchoolVM) => school.SchoolName === value);
});

To filter by two conditions, your way is incorrect. What you are doing is defining two anonymous functions. This will give you a syntax error. Instead you want one anonymous function with the OR condition.

this.filteredSchools = this.schools.map(schools => {
    return schools.filter((school: SchoolVM) => (school.SchoolName === value) || (school.NumberOfStudents >= 100));
});

Upvotes: 2

Related Questions