Skip to content

Commit c989492

Browse files
authored
feat(helper): remove getRefinements, hasRefinements (#6570)
feat(helper): remove getRefinements, hasRefinement These functions are an aggregate of multiple different functions that depend on the type of refinement you're using. It's better to use the getter for the right type of refinement. BREAKING CHANGE: remove helper.hasRefinements (use helper.state.isXXXRefined instead) BREAKING CHANGE: remove helper.getRefinements (read helper.state.XXXRefinement instead) BREAKING CHANGE: remove helper.state.getRefinements (read helper.state.XXXRefinement instead)
1 parent 32f50ac commit c989492

File tree

21 files changed

+169
-799
lines changed

21 files changed

+169
-799
lines changed

examples/js/e-commerce-umd/src/app.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ import { attachEventListeners } from './ui';
33

44
search.start();
55
attachEventListeners();
6+
7+
declare global {
8+
interface Window {
9+
search: typeof search;
10+
}
11+
}
12+
13+
window.search = search;

examples/js/e-commerce-umd/src/widgets/Products.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ export const products = hits<Hit>({
5151
</article>
5252
`;
5353
},
54-
empty(results, { html }) {
55-
const hasRefinements = results.getRefinements().length > 0;
54+
empty(_, { html }) {
55+
const hasRefinements =
56+
window.search.renderState.instant_search.clearRefinements?.canRefine;
5657
const description = hasRefinements
5758
? 'Try to reset your applied filters.'
5859
: 'Please try another query.';

examples/js/e-commerce/src/app.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ import 'instantsearch.css/themes/reset.css';
55

66
search.start();
77
attachEventListeners();
8+
9+
declare global {
10+
interface Window {
11+
search: typeof search;
12+
}
13+
}
14+
15+
window.search = search;

examples/js/e-commerce/src/widgets/Products.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ export const products = hits<Hit>({
5151
</article>
5252
`;
5353
},
54-
empty(results, { html }) {
55-
const hasRefinements = results.getRefinements().length > 0;
54+
empty(_, { html }) {
55+
const hasRefinements =
56+
window.search.renderState.instant_search.clearRefinements?.canRefine;
5657
const description = hasRefinements
5758
? 'Try to reset your applied filters.'
5859
: 'Please try another query.';

examples/js/media/src/widgets/Stats.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { connectHits } from 'instantsearch.js/es/connectors';
1+
import { connectCurrentRefinements } from 'instantsearch.js/es/connectors';
22

33
import { formatNumber, getDateRangeFromTimestamp } from '../utils';
44

5-
const statsWidget = connectHits<{ container: string }>(
6-
({ results, widgetParams }) => {
5+
const statsWidget = connectCurrentRefinements<{ container: string }>(
6+
({ instantSearchInstance, items, widgetParams }) => {
7+
const results = instantSearchInstance.mainIndex.getResults();
78
if (!results) {
89
return;
910
}
@@ -12,25 +13,25 @@ const statsWidget = connectHits<{ container: string }>(
1213
if (!containerNode) {
1314
throw new Error('container not found');
1415
}
15-
const { nbHits } = results;
16+
const { nbHits } = results || {};
1617

1718
const resultsStats = `${formatNumber(nbHits)} articles`;
1819

19-
const stringRefinements = results
20-
.getRefinements()
21-
.filter((refinement) => refinement.type !== 'numeric')
22-
.filter((refinement) => refinement.attributeName !== 'categories')
23-
.map((refinement) => refinement.name);
24-
const dateRefinement = getDateRangeFromTimestamp(
25-
results
26-
.getRefinements()
27-
.filter(
28-
(refinement) => refinement.attributeName === 'created_at_timestamp'
29-
)
30-
.map((refinement) => refinement.numericValue)
31-
);
32-
33-
const refinements = [...stringRefinements, dateRefinement]
20+
const refinements = items
21+
.flatMap((item) => item.refinements)
22+
.map((refinement) => {
23+
switch (refinement.type) {
24+
case 'numeric': {
25+
return getDateRangeFromTimestamp([refinement.value]);
26+
}
27+
default: {
28+
if (refinement.attribute === 'categories') {
29+
return undefined;
30+
}
31+
return refinement.label;
32+
}
33+
}
34+
})
3435
.filter(Boolean)
3536
.map((refinement) => `<strong>${refinement}</strong>`);
3637

examples/react/e-commerce/components/NoResults.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import React from 'react';
2-
import { useInstantSearch } from 'react-instantsearch';
2+
import { useClearRefinements } from 'react-instantsearch';
33

44
import { ClearFilters } from './ClearFilters';
55

66
export function NoResults() {
7-
const { results } = useInstantSearch();
7+
const { canRefine } = useClearRefinements();
88

9-
const hasRefinements = results.getRefinements().length > 0;
10-
const description = hasRefinements
9+
const description = canRefine
1110
? 'Try to reset your applied filters.'
1211
: 'Please try another query.';
1312

examples/vue/e-commerce/src/widgets/NoResults.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,13 @@
8181
Sorry, we can&apos;t find any matches to your query!
8282
</p>
8383
<p class="hits-empty-state-description">
84-
{{
85-
state.results.getRefinements().length > 0
86-
? 'Try to reset your applied filters.'
87-
: 'Please try another query.'
88-
}}
84+
<ais-clear-refinements v-slot="{ canRefine }">
85+
{{
86+
canRefine
87+
? 'Try to reset your applied filters.'
88+
: 'Please try another query.'
89+
}}
90+
</ais-clear-refinements>
8991
</p>
9092

9193
<ais-clear-refinements>

packages/algoliasearch-helper/documentation-src/content/reference.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,6 @@ The values that can be used for filtering are retrieved with the answer from Alg
109109

110110
{{> jsdoc jsdoc/helper/toggleFacetRefinement}}
111111

112-
{{> jsdoc jsdoc/helper/hasRefinements}}
113-
114-
{{> jsdoc jsdoc/helper/getRefinements}}
115-
116112
### Disjunctive facets
117113

118114
Disjunctive facets are used to filter values from a facetted attribute. The filters set on an attribute are combined using an `or`, hence the disjunctive adjective.
@@ -447,8 +443,6 @@ The SearchResults is the interface to read the results received from Algolia sea
447443

448444
{{> jsdoc jsdoc/results/getFacetStats}}
449445

450-
{{> jsdoc jsdoc/results/getRefinements}}
451-
452446
### Geolocation data
453447

454448
{{> jsdoc jsdoc/results/aroundLatLng}}

packages/algoliasearch-helper/index.d.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,9 @@ declare namespace algoliasearchHelper {
300300
setState(newState: PlainSearchParameters): this;
301301

302302
overrideStateWithoutTriggeringChangeEvent: AlgoliaSearchHelper['setState'];
303-
hasRefinements(facet: string): boolean;
304303
getIndex(): string;
305304
getPage(): number;
306305
getTags(): string[];
307-
getRefinements(facetName: string): any[];
308306
getNumericRefinement: SearchParameters['getNumericRefinement'];
309307
getHierarchicalFacetBreadcrumb: SearchParameters['getHierarchicalFacetBreadcrumb'];
310308
clearCache(): this;
@@ -1395,17 +1393,6 @@ declare namespace algoliasearchHelper {
13951393
* @return The stats of the facet
13961394
*/
13971395
getFacetStats(attribute: string): any;
1398-
1399-
/**
1400-
* Returns all refinements for all filters + tags. It also provides
1401-
* additional information: count and exhaustiveness for each filter.
1402-
*
1403-
* See the [refinement type](#Refinement) for an exhaustive view of the available
1404-
* data.
1405-
*
1406-
* @return all the refinements
1407-
*/
1408-
getRefinements(): SearchResults.Refinement[];
14091396
}
14101397

14111398
export type Banner = {

packages/algoliasearch-helper/src/SearchResults/index.js

Lines changed: 1 addition & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,6 @@ function recSort(sortFn, node, names, level) {
744744

745745
SearchResults.DEFAULT_SORT = ['isRefined:desc', 'count:desc', 'name:asc'];
746746

747-
function vanillaSortFn(order, data) {
748-
return data.sort(order);
749-
}
750-
751747
/**
752748
* @typedef FacetOrdering
753749
* @type {Object}
@@ -907,7 +903,7 @@ SearchResults.prototype.getFacetValues = function (attribute, opts) {
907903
var order = formatSort(options.sortBy, SearchResults.DEFAULT_SORT);
908904
return orderBy(data, order[0], order[1]);
909905
} else if (typeof options.sortBy === 'function') {
910-
return vanillaSortFn(options.sortBy, data);
906+
return data.sort(options.sortBy);
911907
}
912908
throw new Error(
913909
'options.sortBy is optional but if defined it must be ' +
@@ -952,159 +948,4 @@ function getFacetStatsIfAvailable(facetList, facetName) {
952948
return data && data.stats;
953949
}
954950

955-
/**
956-
* Returns all refinements for all filters + tags. It also provides
957-
* additional information: count and exhaustiveness for each filter.
958-
*
959-
* See the [refinement type](#Refinement) for an exhaustive view of the available
960-
* data.
961-
*
962-
* Note that for a numeric refinement, results are grouped per operator, this
963-
* means that it will return responses for operators which are empty.
964-
*
965-
* @return {Array.<Refinement>} all the refinements
966-
*/
967-
SearchResults.prototype.getRefinements = function () {
968-
var state = this._state;
969-
// eslint-disable-next-line consistent-this
970-
var results = this;
971-
var res = [];
972-
973-
Object.keys(state.facetsRefinements).forEach(function (attributeName) {
974-
state.facetsRefinements[attributeName].forEach(function (name) {
975-
res.push(
976-
getRefinement(state, 'facet', attributeName, name, results.facets)
977-
);
978-
});
979-
});
980-
981-
Object.keys(state.facetsExcludes).forEach(function (attributeName) {
982-
state.facetsExcludes[attributeName].forEach(function (name) {
983-
res.push(
984-
getRefinement(state, 'exclude', attributeName, name, results.facets)
985-
);
986-
});
987-
});
988-
989-
Object.keys(state.disjunctiveFacetsRefinements).forEach(function (
990-
attributeName
991-
) {
992-
state.disjunctiveFacetsRefinements[attributeName].forEach(function (name) {
993-
res.push(
994-
getRefinement(
995-
state,
996-
'disjunctive',
997-
attributeName,
998-
name,
999-
results.disjunctiveFacets
1000-
)
1001-
);
1002-
});
1003-
});
1004-
1005-
Object.keys(state.hierarchicalFacetsRefinements).forEach(function (
1006-
attributeName
1007-
) {
1008-
state.hierarchicalFacetsRefinements[attributeName].forEach(function (name) {
1009-
res.push(
1010-
getHierarchicalRefinement(
1011-
state,
1012-
attributeName,
1013-
name,
1014-
results.hierarchicalFacets
1015-
)
1016-
);
1017-
});
1018-
});
1019-
1020-
Object.keys(state.numericRefinements).forEach(function (attributeName) {
1021-
var operators = state.numericRefinements[attributeName];
1022-
Object.keys(operators).forEach(function (operator) {
1023-
operators[operator].forEach(function (value) {
1024-
res.push({
1025-
type: 'numeric',
1026-
attributeName: attributeName,
1027-
name: value,
1028-
numericValue: value,
1029-
operator: operator,
1030-
});
1031-
});
1032-
});
1033-
});
1034-
1035-
state.tagRefinements.forEach(function (name) {
1036-
res.push({ type: 'tag', attributeName: '_tags', name: name });
1037-
});
1038-
1039-
return res;
1040-
};
1041-
1042-
/**
1043-
* @typedef {Object} Facet
1044-
* @property {string} name
1045-
* @property {Object} data
1046-
* @property {boolean} exhaustive
1047-
*/
1048-
1049-
/**
1050-
* @param {SearchParameters} state the current state
1051-
* @param {string} type the type of the refinement
1052-
* @param {string} attributeName The attribute of the facet
1053-
* @param {*} name The name of the facet
1054-
* @param {Facet[]} resultsFacets facets from the results
1055-
* @return {Refinement} the refinement
1056-
*/
1057-
function getRefinement(state, type, attributeName, name, resultsFacets) {
1058-
var facet = resultsFacets.find(function (f) {
1059-
return f.name === attributeName;
1060-
});
1061-
var count = facet && facet.data && facet.data[name] ? facet.data[name] : 0;
1062-
var exhaustive = (facet && facet.exhaustive) || false;
1063-
1064-
return {
1065-
type: type,
1066-
attributeName: attributeName,
1067-
name: name,
1068-
count: count,
1069-
exhaustive: exhaustive,
1070-
};
1071-
}
1072-
1073-
/**
1074-
* @param {SearchParameters} state the current state
1075-
* @param {string} attributeName the attribute of the hierarchical facet
1076-
* @param {string} name the name of the facet
1077-
* @param {Facet[]} resultsFacets facets from the results
1078-
* @return {HierarchicalFacet} the hierarchical facet
1079-
*/
1080-
function getHierarchicalRefinement(state, attributeName, name, resultsFacets) {
1081-
var facetDeclaration = state.getHierarchicalFacetByName(attributeName);
1082-
var separator = state._getHierarchicalFacetSeparator(facetDeclaration);
1083-
var split = name.split(separator);
1084-
var rootFacet = resultsFacets.find(function (facet) {
1085-
return facet.name === attributeName;
1086-
});
1087-
1088-
var facet = split.reduce(function (intermediateFacet, part) {
1089-
var newFacet =
1090-
intermediateFacet &&
1091-
intermediateFacet.data.find(function (f) {
1092-
return f.name === part;
1093-
});
1094-
return newFacet !== undefined ? newFacet : intermediateFacet;
1095-
}, rootFacet);
1096-
1097-
var count = (facet && facet.count) || 0;
1098-
var exhaustive = (facet && facet.exhaustive) || false;
1099-
var path = (facet && facet.path) || '';
1100-
1101-
return {
1102-
type: 'hierarchical',
1103-
attributeName: attributeName,
1104-
name: path,
1105-
count: count,
1106-
exhaustive: exhaustive,
1107-
};
1108-
}
1109-
1110951
module.exports = SearchResults;

0 commit comments

Comments
 (0)