I have been trying to pass a callback function down to my app-autocomplete
component using the displayFn
input parameter:
<app-autocomplete [displayFn]="displayWith" formControlName="starter">
</app-autocomplete>
The parent component simply implements this:
displayWith(item) {
return item ? item.name : null;
}
Within the app-autocomplete
component, there is a mat-autocomplete
element where the [displayWith]
function is wrapped by onSelectEvent
:
<mat-autocomplete [displayWith]="onSelectEvent" #autocomplete="matAutocomplete">
</mat-autocomplete>
The purpose of onSelectEvent
is to save the selected option and then call the provided displayFn
function:
onSelectEvent(option) {
this.selectedOption = option;
return this.displayFn(option);
}
However, I am encountering an error:
ERROR TypeError: this.displayFn is not a function
I am puzzled about why this error is occurring. How does my approach differ from that in this answer?
The same error occurs with the following code snippet:
onSelectEvent = (option) => {
this.selectedOption = option;
return this.displayFn(option);
}
Below is the complete component code:
@Component({
selector: 'app-autocomplete',
styles: [`
`],
template: `
<div class="app-autocomplete">
<mat-form-field>
<input #autocompleteInput matInput
[placeholder]="placeholder" autocomplete="off" [matAutocomplete]="autocomplete"/>
</mat-form-field>
<button mat-icon-button type="button" [disabled]="disabled">
<mat-icon>clear</mat-icon>
</button>
<mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="onSelectEvent" autoActiveFirstOption>
<mat-option *ngFor="let option of filteredOptions$ | async" [value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AutocompleteComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AutocompleteComponent),
multi: true,
}]
})
export class AutocompleteComponent implements OnInit, ControlValueAccessor, Validator {
@ViewChild('autocompleteInput')
autocompleteInput: ElementRef;
@Input()
options = [];
@Input()
placeholder;
@Input()
displayFn: (value: any) => string;
disabled;
selectedOption;
filteredOptions$;
_onChangeCallback = (value: any) => {};
_onTouchedCallback = () => {};
ngOnInit() {
this.filteredOptions$ = of(this.options);
}
filterOptions(v) {
}
writeValue(obj: any): void {
this.autocompleteInput.nativeElement.value = obj.value;
}
registerOnChange(fn: any): void {
this._onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
this._onTouchedCallback = fn;
}
setDisabledState(isDisabled: boolean): void {
}
validate(c: AbstractControl): ValidationErrors | any {
return undefined;
}
onSelectEvent = (option) => {
this.selectedOption = option;
return this.displayFn(option);
}
}