Skip to content

Commit 5d02674

Browse files
committed
Updated README.md
1 parent ef90ccc commit 5d02674

2 files changed

Lines changed: 176 additions & 118 deletions

File tree

README.md

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -227,24 +227,32 @@ export class CustomDataSource<T> implements SelectDataSource<T> {
227227

228228
The `MerSelect` supports typeahead functionality, allowing you to search for options as you type. The library provides a generic `TypeaheadDataSource` implementation that handles common typeahead requirements including search request cancellation, loading states, and result management.
229229

230+
### TypeaheadSearchFn Type
231+
232+
A simple function type that can be used to perform typeahead searches:
233+
234+
```typescript
235+
export type TypeaheadSearchFn<T> = (query: string) => Observable<T[]>;
236+
```
237+
230238
### TypeaheadSearchService Interface
231239

232-
First, implement the `TypeaheadSearchService` interface to define how search operations will be performed:
240+
Alternatively, you can implement the `TypeaheadSearchService` interface to define how search operations will be performed:
233241

234242
```typescript
235243
export interface TypeaheadSearchService<T> {
236-
/**
237-
* Search method that takes a query string and returns an Observable of results
238-
* @param query The search query string
239-
* @returns Observable of search results
240-
*/
241-
search(query: string): Observable<T[]>;
244+
/**
245+
* Search method that takes a query string and returns an Observable of results
246+
* @param query The search query string
247+
* @returns Observable of search results
248+
*/
249+
search(query: string): Observable<T[]>;
242250
}
243251
```
244252

245253
### TypeaheadDataSourceOptions Interface
246254

247-
The `TypeaheadDataSource` now accepts a configuration options object:
255+
The `TypeaheadDataSource` accepts a configuration options object:
248256

249257
```typescript
250258
export interface TypeaheadDataSourceOptions<T> {
@@ -273,6 +281,65 @@ The `TypeaheadDataSource` provides a robust solution for typeahead functionality
273281

274282
#### Implementation
275283

284+
You can implement typeahead functionality in two ways:
285+
286+
##### 1. Using a Simple Search Function
287+
288+
```typescript
289+
import { Injectable } from '@angular/core';
290+
import { Observable, of } from 'rxjs';
291+
import { delay } from 'rxjs/operators';
292+
import { HttpClient } from '@angular/common/http';
293+
import { TypeaheadDataSource, TypeaheadDataSourceOptions } from '@merelis/angular/select';
294+
295+
// Define your data model
296+
interface User {
297+
id: number;
298+
name: string;
299+
email: string;
300+
}
301+
302+
@Component({
303+
selector: 'app-user-search',
304+
standalone: true,
305+
imports: [MerSelect],
306+
template: `
307+
<mer-select
308+
[(value)]="selectedUser"
309+
[dataSource]="userDataSource"
310+
[displayWith]="displayUserName"
311+
[placeholder]="'Search for users...'">
312+
</mer-select>
313+
`
314+
})
315+
export class UserSearchComponent implements OnDestroy {
316+
selectedUser: User | null = null;
317+
userDataSource: TypeaheadDataSource<User>;
318+
319+
constructor(private http: HttpClient) {
320+
// Define a search function that returns an Observable
321+
const searchFn = (query: string): Observable<User[]> => {
322+
return this.http.get<User[]>(`/api/users?q=${query}`);
323+
};
324+
325+
// Define options for the data source
326+
const options: TypeaheadDataSourceOptions<User> = {
327+
compareWith: (a, b) => a.id === b.id
328+
};
329+
330+
// Create the data source with the search function and options
331+
this.userDataSource = new TypeaheadDataSource<User>(searchFn, options);
332+
}
333+
334+
// Display function for the select component
335+
displayUserName(user: User): string {
336+
return user?.name || '';
337+
}
338+
}
339+
```
340+
341+
##### 2. Using a TypeaheadSearchService
342+
276343
```typescript
277344
import { Injectable } from '@angular/core';
278345
import { Observable, of } from 'rxjs';
@@ -295,32 +362,8 @@ export class UserSearchService implements TypeaheadSearchService<User> {
295362
search(query: string): Observable<User[]> {
296363
// Real implementation would use HttpClient
297364
return this.http.get<User[]>(`/api/users?q=${query}`);
298-
299-
// Example of a mock implementation for testing:
300-
/*
301-
const users = [
302-
{ id: 1, name: 'John Smith', email: 'john@example.com' },
303-
{ id: 2, name: 'Mary Johnson', email: 'mary@example.com' },
304-
{ id: 3, name: 'Peter Williams', email: 'peter@example.com' }
305-
];
306-
307-
const results = query
308-
? users.filter(user => user.name.toLowerCase().includes(query.toLowerCase()))
309-
: users;
310-
311-
return of(results).pipe(delay(300)); // Simulate network delay
312-
*/
313365
}
314366
}
315-
```
316-
317-
#### Usage in a Component
318-
319-
```typescript
320-
import { Component, OnDestroy } from '@angular/core';
321-
import { MerSelect } from '@merelis/angular/select';
322-
import { TypeaheadDataSource, TypeaheadDataSourceOptions } from '@merelis/angular/select';
323-
import { UserSearchService, User } from './user-search.service';
324367

325368
@Component({
326369
selector: 'app-user-search',
@@ -331,50 +374,35 @@ import { UserSearchService, User } from './user-search.service';
331374
[(value)]="selectedUser"
332375
[dataSource]="userDataSource"
333376
[displayWith]="displayUserName"
334-
[placeholder]="'Search for users...'"
335-
[debounceTime]="300">
377+
[placeholder]="'Search for users...'">
336378
</mer-select>
337-
<p *ngIf="selectedUser">Selected: {{selectedUser.name}}</p>
338379
`
339380
})
340381
export class UserSearchComponent implements OnDestroy {
341382
selectedUser: User | null = null;
342383
userDataSource: TypeaheadDataSource<User>;
343384

344385
constructor(private userSearchService: UserSearchService) {
345-
// Define options for the data source
346-
const options: TypeaheadDataSourceOptions<User> = {
347-
alwaysIncludeSelected: true,
348-
compareWith: (a, b) => a.id === b.id,
349-
suppressLoadingEvents: false
350-
};
351-
352386
// Create the data source with the service and options
353387
this.userDataSource = new TypeaheadDataSource<User>(
354388
userSearchService,
355-
options
389+
{
390+
compareWith: (a, b) => a.id === b.id
391+
}
356392
);
357393
}
358394

359-
ngOnDestroy(): void {
360-
// Cleanup resources
361-
this.userDataSource.disconnect();
362-
}
363-
364-
// Display function for the select component
365-
displayUserName(user: User): string {
366-
return user?.name || '';
367-
}
395+
// Rest of the component...
368396
}
369397
```
370398

371399
### TypeaheadDataSource API
372400

373-
The `TypeaheadDataSource` constructor now accepts the following parameters:
401+
The `TypeaheadDataSource` constructor accepts the following parameters:
374402

375403
| Parameter | Type | Required | Description |
376404
|-----------|------|----------|-------------|
377-
| searchService | TypeaheadSearchService<T> | Yes | The service implementing the search functionality |
405+
| searchService | TypeaheadSearchFn<T> \| TypeaheadSearchService<T> | Yes | A function or service that implements the search functionality |
378406
| options | TypeaheadDataSourceOptions<T> | No | Configuration options object |
379407

380408
#### TypeaheadDataSourceOptions Properties
@@ -397,11 +425,12 @@ The `TypeaheadDataSource` constructor now accepts the following parameters:
397425

398426
### Benefits of Using TypeaheadDataSource
399427

400-
1. **Performance**: Efficiently handles rapid typing by cancelling outdated requests
401-
2. **User Experience**: Shows loading indicators at appropriate times
402-
3. **Resilience**: Provides graceful error handling
403-
4. **Flexibility**: Works with any data type and search implementation
404-
5. **Integration**: Seamlessly works with MerSelect's search capabilities
428+
1. **Flexibility**: Supports two ways to implement search - through a simple function or a full service
429+
2. **Performance**: Efficiently handles rapid typing by cancelling outdated requests
430+
3. **User Experience**: Shows loading indicators at appropriate times
431+
4. **Resilience**: Provides graceful error handling
432+
5. **Adaptability**: Works with any data type and search implementation
433+
6. **Integration**: Seamlessly works with MerSelect's search capabilities
405434

406435
The `TypeaheadDataSource` implementation follows best practices for reactive programming with RxJS and works with both simple and complex typeahead scenarios.
407436

0 commit comments

Comments
 (0)