This is not necessarily an ember specific question, but there’s a bunch of ways you could do this.
I’ll take a stab at this by showing some of the steps I might take to refactor this.
To start, since you’re repeatedly checking for if the property is defined on params
, we could move all of that logic into a separate function (let’s call it maybeFilterByParam
):
function maybeFilterByParam(list, params, key) {
if (params[key]) {
return list.filterBy(key, params[key]);
} else {
return list;
}
}
let data = this.store.peekAll('departed');
data = maybeFilterByParam(data, params, 'name');
data = maybeFilterByParam(data, params, 'departed');
data = maybeFilterByParam(data, params, 'birth');
return maybeFilterByParam(data, params, 'registry');
I’m still not totally happy at this point — it still feels fairly repetitive since I’m having to pass the same arguments over and over. So, we could make this a factory function. Something like:
const maybeFilterByParamFactory = (list, params) => key => {
if (params[key]) {
return list.filterBy(key, params[key]);
} else {
return list;
}
}
let data = this.store.peekAll('departed');
let maybeFilterByParam = maybeFilterByParamFactory(data, params);
data = maybeFilterByParam('name');
data = maybeFilterByParam('departed');
data = maybeFilterByParam('birth');
return maybeFilterByParam('registry');
I think that constantly re-assigning data
looks a little funky at this point. So, maybe there’s a way we can express a list of maybeFilterBys
and use a .reduce
:
function maybeFilterByParams(list, params, ...keys) {
return keys.reduce((filteredList) => {
if (params[key]) {
return filteredList.filterBy(key, params[key]);
}
return filteredList;
}, list);
}
let data = this.store.peekAll('departed');
return maybeFilterByParams(data, params, 'name', 'departed', 'birth', 'registry');
I’m starting to like this more — but, I I think that maybeFilterByParams
is doing too much. Maybe we can make it a teeny bit better by moving out the logic that determines which keys and values from params
we should use (then we don’t need to pass it as an argument to our maybeFilterByParams
.
function nonEmptyEntriesBy(params, ...keys) {
return keys
.filter(key => params[key] != 'undefined')
.map(key => [key, params[key]]);
}
function filterByParamEntries(list, entries) {
return entries.reduce((filteredList, [key, value]) => {
return filteredList.filterBy(key, value);
}, list);
}
let data = this.store.peekAll('departed');
let paramEntries = nonEmptyEntriesBy(params, 'name', 'departed', 'birth', 'registry');
return filterByParamEntries(this.store.peekAll('departed'), paramEntries);
This last one has no if
statement at all. o_O. That might be a little bit too abstract, but maybe not.
Hopefully there’s something here that helps. Let me know if anything I threw out here needs any clarification!