ExtJS 4.2 Tree representation of JSON hierarchical data - json

I have the following hierarchical JSON.
How should I model it so that it can be represented as Tree.
The products array is at the same level as bookFamilies.
Please can anyone provide some help.
I followed this fiddle.sencha
https://fiddle.sencha.com/#fiddle/9vi
It does not work with 4.2. And I don't know how to restructure to bring the products.
{
"Families" : [
{
"FamilyName" : "FICAsia",
"bookFamilies" : [
{
"name" : "Ndf\/Nds Nja",
"book" : ["3782"]
}
],
"products" : ["CorpZC", "CorpInfl", "CorpFix", "CorpFlt"]
},
{
"FamilyName" : "FICUStandard",
"bookFamilies" : [{
"name" : "Local Markets Nja",
"book" : ["3787", "3785"]
}, {
"name" : "Ndf\/Nds Pwja",
"book" : ["3782"]
}
],
"products" : ["Drawdown", "Xorward", "FXY", "wap", "Top"]
}
]
}
I was thinking to restructure the JSON but not sure how to do with the products so that it can be represented as tree.

By default, for each tree node:
"text" is what will be displayed in the tree. This can be changed to a different field by editing the displayField property of the tree panel (as done in the fiddle you linked). However, it doesn't look like this feature is in 4.2.
"leaf" says whether the item can be expanded (default is true). You want to make sure this is set on the children, otherwise you will get strange behavior when trying to open them.
"expanded" says whether the item/parent is expanded (default is false). If you set this to true on a leaf node, nothing will happen.
"children" opens up the recursive hierarchy for the rest of the relationships.
Some tricky things about the fiddle you linked:
The transform function takes the incoming request and parses into a javascript object and is the "data" argument. This is handy when you need to make some transformations to the data. In this case, you see they take the "items" key and turn it into "children."
The "rootProperty" is a private variable in ExtJS 4.2, but a public one in ExtJS >5
Make sure to look at the docs to see the other features in ExtJS 4.2. Be careful about ExtJS 5,6 documentation because it looks like quite a few things were added/removed.
http://docs.sencha.com/extjs/4.2.2
Here's a partial example json of what you listed earlier. Replace the "data" property with this, remove the "rootProperty" and "transform" properties, remove the "displayField" property, and set the version to ExtJS 4.2.1.
{
"children":[
{
"text":"FICAsia",
"children":[
{
"text":"Book Families",
"children":[
{
"text":"Ndf\/Nds Nja",
"children":[
{
"text":"3782",
"leaf":"true"
}
]
}
]
},
{
"text":"Products",
"children":[
{
"text":"CorpZC",
"leaf":"true"
},
{
"text":"CorpInfl",
"leaf":"true"
},
{
"text":"CorpFix",
"leaf":"true"
},
{
"text":"CorpFlt",
"leaf":"true"
}
]
}
]
}
]
}

Related

HAL - is it a violation to the HAL format/standard if links are in the main body?

According to the HAL standard (see here and here) the links to other resources should be placed in a specific embedded section.
So for instance this is not valid HAL, is my understanding correct?
{
"movies": [
{
"id": "123",
"title": "Movie title 1",
"_links": {
"subtitles": {
"href": "/movies/123/subtitles"
}
}
},{
"id": "456",
"title": "Movie title 2",
"_links": {
"subtitles": {
"href": "/movies/456/subtitles"
}
}
}
],
"_links": {
"self": {
"href": "/movies"
}
}
}
The reason for which the above JSON is not valid HAL is that the links should be placed in an embedded section ("_embedded") that links to the ID in the main body. So the right approach would be:
{
"movies": [
{
"id": "123",
"title": "Movie title 1",
},{
"id": "456",
"title": "Movie title 2",
}
],
"_embedded": {
"movies": [
{
"id": "123",
"_links": {
"href": "movies/123/subtitles"
}
},
{
"id": "456",
"_links": {
"href": "movies/456/subtitles"
}
}
]
}
"_links": {
"self": {
"href": "/movies"
}
}
}
Is all the above correct?
Thanks
Gonna use this as a case study on re desiging with hal. #darrel millers answer is good, but not great and has some things i think should be cleared up. this is gonna be LONG.
The big question is what is the context...IE what is this resource you are returning. All you've got is something that relates to movies somehow. Like suppose this is a search result...having a movie relationship is the wrong approach..as the movie relates to the search result "top level resource" as an item. so it should be something more like
{
title : "Results for search XXXXX"
_links : {
self : { href: "https://host.com/search/with/params/XXXXX"},
item : [
{ href : "https://host.com/url/to/movie/result/one", title : "A great Movie"},
{ href : "https://host.com/url/to/movie/result/two", title : "A Terrible Movie"},
]
}
}
but this structure would be expensive for a client to construct a UI around as it would have to make 3 calls..following the N+1 rule (1 for the result set..then N for each result) so thus was born _embedded which is just hal implementation of the hypertext pre fetch pattern (in http2 the server could actually send each result as it's own document and the client's cache would be pre-filled with those results and you wouldn't necessarily need _embedded). That structure looks more like this:
{
title : "Results for search XXXXX"
_links : {
self : { href: "https://host.com/search/with/params/XXXXX"},
item : [
{ href : "https://host.com/url/to/movie/result/one", title : "A great Movie"},
{ href : "https://host.com/url/to/movie/result/two", title : "A Terrible Movie"},
]
},
_embedded : {
item : [
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/one"}
},
title : "a great movie",
rating : "PG",
},
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/two"}
},
title : "a terrbile movie"
rating : "G",
}
]
}
}
That's pretty great 1 http request to get 3 resources. 1 request not N+1. Thank you HAL!
So why item? well does the search result ONLY EVER contain movies...that's very unlikely..and even if it does today...do you want it to only ever contain movies tomorrow...that's pretty narrow and this structure is a contract that you have to maintain basically forever. But your UI really wants to show the result as a movie. That what the profile link i've added is for...the client uses the profile link to know what the resource it's currently processing is..and what fields it can use to build up a UI. A decent client when processing a collection displays what profiles it can..and just ignores what ones it can't (logging a warning maybe). It up to the client dev to upgrade their app to support new profiles...don't believe me? think about how a web browser parses tags it doesn't understand in html...put a <thing-not-invented-yet></think-not-invented-yet> in your html doc and see how a good client works.
another thing you should notice is i do NOT use self links but canonical..i've changed my stance on this over the years. as of late i default to canonical and i ONLY use self when I'm maintaining versions of the target resource and it's important to have the embedded object link to the specific version that was embedded. this is very rare in my experience. I tell clients to follow self it it's present, ortherwise follow canonical when navigating to the embedded item. this gives the server complete control on where it wants to take the client. The top level resource, in this case a result should still have a self...and in this case it makes sense as soem random search probably does not have a canonical link...unless it's a VERY common keyword search...then it probably should as other users could use the same url.
Let take a moment to talk about why item as the rel...cause this is really important. Since it's a search result..why not have the rel be result. There's a really easy answer..result is not a member of the IANA link registry https://www.iana.org/assignments/link-relations/link-relations.xhtml and therefore result is completely invalid...now you could "namespace" your extension rel with my:result or our:result (the "namespace" is up to you, these are just example) but why bother with that if a perfectly good one already exists in the IANA registry..and it does item.
Let's talk about items vs item (or x:movies vs x:movie) . Well items isn't in IANA either..so it'd have to be x:items but instead of doing that let's think about why. If our result doc was represented in HTML it'd be looking like this (ignore my missing body head etc not well-formedness for brevity):
<html>
<title>Results for search XXXXX</title>
<a rel="item" href="https://host.com/url/to/movie/result/one" >A Great Movie</a>
<a rel="item" href="https://host.com/url/to/movie/result/two" >A Great Movie</a>
</html>
This is the SAME resource as the first example (without embedding sub resources). Just represented as text/html and not application/hal+json. If i've lost you here (this is where most people get REALLY confused, the best i can offer is to watch my talk on this at https://www.youtube.com/watch?v=u_pZBBELeEQ ) Hear it's clear the appropriate relationship of each target resource is a SINGLE ITEM and not a set of ITEMS. each link targets one item (or one, singular movie).
There's a trap with HAL to treat it like JSON and that leads to statements like the one the comments that movies is machine readable or better. Let me explain how this comes about by continuing with this HTML representation in a use case.
When a client parses this document looking for item links it must parse EVERY a tag and filter down to only those where rel="item" attribute is present. That's a "full table scan"..and how do we get away from those? we create an index. JSON has the concept of an index built into it's structure. It's a key with an array value. index : [ {entry 1}, {entry 2} ]. The author of HAL knew the most common way to retrieve links (in _links or the prefetched ones in _embedded) would be by relationship..so he structured his spec such that rel is indexed. so when you see:
_links : {
self : { href: "https://host.com/search/with/params/XXXXX"},
item : [
{ href : "https://host.com/url/to/movie/result/one", title : "A great Movie"},
{ href : "https://host.com/url/to/movie/result/two", title : "A Terrible Movie"},
]
},
know that it is REALLY
_links : {
self : { rel: "self", href: "https://host.com/search/with/params/XXXXX"},
item : [
{ rel:"item", href : "https://host.com/url/to/movie/result/one", title : "A great Movie"},
{ rel:"item", href : "https://host.com/url/to/movie/result/two", title : "A Terrible Movie"},
]
},
because the rel is an attribute of the LINK OBJECT and NOT THE RESOURCE. but bytes over http are expensive (gzip would get rid of this) and devs don't like redundancies (a whole other topic) so when we have hal we OMIT the rel attribute since the HAL structure already makes the rel apparent. though it's not really apparent when your parser encounters just this:
{ href : "https://host.com/url/to/movie/result/one", title : "A great Movie"}
what's the rel? you have to pass that in from the parent node..that's always been ugly...anyways all this is to show that redundancy is eliminated in HAL generally. once this redundancy is eliminated it's tempting to change that index key to the plural form items but know that would mean you are saying your link (once redundancies are PUT BACK) would be {rel: "items", href : "https://host.com/url/to/movie/result/one", title : "A great Movie"} and that is clearly wrong..that link is not to many items...just one.
So removing redundancy in this case probably wasn't the best..but it's evil with benefits and HAL follows that pattern for _links and _embedded and that's what we're gonna do with our search result..given that ALL the item links have no been pre-fetched and are present as _embedded it's unimportant to keep them in _links. and as such it should look like this:
{
title : "Results for search XXXXX"
_links : {
self : { href: "https://host.com/search/with/params/XXXXX"}
},
_embedded : {
item : [
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/one"}
},
title : "a great movie",
rating : "PG",
},
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/two"}
},
title : "a terrbile movie"
rating : "G",
}
]
}
}
Now we have a pretty good search result that includes 2 movies (and can include more things in the future without breaking the contract). Note: if you ever went live with JUST _links and no _embedded...you can NOT remove the _links as some client out there is depending on them being present..so it's best to think of this stuff early...thought a well behaving client should always check _embedded before _links when using the HAL representation of a resource...so it's really up to you to know if all your clients are well behaving.
Ok so let's move to a case where x:movie is the correct relationship..that probably would be good if the top level resource is an actor. so something like:
{
Name : "Paul Bettany"
_links : {
canonical : { href: "https://host.com/paul-bettany"},
"x:movie" : [
{ href : "https://host.com/url/to/movie/result/one", title : "A great Movie"},
{ href : "https://host.com/url/to/movie/result/two", title : "A Terrible Movie"},
],
"x:spouse" : { href: "", title: "Jennifer Connely"}
},
_embedded : {
"x:movie" : [
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/one"}
},
title : "a great movie",
rating : "PG",
},
{
_links : {
profile : {href : "https://host.com/result-movie"},
canonical : {href : "https://host.com/url/to/movie/result/two"}
},
title : "a terrbile movie"
rating : "G",
}
]
}
}
Notes: i used canoncial instead of self at the top level because an actor is long-lived resource..that actor will always exist..and an actor is not versioned. For completeness i left both x:movie in _links and _embedded, however in practice i would NOT have the ones in _item. I also kept them in _links to show the reasons to have x:movie is so that you can differentiate it from x:spouse (that semantic differentiation did NOT make sense in the search result case we started with). Finally it's useful to note that i embedded x:movie but NOT x:spouse this is just to illustrate that it is not an either / or thing. you can pre-fetch/embed the link you need for your use case. In fact i often embed things based on the identity of the client..ie i know iOS can display something that android can not.
Those notes aside, the reason i went here is that i wanted to make it clear that you do NOT and SHOULD NOT have that movies: data field that you have...just rely on the movie data in _embedded. You said soemthign like matching up the values in the movies to teh ones in _links or _embedded...you should NOT be doing that..that doesn't make any sense. a movie is a resource...use the linked resource of a movie not some data field. You need to decide early on what is a resource and what is a piece of data. my best tip is if a thing has link relationships..then it's a resource. In my talk i go into MUCH MORE DETAIL on this with broader terms (hypermedia controls) that i don't want to get into here yet.
A final note..in hypermedia applications you KNOW you are doing something wrong if you are exposing internal id fields..as you have done here. That should be a huge red flag that something is wrong. The use case for the id's you described was to match up the data field movies with the _embedded x:movie. As stated...you should NOT be doing that..and the presence of an id field should key you in to that bad practice.
I was asked to answer here..so i hope this helps.
The "_Links" property must go in the root of a resource object. That resource object might be at the root, or it could be in the _embedded object.
I suspect some of the confusing is coming from having an "_embedded" key point to an array. This is only done when you want to represent multiple instances of a related resource.
In the example the key is movies which infers you are embedding a resource object which represents multiple movies. However, the array indicates there are multiple embedded resource objects. Each resource object is one movie.
By changing the name of the key to "movie" you get this:
{
"movies": [
{
"id": "123",
"title": "Movie title 1",
},{
"id": "456",
"title": "Movie title 2",
}
],
"_embedded": {
"movie": [
{
"id": "123",
"_links": {
"href": "movies/123/subtitles"
}
},
{
"id": "456",
"_links": {
"href": "movies/456/subtitles"
}
}
]
}
"_links": {
"self": "https://example.org/movielist"
}
}
So, now you have a representation of a "movie-list" resource object and you have embedded a bunch of "movie" resource objects for each item in the "movie-list". Each resource object pointed to by "movie" has a "_links" property to related information. I'm assuming that "subtitles" link was supposed to be a self link.
As observable in the specs you posted, you can have links and/or embedded resources:
A resource's links should sit as a property of that resource:
{
"movies": [
{
"id": "123",
"title": "Movie title 1",
"_links": {
"subtitles": {
"href": "/movies/123/subtitles"
}
}
}, {
"id": "456",
"title": "Movie title 2",
"_links": {
"subtitles": {
"href": "/movies/456/subtitles"
}
}
}
]
}
The alternative would be to directly embed the movie's subtitles resource:
{
"movies" : [
{
"id" : "123",
"title" : "Movie title 1",
"_embedded" : {
"subtitles" : [{
"name" : "movie 1 subtitles"
}
]
}
}, {
"id" : "456",
"title" : "Movie title 2",
"_embedded" : {
"subtitles" : [{
"name" : "movie 2 subtitles"
}
]
}
}
]
}

Custom json in Drupal 7

I am a beginner in Drupal 7 and I am trying to build a custom JSON by using the taxonomy terms. I have implemented the taxonomy terms with parent child relationship and I want to build the same for json. For example, I have a term term Activism which a parent for several other term. Thus, I am looking for a JSON something like this.
{
"name":"Terms",
"children" : [
{
"name":"Activism",
"children" : [{
"name" : "American Civil Liberties Union (ACLU)",
"size" : "1"
},
{
"name" : "Bertrand Russell",
"size" : "1"
}]
}]
}
Can anyone help how to proceed with it. It seems the JSON data document does not provide such relational structuring.

Is there an easy way to get in-line expanded JSON format from Contentful response

Contentful is a very useful service but unfortunately the json response format does not allow for standard expanded json data format.
It requires us to write and extra translator to return common json structure nesting.
For instance, with Contentful we get (simplified version)
{
"module" : {
"lessons" : [
"id": "<lesson_id>"
]
}
"includes": {
"Entry": [
{
id: "<lesson_id>",
lesson : {
"lesson data" : "lesson data",
topics : [
"id" : "<topic_id>"
]
}
},
id: "<topic_id>",
topic : {
"topic data" : "topic data",
]
}
}
]
}
But we want this
{
"module" : {
"lessons" : [
{
"lessonData" : "lesson data",
"topics" : [
{
"topicData" : "topic data",
}
]
}
],
}
}
Anyone have a generalized tool to assemble a Contentful response into a standard json response?
Have you used any of our SDKs? They have Include resolution built-in so that you don't have to do this manually.
There are many tools built already with them to, for example, serialize content to YAML (using a format similar to what you describe) so that static site generators can consume from it.
You can read more about this on our developers page: https://www.contentful.com/developers/docs/
Hope this helps

Back-converting from JSON draft 4 to JSON draft 3

I have a bit of a weird situation. I am running a JSON schema validator that doesn't support draft 4, and due to corporate wonkiness I'm stuck with it instead of replacing it. Our developers are giving me schemas in draft 4 format, so I have to go through by hand and back-convert it, particularly the required fields.
This has all worked fine up until I hit something like this (consider this pseudo-code; I'm still getting the hang of JSON):
"items": {
"type": "array",
"required" : true,
"items": [
{...},
"required": ["0", "1"] // This bit right here
],
}
I'm told it basically says, "The first two items in the array are required." But I can't find a way to express that in JSON draft 3. Is that even supported, and if so, how would you express it?
required is a keyword that only has meaning for object instances, not for arrays.
The way to indicate that an array must have at least 2 items is through minItems keyword in both Draft3 and Draft4.
If you need to express any other schema just for the first and second item in an array, you do it by having two schemas in the items array. For instance, the following schema requires that properties "0" and "1" are included in the first and second items in the array.
For Draft 3:
"items" : [{
"properties" : {
"0" : {"required" : true},
"1" : {"required" : true}
}
}, {
"properties" : {
"0" : {"required" : true},
"1" : {"required" : true}
}
}
]
And Draft 4:
"items" : [{
"required" : ["0", "1"]
}, {
"required" : ["0", "1"]
}
]

Json array in mongoDB

I want to get objects according to an ID they have in an array in a json file in mongodb.
I tried a lot of ways to get them with no success:
db.collection.find({"Id":"2"})
db.collection.find({"Messages.Id":"2"})
db.collection.find({"Messages":{$elemMatch:{"Id":"2"}}})
db.collection.find({"Messages.Id":{$elemMatch:{"Id":"2"}}})
{
"Messages" : [
{
"text":"aaa",
"Id" : [ "1", "2" ]
},
{
"texts" : "bbb",
"Id" : [ "1", "3" ]
}
]
}
Even though that's how it's supposed to be done according to the mongodb documentation.
So I thought something was wrong with my json design (I tried changing it but that didn't help either).
Can anyone suggest to me a good design or query to get the objects with a certain id will work?
UPDATE:
I want for example that if in the query i request the id 2
only the first message and all of it will be displayed (I don't mind if the Id field wont be displayed)
{
"text":"aaa",
"Id":["1","2"]
}
To find single elements that match you will need to utilize the positional operator ($).
db.collection.find({"Messages.Id": "2"}, {"Messages.$": 1, _id: 0})
For finding multiple matches, you would use the aggregation pipeline:
db.collection.aggregate([
{ $unwind: "$Messages" },
{ $match: {"Messages.Id": "1"}},
{ $group: { _id: null, messages: { $push: "$Messages"}}}
])