I'm having the exact same problem right now.
When the typeahead is used with the Angular Form API, it uses the value found for the key passed in typeaheadOptionField
. This is imho a bug or at least it should be configurable.
What I'm doing now is wrapping the input with a custom control and using the Output typeaheadOnSelect
which is called when an option of the typeahead is selected. Within the event data you can find the entire object. But you have to handle the control data management by yourself.
At least for now, I couldn't find another solution.
Edit:
Here's my code (removed all abstractions, no warranty that it works):
@Component({
selector: 'my-typeahead-control',
templateUrl: './my-typeahead-control.html',
providers: [
{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyTypeaheadControl), multi: true}
]
})
export class MyTypeaheadControl implements ControlValueAccessor
{
// -- -- -- -- -- -- -- -- -- -- typeahead data -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
@Input()
public items:any[] | Observable<any[]> = [];
@Input()
public itemLabelKey:string;
// -- -- -- -- -- -- -- -- -- -- internal data -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public selectedItemLabel:string;
// -- -- -- -- -- -- -- -- -- -- interface implementation -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public writeValue(obj:any):void
{
this.updateSelectedItemLabel(obj);
}
private onChange:Function;
public registerOnChange(fn:any):void
{
this.onChange = fn;
}
private onTouch:Function;
public registerOnTouched(fn:any):void
{
this.onTouch = fn;
}
public setDisabledState(isDisabled:boolean):void
{
// ...
}
// -- -- -- -- -- -- -- -- -- -- control data handling -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
public onSelect(event:TypeaheadMatch):void
{
this.onTouch();
this.onChange(event.item);
this.updateSelectedItemLabel(event.item);
}
private updateSelectedItemLabel(obj:any):void
{
this.selectedItemLabel = (this.itemLabelKey) ? _.get(obj, this.itemLabelKey) : obj;
}
}
And the template:
<input [ngModel]="selectedItemLabel"
[typeahead]="items"
[typeaheadOptionField]="itemLabelKey"
[typeaheadMinLength]="0"
[container]="'body'"
(typeaheadOnSelect)="onSelect($event)">
Now it can be used as follows:
<my-typeahead-control formControlName="item" [items]="allItemsArray" itemLabelKey="name"></my-typeahead-control>