Reputation: 3949
I have a search button and depending upon the selected option from a user, the corresponding API call will be triggered. But I have now a bunch of if else statements.
So my question is, can I refactor this? But without a switch case?
searchFor() {
if (this.selectedSearch === 'Registratie') {
this.extendedSearchService
.filerByRegistration(this.selectedValue, this.startDate)
.subscribe(filterByRegistration => {
this.filterparticipant.emit(filterByRegistration);
});
}
if (this.selectedSearch === 'Chat') {
this.extendedSearchService.filterByChat(this.startDate).subscribe(filterByChat => {
this.filterparticipant.emit(filterByChat);
});
}
if (this.selectedSearch === 'Inlog') {
console.log('INlog');
this.extendedSearchService.filterByInlog(this.startDate).subscribe(filterByInlog => {
this.filterparticipant.emit(filterByInlog);
});
}
if (this.selectedSearch === 'QrCode') {
this.extendedSearchService
.filterByQrCodes(this.selectedValue, this.startDate, this.selectedQrcode)
.subscribe(fitlerByQrCode => {
this.filterparticipant.emit(fitlerByQrCode);
});
}
if (this.selectedSearch === 'Doelen') {
this.extendedSearchService
.filerByChallenge(this.selectedValue, this.startDate, this.selectedValueOptie, this.selectedValueProgressie)
.subscribe(filterByChallenge => {
this.filterparticipant.emit(filterByChallenge);
});
}
if (this.selectedSearch === 'Vcheq') {
this.extendedSearchService
.filterByVchecCode(this.selectedValue, this.startDate, this.selectedVcheqOption)
.subscribe(filterByVcheqCode => {
this.filterparticipant.emit(filterByVcheqCode);
});
}
}
Thank you
I have it now like this:
searchFor() {
const filter = (method, params) => {
this.extendedSearchService[method](...params).subscribe(filter => {
this.filterparticipant.emit(filter);
});
const filters = {
Registratie: filter('Registratie', [this.selectedValue, this.startDate]),
Chat: filter('Chat', [this.startDate]),
Inlog: filter('Inlog', this.startDate),
QrCode: filter('QrCode', [this.selectedValue, this.startDate, this.selectedQrcode]),
Doelen: filter('Doelen', [
this.selectedValue,
this.startDate,
this.selectedValueOptie,
this.selectedValueProgressie
]),
Vcheq: filter('Vcheq', [this.selectedValue, this.startDate, this.selectedVcheqOption])
};
if (filters[this.selectedSearch]) {
filters[this.selectedSearch]();
}
};
}
And it compiles, but the filter doesnt work.
if I do this:
searchFor() {
const filter = (method, params) => {
this.extendedSearchService[method](...params).subscribe(filter => {
console.log('Filter');
this.filterparticipant.emit(filter);
});
};
I get this error:
ExtendedSearchComponent.html:90 ERROR TypeError: Cannot read property 'apply' of undefined
at filter (extended-search.component.ts:211)
at
On this line:
this.extendedSearchService[method](...params).subscribe(filter => {
console.log('Filter');
I have it so:
searchFor() {
const filter = (method, params) => {
this.extendedSearchService[method](...params).subscribe(filter => {
console.log(method);
this.filterparticipant.emit(filter);
});
};
const filters = {
Registratie: filter('filterByRegistration', [this.selectedValue, this.startDate]),
Chat: filter('filterByChat', [this.startDate]),
Inlog: filter('filterByInlog', [this.startDate]),
QrCode: filter('filterByQrCodes', [this.selectedValue, this.startDate, this.selectedQrcode]),
Doelen: filter('filerByChallenge', [this.selectedValue, this.startDate, this.selectedValueOptie, this.selectedValueProgressie]),
Vcheq: filter('filterByVchecCode', [this.selectedValue, this.startDate, this.selectedVcheqOption]),
}
if (filters[this.selectedSearch]) {
filters[this.selectedSearch]();
}
}
Then I get this error:
ExtendedSearchComponent.html:88 ERROR TypeError: Cannot read property 'apply' of undefined
at filter (extended-search.component.ts:213)
at ExtendedSearchComponent.push../src/app/participant/components/extended-search/extended-search.component.ts.ExtendedSearchComponent.searchFor (extended-search.component.ts:220)
at Object.eval [as handleEvent] (ExtendedSearchComponent.html:91)
at handleEvent (core.js:19628)
at callWithDebugContext (core.js:20722)
at Object.debugHandleEvent [as handleEvent] (core.js:20425)
at dispatchEvent (core.js:17077)
at core.js:17524
at HTMLButtonElement.<anonymous> (platform-browser.js:993)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
Oke, I did some debugging.
and put this:
console.log('Method', method);
But then I see that multiple methods are been called:
Method filterByRegistration
extended-search.component.ts:214 Method filterByInlog
extended-search.component.ts:214 Method filterByChat
What of course not has to been. Just one api call at a time.
Upvotes: 0
Views: 992
Reputation: 19301
The lastest version of code in the post calls filter
six times when initializing const filters
. However filter
should only be called once in the if
statement at the end of searchFor
.
One way of achieving this is to record both the method name and parameters in the filters
object and modify filter
to pick up both the method and its parameters. For example:
function searchFor() {
const filter = (using) => {
this.extendedSearchService[using.method](...using.params).subscribe(filter => {
console.log(using.method);
this.filterparticipant.emit(filter);
});
};
const filters = {
Registratie: { method: 'filterByRegistration', params: [this.selectedValue, this.startDate]},
Chat: { method: 'filterByChat', params: [this.startDate]},
Inlog: { method: 'filterByInlog', params: [this.startDate]},
QrCode:{ method: 'filterByQrCodes', params: [this.selectedValue, this.startDate, this.selectedQrcode]},
Doelen: { method: 'filerByChallenge', params: [this.selectedValue, this.startDate, this.selectedValueOptie, this.selectedValueProgressie]},
Vcheq: { method: 'filterByVchecCode', params: [this.selectedValue, this.startDate, this.selectedVcheqOption]},
}
if (filters[this.selectedSearch]) {
filter(filters[this.selectedSearch]);
}
}
Upvotes: 1
Reputation: 31
Made something dynamic, this way you avoid checking one by one
const filter = (method, params) => {
this.extendedSearchService[method](...params).subscribe(filter => {
this.filterparticipant.emit(filter);
});
};
const filters = {
Registratie: filter('filterByRegistration', [this.selectedValue, this.startDate]),
Chat: filter('filterByChat', [this.startDate]),
Inlog: filter('filterByInlog', [this.startDate]),
QrCode: filter('filterByQrCodes', [this.selectedValue, this.startDate, this.selectedQrcode]),
Doelen: filter('filerByChallenge', [this.selectedValue, this.startDate, this.selectedValueOptie, this.selectedValueProgressie]),
Vcheq: filter('filterByVchecCode', [this.selectedValue, this.startDate, this.selectedVcheqOption]),
}
if(filters[this.selectedSearch]) {
filters[this.selectedSearch]();
}
Upvotes: 0
Reputation: 6739
You could create an object with the property as the search type and the function as the value.
This is an example of how it works
var searchObject = {
optionA: function(){
console.log('Option A')
},
optionB: function(){
console.log('Option B')
}
}
function search(option){
searchObject[option]()
}
search('optionA')
search('optionB')
And this is a snippet of what your code would look like, I haven't kept up with angular so it might be this.searchObject
depending on where you define it, but the concept would be the same
var searchObject = {
Registratie: function() {
this.extendedSearchService
.filerByRegistration(this.selectedValue, this.startDate)
.subscribe(filterByRegistration => {
this.filterparticipant.emit(filterByRegistration);
});
},
Chat: function() {
this.extendedSearchService.filterByChat(this.startDate).subscribe(filterByChat => {
this.filterparticipant.emit(filterByChat);
});
}
}
searchFor() {
searchObject[this.selectedSearch]()
}
Upvotes: 0