I have a global variable data_year in a file called energy-maps.globals.v0.js
/**
* @type {number}
* @description The year value to determine data loaded by the application.
*/
var data_year = 2012;
data_year is used to modify a portion of an API url in order to switch the API endpoint to load data to the application. An example, from a file energy-maps.funcs.plants.v0.js:
let coal_plants = new PowerPlant('coal-plants', 'Coal plants', 1_092_000_000_000, 'electricity-generation', [{
draw_layer: draw_coal_plants,
src: [`${API_URL_PREFIX}/${data_year}/power_plants/coal`],
d3_fetch: d3.json,
}], 'COAL', 'rgba(0, 0, 0, .5)', plant_stroke);
API_URL_PREFIX is defined in energy-maps.globals.v0.js:
const API_URL_PREFIX = 'http://127.0.0.1:5000/api/v0.1.0/infrastructure'
The src property of coal_plants is being called in a function called load_layer_data in a file energy-maps.init.builder.v1.js, where src is passed as an argument to d3.json():
/**
* @description Call all draw methods for a given layer and render it
* to its canvas element. Uses a recursive call in special cases.
* @param {Object} lyr - An object from layers[].
* @memberof Init
*/
const load_layer_data = function load_layer_data(lyr) {
for (let i = 0, num_draw_props = lyr.draw_props.length; i < num_draw_props; ++i) {
start_loading_layer();
Promise.all(lyr.draw_props[i].src.map(x => lyr.draw_props[i].d3_fetch(x)))
.then(function(files) {
lyr.context.restore();
lyr.context.save();
return files;
}).then(files => {
transform_layer(lyr.context, transform);
return files
}).then(files => {
console.time('draw_layer')
lyr.draw_props[i].draw_layer(lyr.context, files);
console.timeEnd('draw_layer')
console.log(lyr.draw_props[i].src)
});
}
};
data_year is modified in energy-maps.init.builder.v1.js when attached to a click handler for a button that should change its value.
let create_year_button = function create_year_button(btn_val, year_val) {
let btn = document.createElement("button");
btn.innerHTML = `${btn_val} Data`;
document.getElementsByClassName('map-options-header')[0].appendChild(btn);
btn.classList.add('btn-year');
btn.addEventListener('click', function() {
btn_val = btn_val;
data_year = btn_val
console.log(data_year)
document.getElementById("value-year")
.innerHTML = `out of ${year_val} in ${btn_val}`;
})
}
create_year_button(2022, "$9.8T");
create_year_button(2012, "$9.8T");
When you click the button, the console will log the value of the button appropriately. When set to 2012, the API url is logged to the console as expected: ['http://127.0.0.1:5000/api/v0.1.0/infrastructure/2012/power_plants/coal']
But when data_year is changed to 2022, the API url remains unchanged: ['http://127.0.0.1:5000/api/v0.1.0/infrastructure/2012/power_plants/coal']
I read this post and tried to modify my code as follows in energy-maps.funcs.plants.v0.js, recognizing that string interpolation is not updated unless you declare it as a function:
const apiUrl = () => {
`${API_URL_PREFIX}/${data_year}/power_plants/coal`
}
const url = apiUrl()
let coal_plants = new PowerPlant('coal-plants', 'Coal plants', 681_740_400_000, 'electricity-generation', [{
draw_layer: draw_coal_plants,
src: [url],
d3_fetch: d3.json,
}], 'coal', 'rgba(0, 0, 0, .5)', plant_stroke);
And now when I load the data from the front end I get the following error:
GET http://127.0.0.1:3000/undefined 404 (NOT FOUND), with the application seemingly breaking at this line from energy-maps.init.builder.v1.js:
Promise.all(lyr.draw_props[i].src.map(x => lyr.draw_props[i].d3_fetch(x)))
From here I can't really tell what's going on. Any advice on how to properly update data_year across these files and have it render appropriately in my string interpolation?