Is there a way to build object constructors from a JSON schema? I want to create a json schema associated with my application's namespace that I can edit once, and change the properties(before runtime) of my objects.
I know that you can write a pseudo classical object constructor like
var Note = function(input){
var title = input
};
var newNote = new Note("test title");
Is it possible to create a similar structure from json? Such that I can write:
var Note = {
"title":""
};
var newNote = new Note();
newNote.title = "test title"
I understand that this above is syntactically wrong, but I would like to for example have:
var notes = {
"NotesList":[{
"title":"note1",
"content":"test content"
}]
}
var newNote = new Note();
notes.NotesList.add(newNote);
newNote.title = "new title";
so that I can base all my objects and all of their children off of this object template created from my json schema. If this is not possible, can you recommend a better method?
I'm not sure that I understood your question completely. However if you wish to convert a function into JSON then yes, that's definitely possible.
All you need to do is use a JavaScript parser like acorn which uses the Mozilla Parser API to generate an abstract syntax tree of your constructor in JSON format. For example:
var ast = acorn.parse(Note);
var json = JSON.stringify(ast, null, 4);
alert(json);
function Note(input) {
var title = input;
}
See the demo here. The above code produces the following output:
{
"type": "Program",
"start": 0,
"end": 47,
"body": [
{
"type": "FunctionDeclaration",
"start": 0,
"end": 47,
"id": {
"type": "Identifier",
"start": 9,
"end": 13,
"name": "Note"
},
"params": [
{
"type": "Identifier",
"start": 14,
"end": 19,
"name": "input"
}
],
"body": {
"type": "BlockStatement",
"start": 21,
"end": 47,
"body": [
{
"type": "VariableDeclaration",
"start": 27,
"end": 44,
"declarations": [
{
"type": "VariableDeclarator",
"start": 31,
"end": 44,
"id": {
"type": "Identifier",
"start": 31,
"end": 36,
"name": "title"
},
"init": {
"type": "Identifier",
"start": 39,
"end": 44,
"name": "input"
}
}
],
"kind": "var"
}
]
}
}
]
}
You can save the above AST in a JSON file and load it as and when required. You can use escodegen to convert the AST back to JavaScript as follows:
alert(escodegen.generate(ast));
See the demo here. You may then eval the generated code and use the Note constructor as you wish.
I found the answer to what I was looking for. My ultimate goal was to make an object with arrays of children, each of which could have children etc. The object would then be used as the namespace to my entire application like:
var myobj = {};
I wanted to use JSON to specify the properties of this object, and then build constructors off of these properties like:
var myObj = {
"name": "genericname",
"id": "uniqueid",
"children": [
{
"grandchildren": [
{
"name": "child",
"age": "0"
}
]
}
]
};
What I ended up doing was, building constructor functions from this, and then cloning them into my new objects so they could have these default values like this:
myObj.Child = function(){
var child = myObj.children[0];
return child;
//this is the unmodified constructor child
};
var myObj.createChild = function(){
var newChild = new Clone(myObj.Child());
//do stuff to this is new child which can be modified without changing the original
return newChild;
};
Related
I got a JSON string with an array like this:
{
"Id": 123,
"Username": "Sr. X",
"Packages": [
{
"Name": "Cups",
"SupplierId": 1,
"ProviderGroupId": 575,
"SupplierName": "Foo Cups"
},
{
"Name": "Pins",
"SupplierId": 5,
"ProviderGroupId": 1082,
"SupplierName": "Foo Pins"
}
]
}
and I want to add a new field into Packages array like:
"Packages": [
{
"Name": "Cups",
"SupplierId": 1,
"ProviderGroupId": 575,
"SupplierName": "Foo Cups",
"New Field": "Value"
},...
Right now I can add a new field but in the main object, I'm using Json.NET library to do the job, but it seems that the documentation doesn't reach that level.
Have any one of you done it before?
JObject implemets IDictionary.
var jObj = JObject.Parse(json);
foreach(var item in jObj["Packages"])
{
item["New Field"] = "Value";
}
var newjson = jObj.ToString(Newtonsoft.Json.Formatting.Indented);
Try
JObject root = (JObject) JsonConvert.DeserializeObject(File.ReadAllText("products.json"));
JArray packages = (JArray) root["Packages"];
JObject newItem = new JObject();
newItem["Name"] = "Cups";
// ...
packages.Add(newItem);
Console.WriteLine(root); // Prints new json
I am working on a node.js API for an app with a simple TCP server that accepts NDJSON (essentially delimited by '\r\n'). Anyway, I am having an issue with JSON stringify. I create an object (see below) with variables and then convert it to stringify. When I get the result, it's expanded all the variables except for "requestParamName." It's the only key, as opposed to being a value, and this is the result:
{"jsonrpc":"2.0","method":"Client.SetVolume","id":0,"params":{"client":"00:00:00:00:00:00","requestParamName":10}}
It should be this:
{"jsonrpc":"2.0","method":"Client.SetVolume","id":0,"params":{"client":"00:00:00:00:00:00","volume":10}}
I've tried several things, but I'm not sure what's causing it to not expand that particular variable. If anyone has any suggestions, I'd be grateful.
Function:
function ClientConnect(requestMethod, requestMacAddress, requestParamName, requestParamKey) {
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress,
requestParamName: requestParamKey
}};
formattedJson = (JSON.stringify(objectRequest) + '\r\n');
console.log(formattedJson);
}
P.S. I'm new here so if I messed up the formatting, I apologize ;)
Actually doing :
"params": {
"client": requestMacAddress,
requestParamName: requestParamKey
}};
is exactly the same that :
"params": {
"client": requestMacAddress,
"requestParamName": requestParamKey
}};
You have to do like this (note that it's an ES6 feature - it's ok if you use a recent node.js):
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress,
[requestParamName]: requestParamKey
}};
The ES5 version will be:
var objectRequest = {
"jsonrpc": "2.0",
"method": requestMethod,
"id": 0,
"params": {
"client": requestMacAddress
}};
objectRequest[requestParamName]= requestParamKey;
[variable] is what you need, otherwise it will be the same as above ^^
I'm creating a JSON object from an array and I want to dynamically push data to this JSON object based on the values from array. See my code for a better understanding of my problem...
for(i=0;i<duplicates.length; i++) {
var request = {
"name": duplicates[i].scope,
"id": 3,
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
I take object properties from the duplicates array that can have the following elements:
[{scopeDef=.*, scope=Global, variable=[trackingcode, v1, v2]}, {scopeDef=^https?://([^/:\?]*\.)?delta.com/products, scope=Products Section, variable=[v3]}]
As you can see, an object contain variable element that can have multiple values. I need to push to the JSON object all those values dynamically (meaning that there could be more than 3 values in an array).
For example, after I push all the values from the duplicates array, my JSON object should look like this:
name=Products Section,
rules=
[
{
name=Products Section OP SDR Sync,
tags=[
{
variables=
[
{
matchType=Regex,
variable=v3,
value=^https?://([^/:\?]*\.)?delta.com/products
},
{
matchType=Regex,
variable=trackingcode,
value=.*
},
{
matchType=Regex,
variable=v1,
value=.*
},
{
matchType=Regex,
variable=v2,
value=.*
}
],
condition=false,
},
{
condition=false,
tagId=1
}
],
ruleSetId=3
}
]
}
I tried the following code but without success:
for(var j in duplicates[i].variable) {
var append = JSON.parse(request);
append['variables'].push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
}
Please let me know if I need to provide additional information, I just started working with JSON objects.
First of all, you dont need to parse request, you already create an object, parse only when you get JSON as string, like:
var json='{"a":"1", "b":"2"}';
var x = JSON.parse(json);
Next, you have any property of object wrapped in arrays. To correctly work with it you should write:
request.rules[0].tags[0].variables.push({
"variable":duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
})
If you want to use your code snippet, you need some changes in request:
var request = {
"name": duplicates[i].scope,
"id": 3,
"variables":[
{
"variable": duplicates[i].variable[j],
"matchType": "Regex",
"value": duplicates[i].scopeDef
}
],
"rules":[
{
"name": duplicates[i].scope + " " + "OP SDR Sync",
"tags": [
{
"tagId": 1,
"condition": false,
},
{
"tagId": 1,
"condition": false,
}
],
"ruleSetId": 3,
}
]
}
}
To understand JSON remember basic rule: read JSON backward. It means:
property
object.property
arrayOfObfects['id'].object.property
mainObject.arrayOfObfects['id'].object.property
and so on. Good luck!
I need to remove an object from an JSON tree. I know a reference to that object. Is there a nice way to do it via JavaScript or jQuery besides traversing the whole tree?
Example:
party = {
"uuid": "4D326531-3C67-4CD2-95F4-D1708CE6C7A8",
"link": {
"rel": "self",
"href": "http://localhost:8080/cim/party/4D326531-3C67-4CD2-95F4-D1708CE6C7A8"
},
"type": "PERSON",
"name": "John Doe",
"properties": {
"CONTACT": [
{
"category": "CONTACT",
"type": "EMAIL",
"key": "email",
"value": "john.doe#doe.at",
"id": "27DDFF6E-5235-46BF-A349-67BEC92D6DAD"
},
{
"category": "CONTACT",
"type": "PHONE",
"key": "mobile",
"value": "+43 999 999990 3999",
"id": "6FDAA4C6-9340-4F11-9118-F0BC514B0D77"
}
],
"CLIENT_DATA": [
{
"category": "CLIENT_DATA",
"type": "TYPE",
"key": "client_type",
"value": "private",
"id": "65697515-43A0-4D80-AE90-F13F347A6E68"
}
]
},
"links": []
}
And i have a reference: contact = party.properties.contact[1]. And I want to do something like delete contact.
You may delete it this way. I just tested it.
var party = {
// ...
}
alert(party.properties.CONTACT[0]) // object Object
delete party.properties.CONTACT[0] // true
alert(party.properties.CONTACT[0]) // undefined
Fiddle
UPDATE
In the case above party is a direct property of window object
window.hasOwnProperty('party'); // true
and that's why you can't delete a property by reference. Anyhow, behavior of delete operator with host objects is unpredictable. Though, you may create a scope around the party object and then you'll be allowed to delete it.
var _scope = {};
var _scope.party = {
// ...
};
var r = _scope.party.properties.CONTACT[0];
window.hasOwnProperty('party'); // false
alert(r) // object Object
delete r // true
alert(r) // undefined
It only works one way: a variable holds a reference, but there is no way given a particular reference to infer what variables hold it (without iterating over them and comparing).
I wrote a quick script to parse two fairly large json file (~17k records) to do a comparison of the two. I have confirmed they are both valid json (via jsonlintpro) and the same format. (The source is the same so this should be a given. But, I always assume the mistake is mine. And I still do. Just somewhere else.) However, the parsed file just outputs [object, Object]. I'm wondering what the cause could possibly be?
The json format is like this small snippet (anonymized of course):
[
{
"id": "1234",
"name": "Name1",
"url": "https://localhost/Name1",
"date_created": "2013-07-05T18:47:05Z",
"date_cancelled": "",
"props": [
{
"id": "54321",
"type": "Client",
"value": "General Store"
},
{
"id": "65432",
"type": "Contact_Name",
"value": "Joe Smith"
}
]
},
{
"id": "23456",
"name": "Name2",
"url": "https://localhost/Name2",
"date_created": "2014-02-27T17:46:43Z",
"date_cancelled": "",
"props": [
{
"id": "34567",
"type": "Client",
"value": "Bait Shop"
}
]
}]
And here is the pertinent code:
var _ = require('underscore');
var recs = require('./prod.json');
printArr(recs);
console.log(recs.length);
function printArr(arr) {
arr.forEach(function(item) {
console.log(item + ", ");
});
}
Any guidance would be greatly appreciated.
UPDATE:
Ok, so apparently the issue is with my printArr function. I'm not sure what I'm doing wrong there. I'd like to figure it out because I want to expand upon that so I can print selectively.
the parsed file just outputs [object, Object].
This is the expected behavior BECAUSE you are concatenating an object with a string.
Try console.log(item) instead
console.log(item); should indeed print [object, Object], did you try to output its properties instead?
function printArr(arr) {
arr.forEach(function(item) {
console.log( item.id, item.name, item.url, item.date_created, item.date_cancelled, item.props, ';');
});
}
Just export the value from the prod.json file.
prod.json file
module.exports = [
{
"id": "1234",
"name": "Name1"
},
{
"id": "1234",
"name": "Name1"
}]
elsewhere
var recs = require('./prod.json')
console.log(recs)