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?
CodePudding user response:
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
.
CodePudding user response:
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
);
}