Are references possible in JSON? - javascript

Is it possible to assign references to objects in JSON? I have data that looks like this:
[{
name:"name",
Parent:[{
name:"parentName"
Parent:[{
.....//and so on
}]
}]
}]
I need to traverse it in JavaScript and also change the person's name. How can I do this?

Old question but some possibly new answers like JSON Spec and JSON Reference https://json-spec.readthedocs.io/reference.html
[{
"name": "John",
},
{
"name" : "Jack",
"parent": {"$ref": "#/0"}
},
...
]
or possibly better with JSON Path syntax http://goessner.net/articles/JsonPath/
[{
"name": "John",
},
{
"name" : "Jack",
"parent": {"$ref": "$.[?(#.name=='John')]"}
},
...
]

You can't. You can specify the path to the parent as a string and evaluate that at runtime, but as JSON is just strings, integers, arrays, and dictionaries, you can't use references.

Related

Parsting tree with getJson

I have a JSON file with order data. The JSON file is formatted like this:
{
"orders": [
{"name": "Peter", "email": "peter#aol.com"}
{"name": "David", "email": "david#aol.com"}
{ "name": "George", "email": "george#aol.com"}
]
}
As you can see; all the data is part of a branch called "orders" and then each order is its own branch, but the branch doesn't have a name.
I am trying to generate a list of the "name"s in the dataset.
With a simplified dataset, I would do something like:
$(data).each(function(i, name){
$('#namesText').append($("li")
.append($("li").append(name.name))
});
})
This however doesn't work as the data is not in the first level of the tree.
My question is, how do I go down levels when the levels don't have a name?
This sounds like a DFS problem where each object has keys that can possibly be a primitive data type or another object. Since the name field could be at any level in this given constraint you need to solve for, I would say use DFS algo where it traverses each key in the object and if there is another object, look into that until you find a name field. Better solution is to redesign the data structure so that you are guaranteed to know which level and location the name field is at any time.
If you want a list of the name property from the elements of the orders array you could use Array.map:
const names = myJson.orders.map(o => o.name);
Try
namesText.innerHTML= data.orders.map(p=>`<li>${escape(p.name)}</li>`).join``
var data = {
"orders": [
{
"name": "Peter",
"email": "peter#aol.com",
},
{
"name": "David",
"email": "david#aol.com",
},
{
"name": "George",
"email": "george#aol.com",
}
]
}
namesText.innerHTML= data.orders.map(p=>`<li>${escape(p.name)}</li>`).join``
<ul id="namesText"></ul>

Accessing property with space in template expression

I have the below code structure:
"name": {
"age": [
{
"data": {
"how old": "23"
}
},
my JSON key having space. How to access the property in an Angular template? I was doing the below but it's giving an error.
<span>{{age.data.'how old'}}</span>
{{age.data['how old']}}
or, probably
{{name.age[0].data['how old']}}

Indexing array values in an object in an IndexedDB

For a Chrome app, wich stores data in IndexedDB, i have a object like this:
var simplifiedOrderObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"address": "Foostreet 12, 12345 Bar York",
"orderitems": [
{
"item": "brush",
"price": "2.00"
},
{
"item": "phone",
"price": "30.90"
}
],
"parcels": [
{
"service": "DHL",
"track": "12345"
},
{
"service": "UPS",
"track": "3254231514"
}
]
}
If i store the hole object in an objectStore, can i use an index for "track", which can be contained multiple times in each order object?
Or is it needed or possibly better/faster to split each object into multiple objectStores like know from relational DBs:
order
orderitem
parcel
The solution should also work in a fast way with 100.000 or more objects stored.
Answering my own question: I have made some tests now. It looks like it is not possible to do this with that object in only 1 objectStore.
An other example object which would work:
var myObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"shipping": {"method": "letter",
"company": "Deutsche Post AG" }
}
Creating an index will be done by:
objectStore.createIndex(objectIndexName, objectKeypath, optionalObjectParameters);
With setting objectKeypath it is possible to address a value in the main object like "name":
objectStore.createIndex("name", "name", {unique: false});
It would also be possible to address a value form a subobject of an object like "shipping.method":
objectStore.createIndex("shipping", "shipping.method", {unique: false});
BUT it is not possible to address values like the ones of "track", which are contained in objects, stored in an array. Even something like "parcels[0].track" to get the first value as index does not work.
Anyhow, it would be possible to index all simple elements of an array (but not objects).
So the following more simple structure would allow to create an index entry for each parcelnumber in the array "trackingNumbers":
var simplifiedOrderObject = {
"ordernumber": "123-12345-234",
"name": "Mr. Sample",
"address": "Foostreet 12, 12345 Bar York",
"orderitems": [
{
"item": "brush",
"price": "2.00"
},
{
"item": "phone",
"price": "30.90"
}
],
"trackingNumbers": ["12345", "3254231514"]
}
when creating the index with multiEntry set to true:
objectStore.createIndex("tracking", "trackingNumbers", {unique: false, multiEntry: true});
Anyhow, the missing of the possibility to index object values in arrays, makes using indexedDB really unneeded complicated. It's a failure in design. This forces the developer to do things like in relational DBs, while lacking all the possibilities of SQL. Really bad :(

Can a JSON array contain objects of different key/value pairs?

Can a JSON array contain Objects of different key/value pairs. From this tutorial, the example given for JSON array consists of Objects of the same key/value pair:
{
"example": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
If I want to change it to have different key/value pairs inside the JSON array, is the following still a valid JSON?
{
"example": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"fruit": "apple"
},
{
"length": 100,
"width": 60,
"height": 30
}
]
}
Just want to confirm this. If so, how can I use JavaScript to know if the JSON "example" field contains the first homogeneous objects or the second heterogeneous objects?
You can use any structure you like. JSON is not schema based in the way XML is often used and Javascript is not statically typed.
you can convert your JSON to a JS object using JSON.parse and then just test the existence of the property
var obj = JSON.parse(jsonString);
if(typeof obj.example[0].firstName != "undefined") {
//do something
}
It doesn't matter you can mix and match as much as you want.
You could just test it
typeof someItem.example !== 'undefined' // True if `example` is defined.
It's perfectly valid JSON. Personally I prefer this syntax better, because it reads easier:
{
"example": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"fruit": "apple"
},
{
"length": 100,
"width": 60,
"height": 30
}
]
}
As to answer your second question, you can read data from a JSON string by using var data = JSON.parse(datastring);. Then simply use it by calling data.property.secondlevel. Any variable can be an object, array, string or number, allowing for nested structures.
You are free to do what you want with the contents of the array. Jus remember about this before you try to iterate an access properties of each item in your array.
one thing: you won't be able to deserialize this to anything else than an array of object in your server side, so don't have surprises later.
as a hint, maybe you could include a common field in the objects specifying the "type" so later is easy to process.
var array = [{"type":"fruit", "color":"red"},
{"type":"dog", "name":"Harry"}];
var parser = {
fruit:function(f){
console.log("fruit:" + f.color);
},
dog: function(d){
console.log("dog:"+d.name);
}};
for(var i=0;i<array.length;i++){
parser[array[i].type](array[i]);
}

How to search and select an object in JSON

Consider a JSON like this:
[{
"type": "person",
"name": "Mike",
"age": "29"
},
{
"type": "person",
"name": "Afshin",
"age": "21"
},
{
"type": "something_else",
"where": "NY"
}]
I want to search in the JSON value with a key (for example type='person') and then select a whole object of matched item in JSON. For example when I search for type='person' I expect this value:
[{
"type": "person",
"name": "Mike",
"age": "29"
},
{
"type": "person",
"name": "Afshin",
"age": "21"
}]
Because it's a really big JSON value, I don't want to do a brute-force search in all nodes, so I think the only way is using Regular Expressions but I don't know how can I write a Regex to match something like above.
I'm using NodeJs for the application.
Using underscore.js#where:
var results = _(yourObject).where({ type: 'person' })
If your data set is very very big [e.g. 10k or so], consider filtering / paginating stuff server side.
Plain javascript :
var results = dataset.filter(function(p) {
if(p.type == 'person')
return true;
});
If the requirement is to scan multiple times through the collection, the following one time construction overhead might be of worth.
Use hashing based on values of type.Convert the current data structure to hash map.
var hashMap ={
};
hashMap['person'] =[{},{}];
Hope this helps you.
Use
$.grep(jsonarrayobj,function(n, i){
if(n.type==="person")
{}
})

Categories

Resources