Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
refactor(lodash): remove simple functions (#656)
Browse files Browse the repository at this point in the history
* isFunction

* keys

* isEmpty & isUndefined

* isEqual

* isNaN

* Update src/SearchParameters/index.js

Co-Authored-By: Haroenv <fingebimus@me.com>

* feedback from review

* fix(params): harden conditions for empty refinements

this used to be isEmpty, so here we use a similar, but more focused condition

* chore(numeric): make helper function clearer

* refactor: use created helper method

* fix: don't use const

* feat(objectHasKeys): return false for falsy (non-object)
  • Loading branch information
Haroenv authored May 10, 2019
1 parent c6820da commit c78bd0f
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 64 deletions.
33 changes: 18 additions & 15 deletions src/SearchParameters/RefinementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@
* @typedef {Object.<string, SearchParameters.refinementList.Refinements>} SearchParameters.refinementList.RefinementList
*/

var isUndefined = require('lodash/isUndefined');
var isFunction = require('lodash/isFunction');
var isEmpty = require('lodash/isEmpty');

var defaultsPure = require('../functions/defaultsPure');
var omit = require('../functions/omit');
var objectHasKeys = require('../functions/objectHasKeys');

var lib = {
/**
Expand Down Expand Up @@ -54,7 +51,7 @@ var lib = {
* @return {RefinementList} a new and updated refinement lst
*/
removeRefinement: function removeRefinement(refinementList, attribute, value) {
if (isUndefined(value)) {
if (value === undefined) {
return lib.clearRefinement(refinementList, attribute);
}

Expand All @@ -72,7 +69,7 @@ var lib = {
* @return {RefinementList} a new and updated list
*/
toggleRefinement: function toggleRefinement(refinementList, attribute, value) {
if (isUndefined(value)) throw new Error('toggleRefinement should be used with a value');
if (value === undefined) throw new Error('toggleRefinement should be used with a value');

if (lib.isRefined(refinementList, attribute, value)) {
return lib.removeRefinement(refinementList, attribute, value);
Expand All @@ -92,26 +89,32 @@ var lib = {
* @return {RefinementList} a new and updated refinement list
*/
clearRefinement: function clearRefinement(refinementList, attribute, refinementType) {
if (isUndefined(attribute)) {
if (isEmpty(refinementList)) return refinementList;
if (attribute === undefined) {
if (!objectHasKeys(refinementList)) {
return refinementList;
}
return {};
} else if (typeof attribute === 'string') {
if (isEmpty(refinementList[attribute])) return refinementList;
if (!(refinementList[attribute] && refinementList[attribute].length > 0)) {
return refinementList;
}
return omit(refinementList, attribute);
} else if (isFunction(attribute)) {
} else if (typeof attribute === 'function') {
var hasChanged = false;

var newRefinementList = Object.keys(refinementList).reduce(function(memo, key) {
var values = refinementList[key] || [];
var facetList = values.filter(function(value) {
return !attribute(value, key, refinementType);
});

if (!isEmpty(facetList)) {
if (facetList.length !== values.length) hasChanged = true;
if (facetList.length > 0) {
if (facetList.length !== values.length) {
hasChanged = true;
}
memo[key] = facetList;
} else {
hasChanged = true;
}
else hasChanged = true;

return memo;
}, {});
Expand All @@ -133,7 +136,7 @@ var lib = {
var containsRefinements = !!refinementList[attribute] &&
refinementList[attribute].length > 0;

if (isUndefined(refinementValue) || !containsRefinements) {
if (refinementValue === undefined || !containsRefinements) {
return containsRefinements;
}

Expand Down
12 changes: 6 additions & 6 deletions src/SearchParameters/filterState.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var isEmpty = require('lodash/isEmpty');
var objectHasKeys = require('../functions/objectHasKeys');

/**
* @param {any[]} filters
Expand Down Expand Up @@ -28,20 +28,20 @@ function filterState(state, filters) {
}

var numericRefinements = state.getNumericRefinements(attr);
if (!isEmpty(numericRefinements)) {
if (objectHasKeys(numericRefinements)) {
if (!partialState.numericRefinements) partialState.numericRefinements = {};
partialState.numericRefinements[attr] = state.numericRefinements[attr];
}
});
} else {
if (!isEmpty(state.numericRefinements)) {
if (objectHasKeys(state.numericRefinements)) {
partialState.numericRefinements = state.numericRefinements;
}
if (!isEmpty(state.facetsRefinements)) partialState.facetsRefinements = state.facetsRefinements;
if (!isEmpty(state.disjunctiveFacetsRefinements)) {
if (objectHasKeys(state.facetsRefinements)) partialState.facetsRefinements = state.facetsRefinements;
if (objectHasKeys(state.disjunctiveFacetsRefinements)) {
partialState.disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements;
}
if (!isEmpty(state.hierarchicalFacetsRefinements)) {
if (objectHasKeys(state.hierarchicalFacetsRefinements)) {
partialState.hierarchicalFacetsRefinements = state.hierarchicalFacetsRefinements;
}
}
Expand Down
101 changes: 65 additions & 36 deletions src/SearchParameters/index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
'use strict';

var keys = require('lodash/keys');
var isNaN = require('lodash/isNaN');
var isEmpty = require('lodash/isEmpty');
var isEqual = require('lodash/isEqual');
var isUndefined = require('lodash/isUndefined');
var isFunction = require('lodash/isFunction');

var merge = require('lodash/merge');

var defaultsPure = require('../functions/defaultsPure');
var find = require('../functions/find');
var valToNumber = require('../functions/valToNumber');
var omit = require('../functions/omit');
var objectHasKeys = require('../functions/objectHasKeys');

var filterState = require('./filterState');

var RefinementList = require('./RefinementList');

/**
* like _.find but using _.isEqual to be able to use it
* isEqual, but only for numeric refinement values, possible values:
* - 5
* - [5]
* - [[5]]
* - [[5,5],[4]]
*/
function isEqualNumericRefinement(a, b) {
if (Array.isArray(a) && Array.isArray(b)) {
return (
a.length === b.length &&
a.every(function(el, i) {
return isEqualNumericRefinement(b[i], el);
})
);
}
return a === b;
}

/**
* like _.find but using deep equality to be able to use it
* to find arrays.
* @private
* @param {any[]} array array to search into
* @param {any} searchedValue the value we're looking for
* @param {any[]} array array to search into (elements are base or array of base)
* @param {any} searchedValue the value we're looking for (base or array of base)
* @return {any} the searched value or undefined
*/
function findArray(array, searchedValue) {
return find(array, function(currentValue) {
return isEqual(currentValue, searchedValue);
return isEqualNumericRefinement(currentValue, searchedValue);
});
}

Expand Down Expand Up @@ -195,7 +208,7 @@ function SearchParameters(newParameters) {
* This doesn't contain any beta/hidden features.
* @private
*/
SearchParameters.PARAMETERS = keys(new SearchParameters());
SearchParameters.PARAMETERS = Object.keys(new SearchParameters());

/**
* @private
Expand Down Expand Up @@ -226,6 +239,7 @@ SearchParameters._parseNumbers = function(partialState) {
var value = partialState[k];
if (typeof value === 'string') {
var parsedValue = parseFloat(value);
// global isNaN is ok to use here, value is only number or NaN
numbers[k] = isNaN(parsedValue) ? value : parsedValue;
}
});
Expand Down Expand Up @@ -319,14 +333,19 @@ SearchParameters.validate = function(currentState, parameters) {
'an error, if it is not, you should first clear the tags with clearTags method.');
}

if (currentState.numericFilters && params.numericRefinements && !isEmpty(params.numericRefinements)) {
if (
currentState.numericFilters &&
params.numericRefinements &&
objectHasKeys(params.numericRefinements)
) {
return new Error(
"[Numeric filters] Can't switch from the advanced to the managed API. It" +
' is probably an error, if this is really what you want, you have to first' +
' clear the numeric filters.');
' is probably an error, if this is really what you want, you have to first' +
' clear the numeric filters.'
);
}

if (!isEmpty(currentState.numericRefinements) && params.numericFilters) {
if (objectHasKeys(currentState.numericRefinements) && params.numericFilters) {
return new Error(
"[Numeric filters] Can't switch from the managed API to the advanced. It" +
' is probably an error, if this is really what you want, you have to first' +
Expand Down Expand Up @@ -565,11 +584,16 @@ SearchParameters.prototype = {
*/
removeNumericRefinement: function(attribute, operator, paramValue) {
if (paramValue !== undefined) {
var paramValueAsNumber = valToNumber(paramValue);
if (!this.isNumericRefined(attribute, operator, paramValueAsNumber)) return this;
if (!this.isNumericRefined(attribute, operator, paramValue)) {
return this;
}
return this.setQueryParameters({
numericRefinements: this._clearNumericRefinements(function(value, key) {
return key === attribute && value.op === operator && isEqual(value.val, paramValueAsNumber);
return (
key === attribute &&
value.op === operator &&
isEqualNumericRefinement(value.val, valToNumber(paramValue))
);
})
});
} else if (operator !== undefined) {
Expand Down Expand Up @@ -616,13 +640,17 @@ SearchParameters.prototype = {
* @return {Object.<string, OperatorList>}
*/
_clearNumericRefinements: function _clearNumericRefinements(attribute) {
if (isUndefined(attribute)) {
if (isEmpty(this.numericRefinements)) return this.numericRefinements;
if (attribute === undefined) {
if (!objectHasKeys(this.numericRefinements)) {
return this.numericRefinements;
}
return {};
} else if (typeof attribute === 'string') {
if (isEmpty(this.numericRefinements[attribute])) return this.numericRefinements;
if (!objectHasKeys(this.numericRefinements[attribute])) {
return this.numericRefinements;
}
return omit(this.numericRefinements, attribute);
} else if (isFunction(attribute)) {
} else if (typeof attribute === 'function') {
var hasChanged = false;
var numericRefinements = this.numericRefinements;
var newNumericRefinements = Object.keys(numericRefinements).reduce(function(memo, key) {
Expand All @@ -637,14 +665,16 @@ SearchParameters.prototype = {
var predicateResult = attribute({val: value, op: operator}, key, 'numeric');
if (!predicateResult) outValues.push(value);
});
if (!isEmpty(outValues)) {
if (outValues.length > 0) {
if (outValues.length !== values.length) hasChanged = true;
operatorList[operator] = outValues;
}
else hasChanged = true;
});

if (!isEmpty(operatorList)) memo[key] = operatorList;
if (objectHasKeys(operatorList)) {
memo[key] = operatorList;
}

return memo;
}, {});
Expand Down Expand Up @@ -1179,21 +1209,22 @@ SearchParameters.prototype = {
* @return {boolean} true if it is refined
*/
isNumericRefined: function isNumericRefined(attribute, operator, value) {
if (isUndefined(value) && isUndefined(operator)) {
if (value === undefined && operator === undefined) {
return !!this.numericRefinements[attribute];
}

var isOperatorDefined = this.numericRefinements[attribute] &&
!isUndefined(this.numericRefinements[attribute][operator]);
var isOperatorDefined =
this.numericRefinements[attribute] &&
this.numericRefinements[attribute][operator] !== undefined;

if (isUndefined(value) || !isOperatorDefined) {
if (value === undefined || !isOperatorDefined) {
return isOperatorDefined;
}

var parsedValue = valToNumber(value);
var isAttributeValueDefined = !isUndefined(
findArray(this.numericRefinements[attribute][operator], parsedValue)
);
var isAttributeValueDefined =
findArray(this.numericRefinements[attribute][operator], parsedValue) !==
undefined;

return isOperatorDefined && isAttributeValueDefined;
},
Expand Down Expand Up @@ -1222,7 +1253,7 @@ SearchParameters.prototype = {
}
);

return keys(this.disjunctiveFacetsRefinements)
return Object.keys(this.disjunctiveFacetsRefinements)
.concat(disjunctiveNumericRefinedFacets)
.concat(this.getRefinedHierarchicalFacets());
},
Expand Down Expand Up @@ -1330,9 +1361,7 @@ SearchParameters.prototype = {
var parsedParams = SearchParameters._parseNumbers(params);

return this.mutateMe(function mergeWith(newInstance) {
var ks = keys(params);

ks.forEach(function(k) {
Object.keys(params).forEach(function(k) {
newInstance[k] = parsedParams[k];
});

Expand Down
4 changes: 1 addition & 3 deletions src/SearchResults/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

var merge = require('lodash/merge');

var isFunction = require('lodash/isFunction');

var defaultsPure = require('../functions/defaultsPure');
var orderBy = require('../functions/orderBy');
var compact = require('../functions/compact');
Expand Down Expand Up @@ -706,7 +704,7 @@ SearchResults.prototype.getFacetValues = function(attribute, opts) {
return recSort(function(hierarchicalFacetValues) {
return orderBy(hierarchicalFacetValues, order[0], order[1]);
}, facetValues);
} else if (isFunction(options.sortBy)) {
} else if (typeof options.sortBy === 'function') {
if (Array.isArray(facetValues)) {
return facetValues.sort(options.sortBy);
}
Expand Down
5 changes: 2 additions & 3 deletions src/algoliasearch.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ var requestBuilder = require('./requestBuilder');

var events = require('events');
var inherits = require('./functions/inherits');

var isEmpty = require('lodash/isEmpty');
var objectHasKeys = require('./functions/objectHasKeys');

var version = require('./version');

Expand Down Expand Up @@ -985,7 +984,7 @@ AlgoliaSearchHelper.prototype.isRefined = function(facet, value) {
*
*/
AlgoliaSearchHelper.prototype.hasRefinements = function(attribute) {
if (!isEmpty(this.state.getNumericRefinements(attribute))) {
if (objectHasKeys(this.state.getNumericRefinements(attribute))) {
return true;
} else if (this.state.isConjunctiveFacet(attribute)) {
return this.state.isFacetRefined(attribute);
Expand Down
7 changes: 7 additions & 0 deletions src/functions/objectHasKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

function objectHasKeys(obj) {
return obj && Object.keys(obj).length > 0;
}

module.exports = objectHasKeys;
2 changes: 1 addition & 1 deletion src/functions/valToNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function valToNumber(v) {
return v.map(valToNumber);
}

throw new Error('The value should be a number, a parseable string or an array of those.');
throw new Error('The value should be a number, a parsable string or an array of those.');
}

module.exports = valToNumber;

0 comments on commit c78bd0f

Please sign in to comment.