Settings menu onchange variable handling

Posted on
  • I'm writing a menu with multiple boolean variable. The menu is populated on load, so I don't know ahead of time how many variables there are or what they are named. I am having an issue saving the value on change. My code is as follows:

    data = getDataStreams();
        Object.keys(data).forEach(function(k){
          name = data[k].description.split(" / ")[0];
          if (!settings.keys[name]) {
            // Setting doesn't exist, so we assume it's false
            settings.keys[name] = false;
          }
          submenu[name]= {value:settings.keys[name], onchange: v => {
            settings.keys[name] = v;
            writeSettings();
          }};
        });
    

    the "data" variable looks like this:

    [{"description":"DCP battery voltage / USGS-03272100-1964fee2501b43c5b7b807b687­319588"},
    {"description":"Discharge / USGS-03272100-1db72201226e4f50a94d0b65ab­c8e7a5"},
    {"description":"Gage height / USGS-03272100-56a7245f4b47438cb79c40f0d0­0605ba"},
    {"description":"Temperature, water / USGS-03272100-f8e8a724a5c3498ca11bf1a31b­e5a537"}]
    

    The submenu populates like this:

    
    {
      "": {
        "title": "-- DataStreams --"
       },
      "< Back": function () {E.showMenu(menu);},
      "DCP battery voltage": { "value": false,
        "onchange": function (v) {
      settings.keys[name] = v;
            writeSettings();
    }
       },
      "Discharge": { "value": true,
        "onchange": function (v) {
      settings.keys[name] = v;
            writeSettings();
    }
       },
      "Gage height": { "value": true,
        "onchange": function (v) {
      settings.keys[name] = v;
            writeSettings();
    }
       },
      "Temperature, water": { "value": true,
        "onchange": function (v) {
      settings.keys[name] = v;
            writeSettings();
    }
       }
     }
    

    The issue is that when the "onchange" function runs, name is set to the most recent loop of the foreach, herein "Temperature, water". However, I want it to reflect what the variable "name" was set to when the submenu item was added to the submenu object.

    I could convert the function to a string, replace the variable with its value, and then convert back to function within each iteration of the loop, but that strikes me as messy. Does anyone know a better way of doing this?

  • Your issue is you're not defining name locally, so it's a global variable and just ends up filled with the last value you set it to. If you change:

    data = getDataStreams();
        Object.keys(data).forEach(function(k){
          name = data[k].description.split(" / ")[0];
    

    to

    data = getDataStreams();
        Object.keys(data).forEach(function(k){
          var  name = data[k].description.split(" / ")[0];
    

    Then name ends up defined locally in the function defined inside forEach, so each key in data has its own version of name set.

  • That's exactly it, thank you!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Settings menu onchange variable handling

Posted by Avatar for user156125 @user156125

Actions