0

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?

2
  • 1
    Perhaps you don't need a string, but instead a function that returns a string. Commented Dec 19, 2022 at 22:29
  • @tadman Would that be different from the modification I made to energy-maps.funcs.plants.v0.js after the stack overflow post I mentioned towards the end of my post? Commented Dec 19, 2022 at 23:19

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.