Skip to content

Commit

Permalink
fix: get autocomplete working
Browse files Browse the repository at this point in the history
  • Loading branch information
cmoinier committed Nov 26, 2024
1 parent 586825d commit 777a839
Showing 1 changed file with 49 additions and 21 deletions.
70 changes: 49 additions & 21 deletions libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ import {
MatAutocompleteSelectedEvent,
MatAutocompleteTrigger,
} from '@angular/material/autocomplete'
import { first, merge, Observable, of, ReplaySubject, Subscription } from 'rxjs'
import {
first,
merge,
Observable,
of,
ReplaySubject,
Subject,
Subscription,
} from 'rxjs'
import {
catchError,
debounceTime,
Expand All @@ -30,6 +38,7 @@ import {
map,
switchMap,
take,
takeUntil,
tap,
} from 'rxjs/operators'
import { PopupAlertComponent } from '@geonetwork-ui/ui/widgets'
Expand Down Expand Up @@ -98,6 +107,7 @@ export class AutocompleteComponent
error: string | null = null
suggestions$: Observable<AutocompleteItem[]>
subscription = new Subscription()
clearSuggestions$ = new Subject<void>()

@Input() displayWithFn: (item: AutocompleteItem) => string = (item) =>
item.toString()
Expand Down Expand Up @@ -130,33 +140,47 @@ export class AutocompleteComponent
)
)

const externalValueChange$ = this.control.valueChanges.pipe(
filter((value) => typeof value === 'object' && value.title),
map((item) => item.title)
)

// this observable emits arrays of suggestions loaded using the given action
const suggestionsFromAction = merge(
newValue$.pipe(
filter((value: string) => value.length >= this.minCharacterCount)
),
externalValueChange$
).pipe(
const suggestionsFromAction = newValue$.pipe(
switchMap((value: string) => {
if (value.length === 0) {
return of([]) // Emit an empty array for an empty value
} else if (value.length >= this.minCharacterCount) {
return merge(
of(value),
this.control.valueChanges.pipe(
filter(
(controlValue) =>
typeof controlValue === 'object' && controlValue.title
),
map((item) => item.title),
distinctUntilChanged()
)
).pipe(
takeUntil(this.clearSuggestions$), // Stop emitting when suggestions are cleared
switchMap((title) =>
this.action(title).pipe(
catchError((error: Error) => {
this.error = error.message
return of([])
}),
finalize(() => (this.searching = false))
)
)
)
} else {
return of([])
}
}),
tap(() => {
this.searching = true
this.error = null
}),
switchMap((value) => this.action(value)),
catchError((error: Error) => {
this.error = error.message
return of([])
}),
finalize(() => (this.searching = false))
})
)

this.suggestions$ = merge(
this.clearSuggestions$.pipe(map(() => [])), // Clearing has the highest priority
suggestionsFromAction,
// if a new value is under the min char count, clear suggestions
newValue$.pipe(
filter((value: string) => value.length < this.minCharacterCount),
map(() => [])
Expand Down Expand Up @@ -204,11 +228,15 @@ export class AutocompleteComponent
if (this.inputRef) {
this.inputRef.nativeElement.value = (value as any)?.title || ''
}
if (this.clearOnSelection) {
this.clearSuggestions$.next()
}
}

clear(): void {
this.inputRef.nativeElement.value = ''
this.inputCleared.emit()
this.clearSuggestions$.next()
this.selectionSubject
.pipe(take(1))
.subscribe((selection) => selection && selection.option.deselect())
Expand Down Expand Up @@ -241,7 +269,7 @@ export class AutocompleteComponent
})
}
if (this.clearOnSelection) {
this.inputRef.nativeElement.value = ''
this.clear()
}
}
}

0 comments on commit 777a839

Please sign in to comment.