I'm trying to create a simple abstraction using Google charts, I've created a chartservice which will serve as the abstraction. The module supplies the options and data-source, and the service takes care of the rest(data is supplied by a REST API).
Here is the current code, works only for one case:
createCombo(comboBarLabels: String[], comboBarTypes: String[], options: any, element: any) {
this.overviewService.getOverviewAggBarData().pipe(first()).subscribe(comboRequest => {
for (const index of Object.keys(comboRequest.comboData)) {
comboRequest.comboData[index].unshift(comboBarLabels[index]);
}
const data_array = [comboBarTypes, comboRequest.comboData[0],
comboRequest.comboData[1], comboRequest.comboData[2]];
google.charts.load('current', {'packages': ['corechart']});
google.charts.setOnLoadCallback(() => {
const data = ChartService.createDataTable(data_array);
const chart = new google.visualization.ComboChart(element);
chart.draw(data, options);
});
});
}
What I want to achieve is to remove this.overviewService.getOverviewAggBarData() and replace it by a conditional function, something like this in python:
def foo(a, b): # Adds two numbers
return a + b
a = foo
print(a(1, 2)) # Prints 3
To make something that looks like this:
createCombo(comboBarLabels: String[], comboBarTypes: String[], options: any, element: any, source: any) {
if (source == "OverviewAggBar"){
get_data = this.overviewService.getOverviewAggBarData;
} else {
get_data = this.overviewService.getOverviewPieData;
}
get_data().pipe(first()).subscribe(comboRequest => {
for (const index of Object.keys(comboRequest.comboData)) {
comboRequest.comboData[index].unshift(comboBarLabels[index]);
}
const data_array = [comboBarTypes, comboRequest.comboData[0],
comboRequest.comboData[1], comboRequest.comboData[2]];
google.charts.load('current', {'packages': ['corechart']});
google.charts.setOnLoadCallback(() => {
const data = ChartService.createDataTable(data_array);
const chart = new google.visualization.ComboChart(element);
chart.draw(data, options);
});
});
}
The reason that I want to do this is because the function call is very involved, being able to abstract this part away paves the way for making an even more general function. Other solutions to achieve the same goal are more than welcome!
Solved, here's the new code:
createCombo(comboBarLabels: String[], comboBarTypes: String[], options: any, element: any, source: string) {
let getData: any;
if (source === 'getAggData') {
getData = this.overviewService.getOverviewAggBarData.bind(this);
} else {
getData = this.overviewService.getOverviewPieData.bind(this);
}
getData().pipe(first()).subscribe(comboRequest => {
const data_array = [comboBarTypes];
for (const index of Object.keys(comboRequest.comboData)) {
comboRequest.comboData[index].unshift(comboBarLabels[index]);
data_array.push(comboRequest.comboData[index]);
}
google.charts.load('current', {'packages': ['corechart']});
google.charts.setOnLoadCallback(() => {
const data = ChartService.createDataTable(data_array);
const chart = new google.visualization.ComboChart(element);
chart.draw(data, options);
});
});
}
getOverviewAggBarDataandgetOverviewPieDataimplemented? Do they referencethis? If so, are they arrow functions? I ask because when you assign functions to a variable like this, they could potentially lose context. (Not a huge problem, just wanted to mention it).return this.http.get<OverviewData>('http://127.0.0.1:8080/combodata');Maybe i should just define the function inside of the other function since it's so short.get_data = () => this.overviewService.getOverviewAggBarData();