diff --git a/packages/autocomplete-core/src/__tests__/getSources.test.ts b/packages/autocomplete-core/src/__tests__/getSources.test.ts index 686bc03d0..9cbd5b795 100644 --- a/packages/autocomplete-core/src/__tests__/getSources.test.ts +++ b/packages/autocomplete-core/src/__tests__/getSources.test.ts @@ -6,6 +6,7 @@ import { runAllMicroTasks, } from '../../../../test/utils'; import { createAutocomplete } from '../createAutocomplete'; +import * as handlers from '../onInput'; describe('getSources', () => { test('gets calls on input', () => { @@ -110,4 +111,25 @@ describe('getSources', () => { expect(onStateChange.mock.calls.pop()[0].state.collections).toHaveLength(2); }); + + test('with nothing returned from getItems throws', async () => { + const spy = jest.spyOn(handlers, 'onInput'); + + const { inputElement } = createPlayground(createAutocomplete, { + getSources() { + return [createSource({ sourceId: 'source1', getItems: () => {} })]; + }, + }); + + await expect(() => { + inputElement.focus(); + userEvent.type(inputElement, 'a'); + + return spy.mock.results[0].value; + }).rejects.toThrow( + '[Autocomplete] The `getItems` function from source "source1" must return an array of items but returned undefined.\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems' + ); + + spy.mockRestore(); + }); }); diff --git a/packages/autocomplete-core/src/resolve.ts b/packages/autocomplete-core/src/resolve.ts index 1505f77cd..9e83ed186 100644 --- a/packages/autocomplete-core/src/resolve.ts +++ b/packages/autocomplete-core/src/resolve.ts @@ -27,7 +27,7 @@ function isDescription( function isRequesterDescription( description: TItem[] | TItem[][] | RequesterDescription ): description is RequesterDescription { - return Boolean((description as RequesterDescription).execute); + return Boolean((description as RequesterDescription)?.execute); } type PackedDescription = { @@ -172,9 +172,26 @@ export function postResolve( invariant( Array.isArray(items), - `The \`getItems\` function must return an array of items but returned type ${JSON.stringify( + `The \`getItems\` function from source "${ + source.sourceId + }" must return an array of items but returned type ${JSON.stringify( typeof items - )}:\n\n${JSON.stringify(items, null, 2)}` + )}:\n\n${JSON.stringify(items, null, 2)}. + +See: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems` + ); + + invariant( + (items as Array).every(Boolean), + `The \`getItems\` function from source "${ + source.sourceId + }" must return an array of items but returned ${JSON.stringify( + undefined + )}. + +Did you forget to return items? + +See: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems` ); return {