Can someone post me an example of how to do a typeahead with a REST service as source in Typescript? Do I need to use a promise or can I use observables? Specifically I am looking for what I need in the getAsyncData() function from the example here: http://valor-software.com/ng2-bootstrap/
Rest Response:
[{id: 1, name: 'Alabama'}, {id: 2, name: 'Alaska'}, {id: 3, name: 'Arizona'},{id: 4, name: 'Arkansas'}, {id: 5, name: 'California'}]
What I have (doesn't work):
public getAsyncData(context:any):Function {
if (this._prevContext === context) {
return this._cache;
}
this._prevContext = context;
let f:Function = function (http:Http) {
let searchParams = new URLSearchParams();
searchParams.set('search', context.asyncSelected);
http.get('http://mydomain.com/search', {search: searchParams})
.subscribe(res => {
context.companies = res.json();
});
};
this._cache = f(this.http);
return this._cache;
}
Everything else is like in the example here: http://valor-software.com/ng2-bootstrap/
Any help is greatly appreciated. Thank you.
I had the same question yesterday and here's how I solved it.
In the template, notice the change to the [typeahead] function reference. This is to ensure that Angular does not trigger the call to this function on each change detection:
<input class="form-control"
type="text"
[(ngModel)]="arrivalLocation"
[typeahead]="autoCompleteRef"
[typeaheadOptionField]="'name'"
[typeaheadWaitMs]="100"
[typeaheadMinLength]="3">
Then in my component's class, I declare this reference and bind it to my component:
public autoCompleteRef = this.autoComplete.bind(this);
Finally, the method using Observables:
public autocomplete() {
return this.http.get(`[...what you need to get...]`)
.map(r=>r.json())
.map( [...other mapping you may need... ] )
.toPromise();
}
Note: I had to use something like this to match as my other mapping to match the format expected:
.map( (el)=>{return el.map((data)=>{return({id:data.value,name:data.label});})
Hope this helps!
For me, it does not work :(
can you help me ?
I get an error: EXCEPTION: TypeError: _this.typeahead(...) is undefined
My Component:
public autoRef = this.getVehicleInformation.bind(this);
public getVehicleInformation(): any {
return this.vehicleService.getVehicleInformation(this.vehicleInformation).toPromise;
}
Markup:
<input id="vehicle" placeholder="Example: All New Honda Civic" class="form-control" autocomplete="off" [(ngModel)]="vehicleInformation" [typeahead]="autoRef" [typeaheadOptionField]="'value'" [typeaheadWaitMs]="100" [typeaheadMinLength]="2"
(typeaheadLoading)="changeVehicleInfoLoading($event)"
(typeaheadNoResults)="changeVehicleInfoNoResults($event)"
(typeaheadOnSelect)="onSelectVehicleInfo($event)" >
According with last source code, promise don't work with typeahead anymore. Only Observable.
Example:
<input class="form-control" [(ngModel)]="selectedNumber" [typeahead]="filteredNumbers$" (typeaheadNoResults)="setInvalidNumber($event)" (typeaheadOnSelect)="showNumber($event.item)" [typeaheadOptionsLimit]="10" [typeaheadWaitMs]="500">
filteredNumbers$: Observable<string[]>;
invalidNumber: boolean = false;
selectedNumber: string = '';
ngOnInit(): void {
this.filteredNumbers$ = Observable.create((observer: Observer<string>) => observer.next(this.selectedNumber)).mergeMap((number: string) => ...);
}
setInvalidNumber(invalidNumber: boolean): void {
...
}
showNumber(number: string): void {
...
}
Hello @Martin-Wegner ,
The above code will produce options.slice is not a function exception.
There is some sort of issue with typeahead binding to the result that comes from the server.
Is it possible that you provide an example where typeahead is getting the data from real service (not hard-coded array that exists in the component or a static json file on the server)?
I think type ahead has a similar issue as it used to have during Angular RC4 where there is a problem with binding to data that comes from the service.
Thank you for your time
@binarydigits
Example:
<input [(ngModel)]="selectedNumber" [typeahead]="filteredNumbers$" (typeaheadNoResults)="setInvalidNumber($event)" (typeaheadOnSelect)="showNumber($event.item)" [typeaheadOptionsLimit]="10" [typeaheadWaitMs]="500">
filteredNumbers$: Observable<string[]>;
invalidNumber: boolean = false;
selectedNumber: string = '';
constructor(private yourRestService: YourRestService) {}
ngOnInit(): void {
this.filteredNumbers$ = Observable.create((observer: Observer<string>) => observer.next(this.selectedNumber))
.mergeMap((number: string) => this.yourRestService.getNumbersStartsWith(countingPointNumber));
}
setInvalidNumber(invalidNumber: boolean): void {
...
}
showNumber(number: string): void {
...
}
Hi everyone,
The type ahead works as specified in documentation with the latest upgrade of angular to 2.3 and ng2-bootstrap to 1.1.16-9.
Thank you so much for the effort to develop ng2-bootstrap!
Most helpful comment
I had the same question yesterday and here's how I solved it.
In the template, notice the change to the [typeahead] function reference. This is to ensure that Angular does not trigger the call to this function on each change detection:
Then in my component's class, I declare this reference and bind it to my component:
Finally, the method using Observables:
Note: I had to use something like this to match as my other mapping to match the format expected:
Hope this helps!