Angular Autocomplete Input Provider
This challenge focuses on building a core component of a user-friendly interface: an autocomplete or suggestion input. You will create a reusable Angular service that acts as a "completion provider," responsible for fetching and filtering potential suggestions based on user input. This is a fundamental pattern for improving search functionality, form filling, and overall user experience.
Problem Description
Your task is to design and implement an Angular service, AutocompleteProvider, that will handle the logic for providing suggestions to an input field. This service should accept a search term and return a list of matching suggestions from a predefined dataset.
Key Requirements:
- Service-Based Logic: The suggestion logic should be encapsulated within an Angular service. This promotes reusability and separation of concerns.
- Data Source: The service should operate on a static, predefined array of suggestion strings. In a real-world application, this would typically come from an API, but for this challenge, a hardcoded array is sufficient.
- Fuzzy Matching/Filtering: Implement a filtering mechanism that returns suggestions that "contain" or "start with" the user's input. A case-insensitive comparison is expected.
- Asynchronous Behavior (Simulated): While the data source is static, the service should simulate asynchronous data fetching. This means returning an
Observableof suggestions, even if the data is immediately available. This prepares the service for real-world scenarios where data is fetched from an API. - Debouncing (Optional but Recommended): Consider how to prevent excessive filtering calls as the user types. Implementing a debounce mechanism within the service or in conjunction with the component using it would be a valuable addition.
Expected Behavior:
When a user types into an input field, the component using this service will call a method on the AutocompleteProvider with the current input value. The service will then filter its internal dataset and return an Observable emitting an array of matching strings. The component will subscribe to this observable and display the suggestions.
Edge Cases:
- Empty Input: What happens when the user clears the input field? The service should return an empty array.
- No Matches: What happens if the input term doesn't match any suggestions? The service should return an empty array.
- Case Sensitivity: The filtering should be case-insensitive.
- Partial Matches: The filtering should handle partial matches effectively (e.g., typing "app" should match "Apple", "Application", "Pineapple").
Examples
Example 1:
- Input:
searchTerm: "app"suggestionsDataset:["Apple", "Banana", "Application", "Apricot", "Pineapple"]
- Output: An observable that emits
["Apple", "Application", "Apricot"]. - Explanation: The service filters the dataset to find strings that contain "app" (case-insensitive). "Apple", "Application", and "Apricot" match. "Banana" and "Pineapple" do not.
Example 2:
- Input:
searchTerm: "oran"suggestionsDataset:["Apple", "Banana", "Orange", "Grape", "Watermelon"]
- Output: An observable that emits
["Orange"]. - Explanation: Only "Orange" contains the substring "oran" (case-insensitive).
Example 3:
- Input:
searchTerm: "" (empty string)suggestionsDataset:["Apple", "Banana", "Orange"]
- Output: An observable that emits
[](an empty array). - Explanation: When the search term is empty, no suggestions should be returned.
Constraints
- The
suggestionsDatasetwill contain a maximum of 1000 strings. - Each string in the
suggestionsDatasetwill have a maximum length of 50 characters. - The
searchTermwill have a maximum length of 50 characters. - The filtering logic should aim for reasonable performance, completing within milliseconds for typical datasets and search terms.
Notes
- Consider using RxJS operators like
filter,map, and potentiallydebounceTimeanddistinctUntilChangedfor an efficient and reactive solution. - The service should be designed to be injected into Angular components.
- Think about how you would handle a scenario where the
suggestionsDatasetis dynamically loaded from an API. Your service design should accommodate this future extension.