Reputation: 979
I tried to use auto-complete from an API but it did not work. its works only when I use it with no API as hardcoded.
this is my Component TS: inside there, There is a callback method with the data from the API (onGetTaxList)
import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../../../core/services/users.service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
@Component({
selector: 'app-create-process-modal',
templateUrl: './create-process-modal.component.html',
styleUrls: ['./create-process-modal.component.sass']
})
export class CreateProcessComponent implements OnInit {
myControl = new FormControl();
options = [
{ name: 'One' },
{ name: 'Two' },
{ name: 'Tree' },
];
filteredOptions: Observable<any>;
constructor(private service: UsersService) { }
ngOnInit() {
this.service.createNewProcess((data) => this.onGetTaxList(data));
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
map(value => this._filter(value))
);
}
onGetTaxList(data) {
console.log(data);
}
private _filter(value: string) {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().includes(filterValue));
}
}
Component html:
<div class="formContainer">
<h2 style="text-align: right">New Process</h2>
<mat-form-field style="text-align: right">
<input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
In this state its work with the object
options = [
{ name: 'One' },
{ name: 'Two' },
{ name: 'Tree' },
];
and now i want to make it works from the data api:
0: {companyName: "ziro", cid: "524023240", partners: Array(4)}
1: {companyName: "plus", cid: "524023240", partners: Array(2)}
and I need the autocomplete will filter the companyName. Thanks.
Upvotes: 23
Views: 44303
Reputation: 5264
html
<input class="hscode-box" placeholder=" Select HS Code" type="text" matInput [formControl]="hscodeControl"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of hscodeOptions | async" [value]="option.code">
{{option.code}}
</mat-option>
</mat-autocomplete>
.ts
ngOnInit() {
this.hscodeOptions = this.hscodeControl.valueChanges.pipe(
startWith(''),
debounceTime(500),
switchMap((value) => {
console.log(value, "value");
return this.hscodes(value);
}),
);
hscodes(hscode) {
return this._ProductService.getHSCodeList(hscode).pipe(
filter(data => !!data),
map((data) => {
return data
})
)
}
Upvotes: 0
Reputation: 773
the best way from call data whit out charge all data but partial data on server side: the call start from first letter
Component no Async
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions" [value]="option.name">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
.ts File
ngOnInit() {
this.myControl.valueChanges
.subscribe(value => {
if(value.length >= 1){
this.dashboardService.getProductsByName(value).subscribe(response => {
this.filteredOptions = response;
});
}
else {
return null;
}
})
}
Upvotes: 6
Reputation: 535
constructor(private service: Service) {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
debounceTime(400),
distinctUntilChanged(),
switchMap(val => {
return this.filter(val || '')
})
);
}
// filter and return the values
filter(val: string): Observable<any[]> {
// call the service which makes the http-request
return this.service.getData()
.pipe(
map(response => response.filter(option => {
return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
}))
)
}
}
opts = [];
getData() {
return this.opts.length ?
of(this.opts) :
this.http.get<any>('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
}
For check full demo check this link Stackblitz
Upvotes: 22
Reputation: 73337
I see no attempt to even get the data from Api, so first of all you should add that. Then you are trying to filter by name
, which does not exist in your data, you want to filter by companyName
, then use that. All in all, change your code to:
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
switchMap(value => this._filter(value))
);
And the function to filter and getting the data from api:
private _filter(value: string) {
const filterValue = value.toLowerCase();
// add your service function here
return this.service.getData().pipe(
filter(data => !!data),
map((data) => {
return data.filter(option => option.companyName.toLowerCase().includes(value))
})
)
}
DEMO: StackBlitz
Upvotes: 3
Reputation: 94
on your ngOnInit try to add this:
ngOnInit() {
.
..
...
this.options = []; //init the options data.
this.yourService.getAllCompaniesOrSomething.subscribe((all_companies)=>{
this.options = all_companies.map((company)=>{
return {
name:company.companyName
}
});//closing the map function.
});//closing the subscription.
}
Upvotes: 1
Reputation: 979
Solved:
import { Component, OnInit } from '@angular/core';
import { UsersService } from '../../../../core/services/users.service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { MatAutocompleteSelectedEvent } from '@angular/material';
@Component({
selector: 'app-create-process-modal',
templateUrl: './create-process-modal.component.html',
styleUrls: ['./create-process-modal.component.sass']
})
export class CreateProcessComponent implements OnInit {
myControl = new FormControl();
options;
filteredOptions: Observable<any>;
constructor(private service: UsersService) { }
ngOnInit() {
this.service.createNewProcess((data) => this.onGetTaxList(data));
}
// Auth Complete
onGetTaxList(data) {
this.options = data;
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
map(value => value.length >= 1 ? this._filter(value) : [])
);
}
private _filter(value: string) {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.companyName.toLowerCase().includes(filterValue));
}
}
Html:
<div class="formContainer">
<h2 style="text-align: right">New Process</h2>
<mat-form-field style="text-align: right">
<input type="text" placeholder="Start Typing..." matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option.companyName">
{{option.companyName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
Upvotes: 0