Sireini
Sireini

Reputation: 4262

Turn static array search into an observable search

I have an question I cant figure it out..

I have this function which works fine on my static array but now I want to turn this into a search in my obseravble.

This is my searchbar in home.html:

<ion-searchbar [(ngModel)]="searchKey" [formControl]="searchControl" (ionInput)="onInput($event)" (ionCancel)="onCancel($event)"></ion-searchbar>

And here is the home.ts:

export class HomePage {

   searchControl: FormControl;
   searching: any = false;
   restaurantsList: Observable<any[]>;

   constructor(){
       this.restaurantsList = this.restaurantService.getRestaurantList();
       this.searchControl = new FormControl();
   }      

   ionViewDidLoad(){
      this.searchControl.valueChanges.debounceTime(700).subscribe(search => {  
         this.searching = false;
         this.setFilteredItems();
     });
    }
    setFilteredItems(){
       this.restaurantService.filterRestaurants(this.searchKey).subscribe(
           foundRestaurant => this.restaurantsList = foundRestaurant
       )

       console.log(this.restaurantService.filterRestaurants(this.searchKey));
     }

     onInput(event) {
        this.searching = true;
     }

And this is the restaurant-service.ts:

export class RestaurantService {

  restaurantsRef: AngularFireList<any>;
  restaurantsList: Observable<any[]>;

  constructor(
      public afDb: AngularFireDatabase
  ) {
      this.restaurantsRef = afDb.list('/restaurants');
      this.restaurantsList = this.restaurantsRef.valueChanges();
  }

   getRestaurantList() {
      return this.restaurantsList;
   }

    filterRestaurants(searchKey: string) {
       let key: string = searchKey.toUpperCase();

       return this.restaurantsList.map(
           restaurantsList => restaurantsList.filter(
              restaurant => [
                restaurant.title.toUpperCase(),
                restaurant.address.toUpperCase(),
                restaurant.city.toUpperCase(),
                restaurant.description.toUpperCase()
            ].join(' ').indexOf(key) > -1)
       );
    }
}

But in the setFilteredItems() method the ide says on this.restaurantList: Type boolean is not assignable to type Observable<any[]>

Does anyone know the solution to change the restaurantList to the filteredItems?

FYI I followed this tutorial: LINK

Upvotes: 0

Views: 222

Answers (3)

Evgeniy Malyutin
Evgeniy Malyutin

Reputation: 1387

this.restaurantService.filterRestaurants returns an Observable and you're subscribing to it's result and inside subscribe method you're trying to assign the result to another Observable.

If you want to subscribe on observable's result and update the array of restauraunts then your restaurantsList should be an array:

class HomePage {
   restaurantsList: any[];

And all the code should work fine.

_______________________________________________

Or if you want to update your observable with a new observable then you should not do it in subscribe method

setFilteredItems(){
    this.restaurantsList = this.restaurantService.filterRestaurants(this.searchKey);
}

and then in html use async pipe to subscribe to this Observable and render the list of it's values (here I also use json pipe for debug)

{{restaurantsList | async | json}}

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136174

There seems to be syntactical mistake for me. Here is improvised version and correct searching check by key

filterRestaurants(searchKey: string) {
    //below line isn't needed at all.
    //this.restaurantsList.subscribe()
    let key: string = searchKey.toUpperCase();
    //returns Observable
    return this.restaurantsList.map(
       restaurantsList => {
         restaurantsList.filter(
           let result = restaurant => [
              restaurant.title.toUpperCase(),
              restaurant.address.toUpperCase(),
              restaurant.city.toUpperCase(),
              restaurant.description.toUpperCase()
           ].join(' ').indexOf(key) > -1
          );
          return Observable.of(result);
       }
    );
}

Upvotes: 0

bc1105
bc1105

Reputation: 1270

Look at the return of filterRestaurants, it's a boolean. You define the property of restaurantsList to be an Observable. You need to convert the result of filterRestaurants into an Observable.

import { Observable } from 'rxjs/Observable';

const filtered: Observable<boolean> = Observable.of( 
    this.restaurantService.filterRestaurants(this.searchKey)
);


filtered.subscribe(...);

Upvotes: 0

Related Questions