import { getSelectOptionsFromUrl } from "./getSelectOptionsFromUrl"; import { selectEmptyOptions } from "../config/constants"; import type { TOptionType, IStateActions, IOnOptionsSearchRequestConfig, } from "../config/types"; type TGetOptionsParams = { value: string; callback: (options: TOptionType[]) => void; onOptionsSearchRequest: IOnOptionsSearchRequestConfig; stateActions: IStateActions; name: string; }; /** * Fetches options asynchronously based on the user's search input. * Uses the configuration provided in `onOptionsSearchRequest`. * @returns {Promise} */ export const getOptions = async ({ value, callback, onOptionsSearchRequest, stateActions, name, }: TGetOptionsParams): Promise => { if (!onOptionsSearchRequest) { console.error("[Select] No 'onOptionsSearchRequest' object provided to select cfg"); return Promise.reject(selectEmptyOptions); } const { onSuccess, onError, onDone, requestCfg = {}, requestFn = null, getMappedOptions = (options) => options, getData = (selectValue) => { const baseData = requestCfg?.data ?? {}; return { [name]: selectValue, ...baseData }; }, } = onOptionsSearchRequest; const fn = async () => { const cfg = { ...requestCfg, data: getData(value), }; if (typeof requestFn === "function") { return await requestFn(cfg) .then((options = selectEmptyOptions) => { return options; }); } else { return await getSelectOptionsFromUrl(cfg) .then((options = selectEmptyOptions) => { return options; }); } }; return await fn() .then( (options: TOptionType[]) => { if (typeof onSuccess === "function") { return onSuccess({ options, stateActions, callback }); } else { callback(getMappedOptions(options)); return options; } } ) .catch((error: Error) => { if (typeof onError === "function") { return onError({ error, stateActions, callback }); } else { return selectEmptyOptions; } }) .finally(() => { if (typeof onDone === "function") { onDone({ stateActions, callback }); } }); };