if(weekly_trending === "true" && monthly_trending === "true"
&& quarterly_trending === "true"
&& sort_by_likes === "true"
&& sort_by_date === "true" ){
return
}
These are the filters I want to use in my API, but I want to allow to use only one of these filter at a time, like only weekly_trending === "true", not any other from the list.
I can do that using if statements like this, but I have to write so much code. Is there any other solution to this?
something you can do is create an array from all your boolean and with array.filter get an array of all one equal to true
var conditions = [
weekly_trending,
monthly_trending,
quarterly_trending,
sort_by_likes,
sort_by_date
];
conditions.filter(condition => condition)
array.filter is a method that :
your if can be simplified to
if(conditions.filter(condition => condition).length === 1){
var weekly_trending = true;
var monthly_trending = false;
var quarterly_trending = false;
var sort_by_likes = false;
var sort_by_date = false;
function getConditions() {
return [
weekly_trending,
monthly_trending,
quarterly_trending,
sort_by_likes,
sort_by_date
];
}
function validate() {
var conditions = getConditions();
if(conditions.filter(condition => condition).length === 1) {
console.log('win');
} else {
console.log('failed');
}
}
validate();
monthly_trending = true;
validate();
I think this solution will do if you want to limit only one filter for your API:
const filterWeeklyTrending = (unfilteredResults) => {/*...*/}
// rest of the possible filter functions...
const filterFunctions = {
weekly_trending: filterWeeklyTrending,
monthly_trending: filterMonthlyTrending,
// rest of the possible filters...
}
// Suppose you are using Express and queries live in `req.param` like so:
// { weekly_trending: 1 }
// We want to return an array of matched filter names here.
const matchedFilterNames = Object.keys(filterFunctions).filter(key => key in req.param) // e.g. ['weekly_trending']
if (matchedFilterNames.length !== 1) {
// tell client they must provide only 1 filter
return
}
// otherwise, filter results
const selectedFilterFunction = filterFunctions[matchedFilterNames[0]]
const filteredResults = selectedFilterFunction(unfilteredResults)
However, if you are building an API, and the filter is specified by the end user, would a slightly different design that forces the end user to only be able to choose one filter from the start mitigate the problem?
e.g. if it's an HTTP API, it would indicate better to the user to only provide one filter option if instead of http://my.site/api/sports?weekly_trending=true, we have http://my.site/api/sports?sort=weekly_trending?
Then we can substitute the following:
const matchedFilterNames = Object.keys(filterFunctions).filter(key => key in req.param) // e.g. ['weekly_trending']
if (matchedFilterNames.length !== 1) {
// tell client they must provide only 1 filter
return
}
with
const filterName = req.params.sort // if this is where user specifies the filter function
if (!(filterName in filterFunctions)) {
// tell client this filter does not exist
return
}
Create a helper Class Validator to add your rules as you need and validate the result.
const weekly_trending = true;
const monthly_trending = true;
const quarterly_trending = true;
const sort_by_likes = true;
const sort_by_date = true;
class Validator {
constructor() {
this.rules = [];
}
addRules(...rules) {
this.rules.push(...rules);
}
validate() {
if (this.rules.every(rule => rule === true)) {
console.log("all true");
}
}
}
const validator = new Validator();
validator.addRules(
weekly_trending,
monthly_trending,
quarterly_trending,
sort_by_likes,
sort_by_date
);
validator.validate();