0

May I know how can I preserve the plain JSON object while I save to .json file and retrieve from the json file in the properly way.

const jsonObj = [
        {
            min:1,
            max:4,
            defaultValue:3,
            width:"100%",
            label:"Column",
            onChange:(evt) => adjustGrid("col", evt),
            type:"InputNumber"
        },
        {
            min:1,
            max:4,
            defaultValue:1,
            width:"100%",
            label:"Row",
            onChange:(evt) => adjustGrid("row", evt),
            type:"InputNumber"
        }
    ]

The intention of preserving the plain JSON object is because I want to achieve fully dynamic form element controls with the helps of JSON object.

I have attempted to use JSON.stringify but it escape the onChange key-pair which makes I cannot retrieve back the onChange key when I retrieve it from my .JSON file.

the onChange function is not restricted for adjustGrid function, it can be any function that has been defined in the JS file.

The render code will be:

 return jsonObj.map((v) => {
            return (
                <Form.Item label={v.type}>
                        <InputNumber
                        min={v.defaultValue}
                        max={v.max}
                        defaultValue={v.defaultValue}
                        {...v}
                        width={v.width}
                      />
                </Form.Item>
            )
        });
Miracle Hades
  • 146
  • 2
  • 10
  • 1
    you need JSON.stringify to convert that **object** to JSON - however, you will lose the `functions` as JSON does not contain functions – Bravo Mar 06 '22 at 04:38
  • If the method is going to be the same, and the only difference is the first argument (`col` vs `row`), just store the argument and run the method with that. – yaakov Mar 06 '22 at 04:39
  • @Bravo I cant lose the functions because the dynamic form elements generator rely on the function to trigger onChange event on the created form element. – Miracle Hades Mar 06 '22 at 04:41
  • @traktor may I know how can I preserve those functions and key-pairs in the external file and I can load it when I need it. If the JSON file architecture is not suitable for this case scenario, could you suggest me any other alternate solution – Miracle Hades Mar 06 '22 at 04:44
  • Please show the enclosing code so we can recommend how to move the handler functions elsewhere, for example by checking the label property and then attaching the proper handler – fotoflo Mar 06 '22 at 04:48
  • @fotoflo please check the updated main thread for reading and render the jsonObj into a functional UI components – Miracle Hades Mar 06 '22 at 04:51
  • Maybe move `adjustGrid` into its own library file, and import it into this JS file. And then import this file into your component. No JSON. – Andy Mar 06 '22 at 04:54
  • `I cant lose the functions` - then you can't use JSON – Bravo Mar 06 '22 at 04:58
  • previous comments posted as an answer. – traktor Mar 06 '22 at 05:01

2 Answers2

0

JSON

There is no "JSON Object" to start with, if such a thing can be said to exist: JSON is a notation syntax for serializing data objects. By design it does not serialize object properties that are functions, does not distinguish between null and undefined, and can't encode objects with cyclic property references.

JavaScript

You could use a JavaScript file containing the text in the post - which is JavaScript source code and not JSON anyway. If you don't want to create or make use of global variables in the script, you could use export and import statements for jsonObj from within script files of type "module". The downside for modules is that they are not available using the file:// protocol and must come from a server.

traktor
  • 17,588
  • 4
  • 32
  • 53
  • I have attempted to moved that jsonObj to a file called "jsonObj.js" but it turn out the adjustGrid caused an error as adjustGrid is not defined. – Miracle Hades Mar 06 '22 at 05:09
  • The code in jsonObj.js is exports.jsonObjj = ["the json obj"] – Miracle Hades Mar 06 '22 at 05:09
  • If the [use of import/export in React](https://reactjs.org/docs/code-splitting.html) is compatible with the ES6 module system you would be looking at exporting `adjustGrid` from the file where it is defined so you can import it in another module (for jsonObj). Modules can only import and export to other modules. See [this question](https://stackoverflow.com/q/53630310/5217142) for some of the implications. – traktor Mar 06 '22 at 05:24
0

You can't get a function from a stringified Object.

You want to keep code in source control, not in data, so it's a bad practice to do that. Also, it's a security hazard to have executable code in data...

I suggest extracting the handlers and using a conditional:

If you have more handlers, you can create a choose handler function, but i just inlined it here...

const InputItem = ()=>{

  const rowHandler = (evt) => adjustGrid("row", evt)
  const colHandler = (evt) => adjustGrid("col", evt)

  return jsonObj.map((v) => {
    return (
        <Form.Item label={v.type}>
                <InputNumber
                //...other properties
                onChange = {v.label == "Column" ? colHandler : rowHandler}
              />
        </Form.Item>
    )
  });
}
fotoflo
  • 821
  • 1
  • 9
  • 21