Skip to content

Commit

Permalink
feat(dynamicWidgets): accept strings for facets (#5948)
Browse files Browse the repository at this point in the history
* feat(dynamicWidgets): accept strings for `facets`

This can be useful for when you want to ensure certain facets are already requested, or know the exact list of facets to request (maximally, in the right order), to still have the advantages of request deduplication without using `*`

* test(dynamicWidgets): make sure facets is implemented right
  • Loading branch information
Haroenv committed Dec 5, 2023
1 parent 042aaac commit 61a4bea
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,32 +58,42 @@ describe('connectDynamicWidgets', () => {
).not.toThrow();
});

it('fails when a non-star facet is given', () => {
it('fails when widgets is not an array', () => {
expect(() =>
connectDynamicWidgets(() => {})(
connectDynamicWidgets(() => {})({
// @ts-expect-error
{ widgets: [], facets: ['lol'] }
)
widgets: {},
})
).toThrowErrorMatchingInlineSnapshot(`
"The \`facets\` option only accepts [] or [\\"*\\"], you passed [\\"lol\\"]
"The \`widgets\` option expects an array of widgets.
See documentation: https://www.algolia.com/doc/api-reference/widgets/dynamic-widgets/js/#connector"
`);
});

it('fails when a multiple star facets are given', () => {
it('fails when facets is not an array', () => {
expect(() =>
connectDynamicWidgets(() => {})(
connectDynamicWidgets(() => {})({
widgets: [],
// @ts-expect-error
{ widgets: [], facets: ['*', '*'] }
)
facets: {},
})
).toThrowErrorMatchingInlineSnapshot(`
"The \`facets\` option only accepts [] or [\\"*\\"], you passed [\\"*\\",\\"*\\"]
"The \`facets\` option only accepts an array of facets, you passed {}
See documentation: https://www.algolia.com/doc/api-reference/widgets/dynamic-widgets/js/#connector"
`);
});

it('does not fail when only some facets are given', () => {
expect(() =>
connectDynamicWidgets(() => {})({
widgets: [],
facets: ['a', 'b', 'c'],
})
).not.toThrow();
});

it('does not fail when only star facet is given', () => {
expect(() =>
connectDynamicWidgets(() => {})({ widgets: [], facets: ['*'] })
Expand Down Expand Up @@ -872,5 +882,34 @@ describe('connectDynamicWidgets', () => {
})
);
});

test('adds to existing facets', () => {
const dynamicWidgets = connectDynamicWidgets(() => {})({
facets: ['facet1', 'facet2'],
transformItems() {
return ['test1'];
},
widgets: [
connectMenu(() => {})({ attribute: 'test1' }),
connectHierarchicalMenu(() => {})({ attributes: ['test2', 'test3'] }),
],
});

expect(
dynamicWidgets.getWidgetSearchParameters!(
new SearchParameters({
facets: ['existing'],
}),
{
uiState: {},
}
)
).toEqual(
new SearchParameters({
facets: ['existing', 'facet1', 'facet2'],
maxValuesPerFacet: 20,
})
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,21 @@ export type DynamicWidgetsConnectorParams = {

/**
* To prevent unneeded extra network requests when widgets mount or unmount,
* we request all facet values.
* we request all facet values by default. If you want to only request the
* facet values that are needed, you can set this option to the list of
* attributes you want to display.
*
* If `facets` is set to `['*']`, we request all facet values.
*
* Any facets that are requested due to the `facetOrdering` result are always
* requested by the widget that mounted itself.
*
* Setting `facets` to a value other than `['*']` will only prevent extra
* requests if all potential facets are listed.
*
* @default ['*']
*/
facets?: ['*'] | never[];
facets?: ['*'] | string[];

/**
* If you have more than 20 facet values pinned, you need to increase the
Expand Down Expand Up @@ -105,16 +115,10 @@ const connectDynamicWidgets: DynamicWidgetsConnector =
);
}

if (
!(
Array.isArray(facets) &&
facets.length <= 1 &&
(facets[0] === '*' || facets[0] === undefined)
)
) {
if (!Array.isArray(facets)) {
throw new Error(
withUsage(
`The \`facets\` option only accepts [] or ["*"], you passed ${JSON.stringify(
`The \`facets\` option only accepts an array of facets, you passed ${JSON.stringify(
facets
)}`
)
Expand Down Expand Up @@ -201,8 +205,7 @@ const connectDynamicWidgets: DynamicWidgetsConnector =
unmountFn();
},
getWidgetSearchParameters(state) {
// broadening the scope of facets to avoid conflict between never and *
return (facets as string[]).reduce(
return facets.reduce(
(acc, curr) => acc.addFacet(curr),
state.setQueryParameters({
maxValuesPerFacet: Math.max(
Expand Down

0 comments on commit 61a4bea

Please sign in to comment.