I am trying to create a drop-down list of customers (or anything), making use of Angular 5 Material's Autocomplete functionality. But unlike the examples provided on the Angular website, my data is not static, but gets returned after a data call getAllCustomer()
.
The problem I am having, seems to be the assigning of the filterOptions
before the data has been returned from my getAllCustomer()
method.
How can I make sure to only assign my filterOptions
after my data returns?
Here is my code:
filteredOptions: Observable<string[]>;
constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }
ngOnInit() {
this.getAllCustomers();
this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
startWith(''),
map(val => this.filter(val))
);
}
filter(val: string): string[] {
return this.customerArray.filter(option => option.toLowerCase().indexOf(val.toLowerCase()) === 0);
}
getAllCustomers() {
this.loadDataService.getAllCustomers()
.subscribe(data => {
this.customerArray = data;
});
}
This is my HTML:
<mat-form-field>
<input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
And as a bonus, how would I be able to implement the same, but with an actual search function that returns the data as a user types in the search box - i.e., a search by string method?
This is my searchByString
function:
searchForCustomerByString(string) {
this.loadDataService.getCustomer(string)
.subscribe(data => {
this.returnedCustomers = data;
});
}
You can define the variable in the result of the subscribe like this:
getAllCustomers() {
this.loadDataService.getAllCustomers()
.subscribe(data => {
this.customerArray = data;
this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
startWith(''),
map(val => this.filter(val))
);
});
}
But the variable filteredOptions might not be initialized so maybe you can use something like a BehaviorSubject to initialize the variable.