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. Does anyone have an idea what I did wrong in 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}`);
}
}