0

I have the following in my script

var mycolor = 'blue';
var option;
option = {
  grid: {
    color: mycolor
  },
  axis: {
    color: mycolor
  }
}

Then, I want to change it to red. usual way would be

option.grid.color = 'red'
option.axis.color = 'red'

This way it works; however, when I try mycolor='red', it is not updated in var option. How can I in one line change the color in option? For example, I want a command like option.*.color = red. Thanks

stats con chris
  • 178
  • 1
  • 10
  • You change it to a method or getter and have it return the variable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get – Lee Feb 24 '22 at 13:41
  • 1
    There is no variable in the object. The *value* of the variable, at the time of object creation, is used to define a property of the object that is completely independent from the variable. – Bergi Feb 24 '22 at 13:45
  • Thanks but is not what I'm looking @tom. color can be in different sublevels within option. So I really need a way where the script reads the lines of option and whenever it sees ''color', would change its value. If it is a method, could you share an example please. I do need to keep the json format of option as it is called by my chart – stats con chris Feb 24 '22 at 13:51

2 Answers2

1

Objects are "references" until you clone them, so this works:

var myColor = { color: 'blue' };
var option;

option = {
  grid: myColor,
  axis: myColor,
};

console.log(option); // { grid: { color: 'blue' }, axis: { color: 'blue' } }

myColor.color = 'red';

console.log(option); // { grid: { color: 'red' }, axis: { color: 'red' } }

Note that you don't reassign the myColor variable here, that would not work; instead you set the color property inside of the object which is used twice in the options, thus updating the value inside of the referenced object in the options as well.

geisterfurz007
  • 5,292
  • 5
  • 33
  • 54
  • Thanks. This is close to want I wanted. The problem is that grid or axis may have other properties so they are not symmetric. I wish your approach allows me to write more parameters for grid and axis without messing up the code. is it possible? – stats con chris Feb 25 '22 at 00:47
  • The object "reference" must stay intact, as long as that holds true, it is going to work. You might have to introduce another level of nesting though to allow for that. – geisterfurz007 Feb 25 '22 at 08:03
1

What you try to do is not assign a variable to the option but just pass the value to the properties of the object.

You can use a setter in the option object.

option = {
    grid: {
        color: "red",
    },
    axis: {
        color: "red",
    },
    set color(color) {
        this.grid.color = color;
        this.axis.color = color;
    },
};

console.log(option.grid.color);
console.log(option.axis.color);

option.color = "blue";

console.log(option.grid.color);
console.log(option.axis.color);

Edit: update all the properties with name color in the object

option = {
    grid: {
        color: "red",
    },
    axis: {
        color: "red",
    },
    set allColor(color) {
        const setColor = obj => {
            if (
                typeof obj === "object" &&
                !Array.isArray(obj) &&
                obj !== null
            ) {
                Object.keys(obj).forEach(key => {
                    if (key === "color") {
                        obj[key] = color;
                    }
                    setColor(obj[key]);
                });
            }
        };

        setColor(this);
    },
    get allColor() {
        return null;
    },
};

console.log(option);

option.allColor = "blue";

console.log(option);
ikhvjs
  • 5,316
  • 2
  • 13
  • 36
  • Thanks but this is similar to my approach: option.grid.color = 'red', option.axis.color = 'red'. I have several fields, so I would need to type 20 lines in set and that's what I want to avoid. – stats con chris Feb 25 '22 at 00:41
  • @statsconchris, I update my answer. Now, you don't need to type multiple lines to set the colors. – ikhvjs Feb 25 '22 at 07:53