Implement duck search by color

This is a very rough thing. In the final version it should provide
resilts with similar colors.

Signed-off-by: Gergely Polonkai <gergely@polonkai.eu>
This commit is contained in:
Gergely Polonkai 2016-09-07 08:21:52 +02:00
parent 267b229e13
commit bfcabd7925
6 changed files with 86 additions and 0 deletions

View File

@ -1,3 +1,5 @@
import "./rxjs-extensions";
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
@ -12,6 +14,7 @@ import { AppComponent } from "./app.component";
import { DucksComponent } from "./ducks.component";
import { DuckDetailComponent } from "./duck-detail.component";
import { DashboardComponent } from "./dashboard.component";
import { DuckSearchComponent } from "./duck-search.component";
import { DuckService } from "./duck.service";
@ -27,6 +30,7 @@ import { DuckService } from "./duck.service";
AppComponent,
DucksComponent,
DuckDetailComponent,
DuckSearchComponent,
DashboardComponent
],
providers: [ DuckService ],

View File

@ -1,3 +1,4 @@
<div *ngFor="let duck of ducks" (click)="gotoDetail(duck)">
{{ duck.color }}
</div>
<duck-search></duck-search>

View File

@ -0,0 +1,11 @@
<div id="search-component">
<h4>Duck search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)">
<div>
<div *ngFor="let duck of ducks | async"
(click)="gotoDetail(duck)"
class="search-result">
{{ duck.color }}
</div>
</div>
</div>

View File

@ -0,0 +1,43 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { DuckSearchService } from "./duck-search.service";
import { Duck } from "./models";
@Component({
selector: "duck-search",
templateUrl: "/app/duck-search.component.html",
providers: [ DuckSearchService ]
})
export class DuckSearchComponent implements OnInit {
ducks: Observable<Duck[]>;
private searchTerm = new Subject<string>();
constructor(private duckSearchService: DuckSearchService,
private router: Router)
{}
search(term: string): void {
this.searchTerm.next(term);
}
ngOnInit(): void {
this.ducks = this.searchTerm
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
? this.duckSearchService.search(term)
: Observable.of<Duck[]>([]))
.catch(error => {
console.log(error);
return Observable.of<Duck[]>([]);
});
}
gotoDetail(duck: Duck): void {
let link = ['/detail', duck.id];
this.router.navigate(link);
}
}

View File

@ -0,0 +1,15 @@
import { Injectable } from "@angular/core";
import { Http, Response } from "@angular/http";
import { Observable } from "rxjs";
import { Duck } from "./models";
@Injectable()
export class DuckSearchService {
constructor (private http: Http) {}
search(term: string): Observable<Duck[]> {
return this.http.get(`app/ducks/?color=${term}`)
.map((r: Response) => r.json().data as Duck[]);
}
}

12
app/rxjs-extensions.ts Normal file
View File

@ -0,0 +1,12 @@
// Observable class extensions
import "rxjs/add/observable/of";
import "rxjs/add/observable/throw";
// Observable operators
import "rxjs/add/operator/catch";
import "rxjs/add/operator/debounceTime";
import "rxjs/add/operator/distinctUntilChanged";
import "rxjs/add/operator/do";
import "rxjs/add/operator/filter";
import "rxjs/add/operator/map";
import "rxjs/add/operator/switchMap";