I am fairly new to angular and I am trying to create a filter for a value.
In my component - I have => myData$: Observable<MyInterface>
and the interface is as follows
export class FoundValues {
customerName: string;
startDate: string;
endDate: string;
includes(values: string) : boolean {
value = value.toLowerCase();
return this.valueIncludes(this.customerName, value);
}
private valueIncludes(includedValue, value){
if (value) {
const value = value.toLowerCase().includes(includedValue);
return result;
} else {
return false;
}
}
}
export interface MyInterface {
found_values : Array<FoundValues>;
}
In my component ngOnInit(), I am trying to create a logic filter but not getting it as it return a type FoundValues[] and it's complaining that it's not the expected Observable return type.
export class MyComponent implements OnInit{
myData$ = Observable<MyInterface>;
myControl = new FormControl();
ngOnInit(): void{
this.filterData =
this.myControl.valueChanges.pipe(map(value=>this._filter(value)));
}
private _filter(value:string): .....{
--- need logic here ----
}
}
How can I create the filter so that if I type a customer name in my form it shows only the matching customer name?
You can use the combineLatest RxJS operator for filtering through as shown in the following code snippet,
export class MyComponent implements OnInit {
myData$ = Observable < MyInterface > ;
mySearchQuery$: Observable < any > ;
searchString = new FormControl('');
filterData: Observable < any >
constructor() {
mySearchQuery$ = this.searchString.valueChanges.startsWith('');
}
ngOnInit(): void {
this.filterData = this.searchQuery$.combineLatest(this.myData$).map(([queryString, listOfCustomers]) => {
return listOfCustomers.filter(customer => customer.name.toLowerCase().indexOf(queryString.toLowerCase()) !== -1)
})
}
}
The combineLatest RxJS operator takes in the observables myData$ and mySearchQuery and returns the observable filterData containing the emitted values that match the searchString.
usual design in angular would be different
https://stackblitz.com/edit/angular7-rxjs-pgvqo5?file=src/app/app.component.ts
interface Entity {
name: string;
//...other properties
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = new FormControl('');
data$: Observable<Array<Entity>> = of([
{ name: 'Jhon' },
{ name: 'Jane' },
{ name: 'Apple' },
{ name: 'Cherry' },
]);
filtered$: Observable<Array<Entity>>;
ngOnInit() {
// this can be moved to a util lib/file
const startWithPipe = pipe(
map(
([query, data]: [query: string, data: Array<Entity>]): Array<Entity> =>
data.filter((entity) =>
query ? entity.name.toLowerCase().startsWith(query) : true
)
)
);
this.filtered$ = this.name.valueChanges.pipe(
startWith(''),
debounceTime<string>(300),
withLatestFrom(this.data$),
startWithPipe
);
}