Currently, I am working on an autocomplete feature that dynamically filters a list of meals based on the user's input:
export class MealAutocompleteComponent {
mealCtrl = new FormControl()
filteredMeals: Observable<Array<Meal>>
liveMeals$: Observable<Array<Meal>>
mealsSnapshot: Meal[]
constructor(private mealsQuery: MealsQuery) {
this.liveMeals$ = this.mealsQuery.all$ // <= observable (not used)
this.mealsSnapshot= this.mealsQuery.getAll() // <= array (used)
// Observing user input and triggering filtering process
this.filteredMeals = this.mealCtrl.valueChanges.pipe(
startWith(null),
map((filterTerm: string | null) => {
let mealArr: Array<Meal> = mealsQuery.getAll() // <= Using observable instead
return filterTerm ? this._filter(filterTerm, mealArr) : mealArr
})
)
}
private _filter(value: string, meals:Array<Meal>): Array<Meal> {
// Filtering method for meals
const filterValue = value.toLowerCase()
return meals.filter(meal =>
meal.label.toLowerCase().indexOf(filterValue) === 0
)
}
}
What is the correct approach to transition from using meals:Array to meals:Observable?
The current code functions as intended. However, there are two sources to retrieve the complete list of meals
- an array this.mealsSnapshot
and an observable: this.liveMeals
.
In the provided code snippet, the mealsSnapshot
array is utilized. But ideally, I would like to leverage the flexibility offered by the liveMeals$
observable, derived from a state store. Unfortunately, I am unsure about the appropriate RxJS operators required for this transition. The liveMeals$
observable returns a singular array of meals.
I attempted the following implementation but encountered issues with nested subscriptions which go against reactive programming guidelines, resulting in inefficient and messy code.
this.filteredMeals = this.mealCtrl.valueChanges.pipe(
startWith(null),
concatMap((filterTerm: string | null) => {
this.liveMeals$.pipe(
first()
).subscribe((mealsArr:Meal) => {
return filterTerm ? this._filter(filterTerm, mealsArr) : mealsArr
}
)
})
)
Could you provide insights into effectively utilizing
liveMeals$:Observable<Array>
instead of relying on mealsSnapshot
?