Trying to make Play Framework (REST) and ng-bootstrap - Typeahead
work together. But I'm facing a problem with extracting data from json
response. For example I write "test" (searches in database by name
), server returns json array(everything is right):
[{
"id": 1,
"name": "test",
"annotation": "test annotation",
"kiMin": 1,
"kiMax": 2,
"cosFiMin": 3,
"cosFiMax": 4
}, {
"id": 4,
"name": "test2",
"annotation": "test annotation",
"kiMin": 1,
"kiMax": 2,
"cosFiMin": 3,
"cosFiMax": 4
}]
But the view looks like this:
Here's my code:
http.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Equipment } from './equipment';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HttpService {
private Url = "http://localhost:9000/find?term="; // URL to web API
constructor (private http: Http) {}
search ( term :String ): Observable<Equipment[]> {
return this.http.get(this.Url+term)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError (error: Response | any) {
// In a real world app, we might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
ngb-typeahead-http.ts
import {Component} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {HttpService} from './http.service';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'ngb-typeahead-http',
templateUrl: './typeahead-http.html',
providers: [HttpService],
styles: [`.form-control { width: 300px; display: inline; }`]
})
export class NgbTypeaheadHttp {
model: any;
searching = false;
searchFailed = false;
constructor(private _service: HttpService) {}
search = (text$: Observable<string>) =>
text$
.debounceTime(300)
.distinctUntilChanged()
.do(() => this.searching = true)
.switchMap(term =>
this._service.search(term)
.do(() => this.searchFailed = false)
.catch(() => {
this.searchFailed = true;
return Observable.of([]);
}))
.do(() => this.searching = false);
}
typeahead-http.html
<div class="form-group" [class.has-danger]="searchFailed">
<input type="text" class="form-control" [(ngModel)]="model" [ngbTypeahead]="search" placeholder="search" />
<span *ngIf="searching">searching...</span>
<div class="form-control-feedback" *ngIf="searchFailed">Sorry, suggestions could not be loaded.</div>
</div>
How could I extract data from json object? Any suggestions, please.
When you're using objects with the typeahead you need to make use of the [inputFormatter] and [resultFormatter] inputs. For inputFormatter and resultFormatter you pass functions that take the object from your selection or results list and output the text value you want to display for that object.
Added function to component:
@Component({
selector: 'ngb-typeahead-http',
templateUrl: './typeahead-http.html',
providers: [HttpService],
styles: [`.form-control { width: 300px; display: inline; }`]
})
export class NgbTypeaheadHttp {
model: any;
searching = false;
searchFailed = false;
constructor(private _service: HttpService) {}
// Added
formatMatches = (value: any) => value.name || '';
search = (text$: Observable<string>) =>
text$
.debounceTime(300)
.distinctUntilChanged()
.do(() => this.searching = true)
.switchMap(term =>
this._service.search(term)
.do(() => this.searchFailed = false)
.catch(() => {
this.searchFailed = true;
return Observable.of([]);
}))
.do(() => this.searching = false);
}
Passing function to typeahead inputs
<div class="form-group" [class.has-danger]="searchFailed">
<input type="text" class="form-control"
[(ngModel)]="model" [ngbTypeahead]="search"
placeholder="search"
[resultFormatter]="formatMatches"
[inputFormatter]="formatMatches" />
<span *ngIf="searching">searching...</span>
<div class="form-control-feedback" *ngIf="searchFailed">Sorry, suggestions could not be loaded.</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With