1

I've found and read posts about using variables inside bracket notation to access object properties (like this one), but it works only for objects with no depth. In my case I have an object with properties on different levels of depth and I want to access them dynamically using a variable.

Here's what my object looks like (it's an example obviously) :

{
  settings: {
    datasets: [
      {
        label: "Suivi",
        type: "line",
        backgroundColor: "#2bb0e9",
        borderColor: "#2bb0e9",
        pointBackgroundColor: "#2bb0fc",
        pointBorderColor: "#2bb0fc",
        pointRadius: 0,
        data: [],
        cubicInterpolationMode: "monotone",
        tension: 0.4,
      },
    ],
  },
  config: {
    maintainAspectRatio: false,
    plugins: {
      legend: {
        display: false,
      },
      tooltip: {
        callbacks: {
          label: function (context) {
            let label = "";
            if (
              context.dataset.backgroundColor[context.dataIndex] !== "#f4f4f4"
            ) {
              label = context.formattedValue;
            } else {
              label = "No information";
            }
            return label;
          },
        },
      },
    },
  },
}

So I may want to access object.config.maintainAspectRatio (3 levels of depth) or object.settings.datasets[0].backgroundColor (5 levels of depth) among other things.

I have a function that is supposed to update this object dynamically, it receives both path and newValue.

What I've tried :

  1. putting the entire path in a single string (ex : "settings.datasets[0].label") and trying to access object[path] : it doesn't work.
  2. putting all different depth levels in an array of strings (ex : ["settings", "datasets", "0", "borderColor"]). It works but it requires something like this :
if(path[8]){
      stockInfo[path[0]][path[1]][path[2]][path[3]][path[4]][path[5]][path[6]][path[7]][path[8]] = newValue;
    } else if(path[7]){
      stockInfo[path[0]][path[1]][path[2]][path[3]][path[4]][path[5]][path[6]][path[7]] = newValue;
    } else if(path[6]){
      stockInfo[path[0]][path[1]][path[2]][path[3]][path[4]][path[5]][path[6]] = newValue;
    } else if(path[5]){
      stockInfo[path[0]][path[1]][path[2]][path[3]][path[4]][path[5]] = newValue;
    } else if(path[4]){
      stockInfo[path[0]][path[1]][path[2]][path[3]][path[4]] = newValue;
    } else if(path[3]){
      stockInfo[path[0]][path[1]][path[2]][path[3]] = newValue;
    }

Which looks like awfully bad practice.

Is there a better way to do it ?

FlowRan
  • 119
  • 1
  • 15
  • There was an answer in the mentioned topic. I guess this is your solution https://stackoverflow.com/a/45322101/18891587 – Jaood_xD Jul 01 '22 at 08:41
  • It seems like it works as a getter (even though I get `null`) but not as a setter @Jaood_xD – FlowRan Jul 01 '22 at 12:53
  • Try to use it without last path item to get container of your value. Since you'll get reference to the original object, you can update it manualy. instead of `stockInfo['one.two.tree.four']=newValue` use `stockInfo['one.two.tree'].four=newValue – Jaood_xD Jul 01 '22 at 13:14

0 Answers0