UNPKG

@yext/search-ui-react

Version:

A library of React Components for powering Yext Search integrations

56 lines (53 loc) 2.42 kB
import { useSearchActions, AutocompleteResponse, SearchIntent } from '@yext/search-headless-react'; import { executeSearch, executeAutocomplete } from '../utils/search-operations'; import { updateLocationIfNeeded } from '../utils/location-operations'; import { MutableRefObject, useRef } from 'react'; import { onSearchFunc } from '../components/SearchBar'; /** The type of a function for executing a query and returning a promise. @public */ export type QueryFunc = () => Promise<void>; /** * A ref which contains a promise of the latest autocomplete response in order get the * latest search intents. */ export type AutocompleteRef = MutableRefObject<Promise<AutocompleteResponse | undefined> | undefined>; /** * Returns a search action that will handle near me searches, by first checking * for near me intents using an autocomplete request. * * @remarks * You can optionally use the provided ref to store autocomplete responses, to avoid * making unnecessary autocomplete requests. */ export function useSearchWithNearMeHandling( geolocationOptions?: PositionOptions, onSearch?: onSearchFunc ): [QueryFunc, AutocompleteRef] { /** * Allow a query search to wait on the response to the autocomplete request right * before the search execution in order to retrieve the search intents. */ const autocompletePromiseRef = useRef<Promise<AutocompleteResponse | undefined>>(); const searchActions = useSearchActions(); async function executeQuery() { try { let intents: SearchIntent[] = []; if (!searchActions.state.location.userLocation) { if (!autocompletePromiseRef.current) { autocompletePromiseRef.current = executeAutocomplete(searchActions); } const autocompleteResponseBeforeSearch = await autocompletePromiseRef.current; intents = autocompleteResponseBeforeSearch?.inputIntents || []; await updateLocationIfNeeded(searchActions, intents, geolocationOptions); } } catch (e) { console.error('Error executing autocomplete before search:', e); await updateLocationIfNeeded(searchActions, [], geolocationOptions); } const verticalKey = searchActions.state.vertical.verticalKey ?? ''; const query = searchActions.state.query.input ?? ''; onSearch ? onSearch({ verticalKey, query }) : executeSearch(searchActions); } return [executeQuery, autocompletePromiseRef]; }