I am trying to refactor a ViewModel
class because it has two methods that are really similar called updateRegions
and updateTowns
and even another one may end up being made called updateCountries
. I basically copy-paste the method and change the variable names. How can this be refactored with maybe an abstract class that has an abstract updateArea
function?
class SearchFilterViewModel {
_regionsList = [];
_townsList = [];
_regions = ko.observableArray();
_towns = ko.observableArray();
selectedRegion: KnockoutObservable<string> = ko.observable('');
selectedTown: KnockoutObservable<string> = ko.observable('');
selectedCategories: KnockoutObservableArray<string> = ko.observableArray([]);
constructor() {
this.updateRegions("2186224");
this.selectedRegion.subscribe(this.updateTowns.bind(this));
}
updateRegions(geonameId) {
var self = this;
self._regionsList = [];
$.ajax({
url: `http://api.geonames.org/children?geonameId=${geonameId}&username=elion`
}).then(function(allRegionsXML) {
var allRegionsJSON = xml2json(allRegionsXML);
var allRegions = JSON.parse(allRegionsJSON);
if(allRegions.geonames.length) {
for (var index = 1; index < allRegions.geonames.length - 1; index++) {
self._regionsList.push(allRegions.geonames[index].geoname);
}
} else {
if(allRegions.geonames) {
self._regionsList.push(allRegions.geonames.geoname);
}
}
self._regions(self._regionsList);
});
}
updateTowns(geonameId) {
var self = this;
self._townsList = [];
$.ajax({
url: `http://api.geonames.org/children?geonameId=${geonameId}&username=elion`
}).then(function(allTownsXML) {
var allTownsJSON = xml2json(allTownsXML);
var allTowns = JSON.parse(allTownsJSON);
if(allTowns.geonames.length) {
for (var index = 1; index < allTowns.geonames.length - 1; index++) {
self._townsList.push(allTowns.geonames[index].geoname);
}
} else {
if(allTowns.geonames) {
self._townsList.push(allTowns.geonames.geoname);
}
}
self._towns(self._townsList);
});
}
}