Quantcast
Channel: Ionic Framework - Ionic Forum
Viewing all articles
Browse latest Browse all 49235

List Filtering with Observables (Real Time Search)

$
0
0

@ThomasLohmann wrote:

Hi everyone!

I’m trying to filter a list with an observable (Subject). I want to reach a real time search. But if I write something in the search box, e.g. the id of a list item as I declacred in my Http-Service (search Method), nothing happen. Do you have any idea what I did wrong in my code? Below is my code.

Please note: The “C” in my code stands for “Consumer”

I would be glad about the simplest solution.

Kind regards,
Thomas

Component.ts

import { Component, OnInit } from '@angular/core';
import { NavController, NavParams, PopoverController } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { debounceTime, distinctUntilChanged, switchMap} from 'rxjs/operators';

import { CVideoAddPage } from '../c-video-add/c-video-add';
import { CVideoDetailPage } from '../c-video-detail/c-video-detail';
import { MoreContentPage } from '../../../more/content/more-content';
import { CVideoModel } from '../c-video.model';
import { CVideoHttp } from '../c-video.http';

@Component({
    selector: 'c-video-list',
    templateUrl: 'c-video-list.html',
})

export class CVideoListPage implements OnInit {

    videos: Observable<CVideoModel[ ]>;

    private searchTerms = new Subject<string>();

    constructor(public navCtrl: NavController, public navParams: NavParams, public popoverCtrl: PopoverController, private cVideoHttp: CVideoHttp) {

    }

    ngOnInit(): void {
        this.videos = this.cVideoHttp.getVideos();

        this.searchTerms.pipe(
            // wait 300ms after each keystroke before considering the term
            debounceTime(300),
            // ignore new term if same as previous term
            distinctUntilChanged(),
            // switch to new search observable each time the term changes
            switchMap((term: string) => this.cVideoHttp.searchVideo(term)),
        );

    }

    // Push a search term into the observable stream.
    searchVideo(term: string): void {
        this.searchTerms.next(term);
    }

    addVideo() {
        this.navCtrl.push(CVideoAddPage);
    }

    videoDetail(video) {
        this.navCtrl.push(CVideoDetailPage, video);
    }

    more(more) {
        let popover = this.popoverCtrl.create(MoreContentPage);
        popover.present({ev: more});
    }

}

Component.html

<ion-header #head>
    <c-itoolbar></c-itoolbar>
</ion-header>

<ion-content header-hide fab-hide [header]="head">

    <ion-card>
        <ion-toolbar color="white">
            <ion-searchbar placeholder="Videos (10)" #searchBox (keyup)="searchVideo(searchBox.value)"></ion-searchbar>
            <ion-buttons end>
                <button ion-button icon-only color="dark">
                    <ion-icon name="square"></ion-icon>
                </button>
            </ion-buttons>
            <ion-buttons end>
                <button ion-button icon-only color="dark">
                    <ion-icon name="options"></ion-icon>
                </button>
            </ion-buttons>
        </ion-toolbar>
    </ion-card>

    <ion-card *ngFor="let video of videos | async" (click)="videoDetail(video)">
        <button ion-item>
            <ion-thumbnail item-start>
                <img [src]="video.url">
            </ion-thumbnail>
            <h2 ion-text text-wrap color="black" class="text-bolder">{{video.id}} {{video.title}}</h2>
            <p>{{video.publisher}}</p>
            <p text-wrap>
                <ion-icon name="eye"></ion-icon>
                {{video.views | number}} •
                 <ion-icon name="thumbs-up"></ion-icon>
                 {{video.likes | percent}} •
                 <ion-icon name="time"></ion-icon>
                 {{myDate | amTimeAgo: true}}
             </p>
            <button ion-button small clear icon-only item-end (click) ="more()">
                <ion-icon name="more" color="dark"></ion-icon>
            </button>
        </button>
        <button ion-button full color="red" (click)="delete(video)">Delete</button>
    </ion-card>

    <ion-fab right bottom #fab>
        <button ion-fab color="primary" (click)="addVideo()">
            <ion-icon name="videocam"></ion-icon>
        </button>
    </ion-fab>

</ion-content>

Http-Service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

import { CVideoModel } from './c-video.model';

@Injectable()

export class CVideoHttp {

  private videosUrl: any = "http://my-json-server.typicode.com/thomaslohmann/jsonserver/videos";

  constructor(private http: HttpClient) {

  }

  getVideos (): Observable<CVideoModel[]> {
      return this.http.get<CVideoModel[]>(this.videosUrl);
  }

  getVideo (id: number): Observable<CVideoModel> {
      return this.http.get<CVideoModel>(`${this.videosUrl}/${id}`);
  }

  addVideo (VideoModel: CVideoModel): Observable<CVideoModel> {
      return this.http.post<CVideoModel>(this.videosUrl, CVideoModel);
  }

  updateVideo (CVideoModel: CVideoModel ): Observable<CVideoModel> {
      return this.http.put<CVideoModel>(`${this.videosUrl}/${CVideoModel.id}`, CVideoModel);
  }

  deleteVideo(CVideoModel: CVideoModel): Observable<CVideoModel> {
      return this.http.delete<CVideoModel>(`${this.videosUrl}/${CVideoModel.id}`);
}

  searchVideo(term: string): Observable<CVideoModel[]> {
      if (!term.trim()) {
          // if not search term, return empty array.
          return of([]);
      }
      return this.http.get<CVideoModel[]>(`http://my-json-server.typicode.com/thomaslohmann/jsonserver/videos/?id=${term}`);
  }

}

Posts: 1

Participants: 1

Read full topic


Viewing all articles
Browse latest Browse all 49235

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>