JavaScript preserver plain json object while saving to json file - javascript

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>
)
});

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>
)
});
}

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.

Related

Object behaviour changed after assigned the variable

I have received a query/argument (matchQuery) from the client side through API.
When I console this request.query.matchQuery.on the server side it gives me {"count":{"$gt":1}} this is good for me.
when I assign this argument on the other variable like this
var aggregateQuery = {
$match: request.query.matchQuery
}
and now I console aggregateQuery its returns
{ '$match': '{"count":{"$gt":1}}' }
its behavior gets changed. But I don't want to single quotes on the right
side.
OUTPUT
{ '$match':{"count":{"$gt":1}}}
OR
{ $match:{"count":{"$gt":1}}}
OR
{ $match:{count:{$gt:1}}}
Best way to correct data that receive in serialized JSON is to parse it. JavaScript has JSON global object for facilitate JSON conversion and applied in application.
in your case evidence shows that request that came from client is like this:
"{\"count\":{\"$gt\":1}}"
but in your framework changed to STRING
typeof('{"count":{"$gt":1}}') ==> 'string'
that is not object
for use request.query.matchQuery as java script object your may convert it to JavaScript Object. for more details refer to below example:
var aggregateQuery = {
$match: JSON.parse(request.query.matchQuery)
}
Notice:
If you are not in STRICT MODE by adding
"use strict"
you can execute your code with
eval( code to be execute )
for examlpe
eval(`var e = { '$match':` + '{"count":{"$gt":1}}' + `}`)

Call a jquery function dynamically from a json object

Say, I have JSON data getting from API. I want to use a value of JSON key to call a user-defined jquery function.
The data I am getting from the server is :
{
"question":"What is your age?",
"graphType":"horizontalBar",
}
Now I am having a function in my script which is named as horizontalBar.
( function( $ ){
$.fn.horizontalBar = function(data){
//do some stuff
}
})( jQuery );
So, now I want something like this in order to call the function:
$().json.graphType(data);
Here is what I searched and tried to call it:
window[json.graphType](data);
What about:
$(<selector of target object>)[json.graphType](data);
This will apply the jquery-method named in json.graphType on the selected jQuery target object.
From your post I now guess, that you don't even have a selector. So, <selector of target object> is void:
$()[json.graphType](data);

Executing a script from jQuery GET request

I'm sending a GET request with jQuery
$.get("/index.html", /*Adding '?update' to the request*/ "update",
function (data) {/* Enter code here */}, "html");
where data is my server's response. I'm sending back a simple script like alert() so the 'data' variable equals <script> alert("Hello world!") </script>.
I need a way to automatically execute the script. I could just .append(data) to an element but I'm having multiple appends so that isn't really practical.
What is the easiest and the most practical way of executing the script?
Either .append it, like you said, or use eval(data), but then you'd have to get rid of the <script></script>. You can supply eval() a piece of Javascript code and it will execute that.
Please be aware that using eval should be avoided at all costs.
I did some crazy stuff in a case like this but you may think it is extreme. In my case I had to store some functions in localStorage and execute them by history state ( when user goes back/forth ). I have created a json object similar to
{obj:'myObject', fn: 'myfn', args: myArgs}
then stored this data base64 encoded. then when I need it back, I simply decoded content and
window.[data.fn].[data.obj].apply(null,data.args)`
did the trick without exposing too much data and not using eval. Eval comes from Evil so I would stay away. =)
UPDATE
So in my case all main core functions are json objects at window namespace similar to ( not actual content but an sample)
Member = {
initialize: function (){
//some process
},
render:function(memberId, selector){
//Some process
},
//...etc }
So when I store each item it, I used something similar to
var data = {obj: 'Member', fn: 'render', args: [1,'#member-block']}
then encoded version will be
localStorage.setItem('data', btoa(JSON.stringify(data)));
dmFyIGRhdGEgPSB7b2JqOiAnTWVtYmVyJywgZm46ICdyZW5kZXInLCBhcmdzOiB7bWVtYmVySWQ6MSwgc2VsZWN0b3I6ICcjbWVtYmVyLWJsb2NrJ319
Then when I need to call back
var data = JSON.parse(atob(localStorage.getItem('data'));
would return my original data object. Since the main functions in my case are in window namespace.
if (typeof window[data.obj]!=='undefined') { // same as window.Member
if (typeof window[data.obj][data.fn]!=='undefined' && typeof window[data.obj][data.fn]!=='function' ) { // make sure fn is defined and is a function
window[data.obj][data.fn].apply(null, data.args);
// we pass same arguments to function call with apply.
// `apply` will give us option to add arguments dynamically without knowing its size.
// it can be null any number of arguments that needed for that function.
}
}

Add function to JSON object with php

Is there any way to add function to JSON object with php?
i have an array in php like this :
$aoData = array(
array('name' => 0, 'value' => "id"),
array('name' => 1, 'value' => "title"),
array('name' => 2, 'value' => "cat"),
array('name' => 3, 'value' => "img"),
array('name' => 4, 'value' => "des"));
and i want add a function like this:
array('name' => 5, 'value' => function(){return "hi"})
and use this function in my jquery.
is there any way for this?
Update
in data table i need to set aoColumnDefs in php.
"aoColumnDefs":
[{
"aTargets": [ img ],
"mData": "thumb_img",
"mRender": function ( data, type, full )
return '<img src="../up/thumb/'+data+'">';
},
{etc}
]
so i need set function as a Json function or another way ...
JSON does not allow function definition for security and compatibility reasons, and as a proof, I don't see any other way than storing a string and use a form of eval (that is using eval or creating a Function with a body). I'd strongly recommend not to do it though.
In order for it to be JSON, and for any JSON library to work with it, no, it is not possible.
JSON is a language and platform independent, portable data serialization scheme and, therefore, has a limited set of things which can be represented within. Functions, given that they are language and platform specific, are not portable.
It is possible to use PHP to "manually" output a JavaScript object which has methods:
<?php
$foo = '{name: 5, value: function () { return "hi";}}'
?>
var js_object = <? echo $foo; ?>;
This is messy and error prone, however, and would not be JSON.
So yeah...
JS Object is not the same as JSON.
Some libs or frameworks will want to add functions to the JS Object.
For example primevue has a menu structure with functions in the Object:
const items = {
label: 'New',
icon: 'pi pi-plus',
command: (event) => {
// event.originalEvent: Browser event
// event.item: Menuitem instance
}
}
;
Nice, but what if you want this data provided from DB via php...?
this works:
const func = 'items.command = function(event){ console.log(event) }'
eval(func)
So we could do something with this.
This means doing something with the JSON when it is loaded into Javascript and turn some strings into functions with eval.
This is of course a security risk.
But somehow we'll need to change the JSON into a JS Object.
Better maybe is to not have info of the end platform in the DB.
The solution I'm using is that I'm pre-defining what commands can be added to the JS Object and use codes to tell the reader what I want added.
switch (add) {
case '[login]':
items.command: () => {
auth.destroyToken()
this.$router.push({ name: 'login' })
}
break;
}
Not as "free", but for security that's a good thing.
You can't add the function as value, but you can add the return value of the function as value of the json object.
So in the example you gave, the value will just be "hi" (if you type return correctly).
I don't see the reason for adding a function into a JSON object, because you can probebly do the same with JQuery and if you can't then use AJAX to get results from the serverside.

Passing function object references as serialized json

I have written some widgets using the jquery widget factory. Normally, I pass options and callback references using the widget constructor in a JavaScript code block.
Now I want to use the widgets in auto generated html pages and pass options to them without using JavaScript blocks. I am specifying the options in embedded json which a common JavaScript code block parses and passes it on to the widget.
<div id="search_widget">
<script type="application/json">
{
"search": {
"search_string": "text to be searched",
"callback": "a function object in an outer scope"
}
}
</script>
</div>
How do I pass the function objects preserving their scope to the widgets in json format ?
The widget will then call the function specified when a condition is met.
Thanks for your help.
You can pass the function body as text, but your receiving context will have to know it's a function and "reconstitute" it with the Function constructor (or something). You can't preserve the "scope", though that doesn't really mean much in a block of JSON.
You could also pass the function name, or some identifying pattern, or anything else you like, but all on the condition that the receiving code knows how to act on that.
JSON provides no mechanism for representing a "function". The concept is completely alien to the format, and rightly so, as it's intended to be language-neutral.
edit — Note that if you encode your function by name:
<script type="application/json">
{
"search": {
"search_string": "text to be searched",
"callback": "search_callback_23"
}
}
</script>
Then the code that grabs the object and interprets the contents can always invoke the function with the outer JSON object as the context:
function handleJSON( the_JSON_from_the_example ) {
var json = JSON.parse(the_JSON_from_the_example);
if ("search" in json) {
var searchTerm = json.search.search_string;
var callback = findCallbackFunction(json.search.callback); // whatever
callback.call(json, searchTerm); // or json.search maybe?
}
}
In other words, if the code that's interpreting the JSON-encoded information knows enough to find callback function references, then it can probably figure out an appropriate object to use as this when it calls the function.

Categories