I'm designing JSON structure for communication between front-end and backend.
As you can see on the JSON structure. The couldHave node value is empty.
Should I remove this node from the JSON totally?
Or leave it as an empty value.
I can think of if I remove them entirely. The size will be reduced.
"structureNames":{
"List View":"default_related_queue_contracts_list_view"
},
"whereClause":{
"mustHave":[
{
"fieldName":"Status",
"comparison":"eq",
"value":"5"
}
],
"couldHave":[
]
}
Though having empty array[] will not be an issue, apart from the size you have mentioned. But if you don't send this node at all, then in cases where you need to access value of couldHave, will start throwing error like Cannot read value <key> of undefined. So, it's better if you send an empty array.
To handle such cases in client, you will anyway write something to handle this undefined case. Or you will use it something like
var a = whereClause.couldHave || [];
From my experience, leaving an empty node will not cause any problems if your front-end is not trying to parse that empty node ...however, it is always good practice to have at least a default empty value... that way your front end can call a function handleMissingInformation() when ever an empty node value is referenced.
Related
I'm using the TJsonDataObjects Delphi component (https://github.com/ahausladen/JsonDataObjects). I am using it as the data store for what is is displayed in a editable TreeView. In the treeview I store the "path" using a JsonPath string. When the user modifies the values in the Treeview, the path property allows me locate the record by path and modify it via the component path property.
My issue is when a user wants to delete a record, I need to remove it from the JSON file. It does note seem like there is a simple way to do this via its "path. I expect I could trim off the item from the path to gets it parent and then delete it by "name" or "index" if an array. I was hoping there might just be an easier way before I start to code this up.
On a similar node, I didn't find any way to extract the text path of a given item. While it can modify or locate a node by path, there does not seem to be a way to get the actual path so I'm doing that manually as I parse the JSON file (yuck). Anyone have a better solution?
For example, this is the path of the "value" property in the JSON below: Level1.Level2.Level3
{
"Level1": {
"Level2": {
"Level3": "value"
}
}
}
In TJsonDataObjects you can set the path with:
Json.Path['Level1.Level2.Level3'] := "value";
//or
Json['Level1']['Level2']['Level3'] := "value";
Or retrieve it with:
prop := Json.Path['Level1.Level2.Level3'];
// or
prop := Json['Level1']['Level2']['Level3'];
So if you want to remove Level3, it would be nice if there was some simple function like Json.DeletePath('Level1.Level2.Level3');. As far as I can tell, there is nothing that does this. Since this is a very complex unit, I thought someone might have an easy answer that I overlooked. I have coded a way around this (as described above).
As to the second question, while you can access a value by its path, there is no function to "return" a path from a given node. And yes, I can and do build it as I go along, it would be handy as that way it remains consistent in its format of the JsonPath.
Is there a way to serialize an empty array attribute (not null) of a struct and deserialize it back to an empty array (not null again)?
Considering that an empty array is actually a pointer to null, is the perceptible initial difference between an empty array and pointer to null completely lost after serialize/deserialize?
The worst practical scenario is that when I show an empty array attribute to my REST client, as a json "att":[], at first time, and, after cache register to redis and recover it, the same attribute is shown to my client as "att":null, causing a contract broken and a lot of confusing.
Summing up: is possible to show the Customer 2 addresses like an json empty array, after serialize/deserialize => https://play.golang.org/p/TVwvTWDyHZ
I am pretty sure the easiest way you can do it is to change your line
var cust1_recovered Customer
to
cust1_recovered := Customer{Addresses: []Address{}}
Unless I am reading your question incorrectly, I believe this is your desired output:
ORIGINAL Customer 2 {
"Name": "Customer number 2",
"Addresses": []
}
RECOVERED Customer 2 {
"Name": "Customer number 2",
"Addresses": []
}
Here is a playground to verify with: https://play.golang.org/p/T9K1VSTAM0
The limitation here, as #mike pointed out, is if Addresses is truly nil before you encode, once you decode you do not get the json equivalent null, but would instead end up with an empty list.
No, it's not possible. To understand why, let's look at the Go spec. For it to output two different results for empty vs. nil, any serialization method would need to be able to tell the difference between the two. However, according to the Go spec,
Two array types are identical if they have identical element types and
the same array length.
Since neither contains any elements and have the same element type, the only difference could be in length, but it also states that
The length of a nil slice, map or channel is 0
So through comparison, it would be unable to tell. Of course, there are methods other than comparison, so to really put the nail in the coffin, here's the portion that shows they have the same underlying representation. The spec also guarantees that
A struct or array type has size zero if it contains no fields (or
elements, respectively) that have a size greater than zero.
so the actual allocated structure of a zero length array has to be of size zero. If it's of size zero, it can't store any information about whether it's empty or nil, so the object itself can't know either. In short, there is no difference between a nil array and a zero length array.
The "perceptible initial difference between an empty array and pointer to null" is not lost during serialization/deserialization, it's lost from the moment initial assignment is complete.
For another solution, we have forked encoding/json to add a new method called MarshalSafeCollections(). This method will marshal Slices/Arrays/Maps as their respective empty values ([]/{}). Since most of our instantiation happens on the data layer we did not want to add code that fixed issues in our http response layer. The changes to the library are minimal and follow go releases.
I need to pass data between views in my client-server app. For simple string value, I can put them as attributes on the target element and read the value when the select event is triggered on it. From there, I can pass this string value onto the next document pretty easily.
But the problem comes with much more complex data that's in JSON format. I tried doing JSON.stringify(myData) and putting this value in an attribute. But the compiler doesn't like the { in this attribute value.
I could probably try escaping all the different characters that the compiler has problems with. But I don't think that's a good idea.
Is there any way of implementing jQuery's .data() functionality in TVML and TVJS ? Or is there any other way that makes sending data between views a possibility ?
You can pass your data as URL parameters. Then in the new view, get them using Javascript.
EDIT: And I see in the comment above you came to a similar conclusion.
You could keep your data in a semi-global associative array. Store the key in an attribute on the element and use that to get your data structure.
Ex:
var globalData;
function onSelect(e){
var id=e.target.getAttribute("id");
var specificData=globalData[id];
}
So I've read that you cannot expect a default order when requesting json. I've seen this in action making a call to a little api that I built, that will return a jumbled, random order of elements each time I make a different call.
How does a site like ticketfly's api ( call it here http://www.ticketfly.com/api/events/upcoming.json?venueId=57 ) always ensure that the json returned is in a specific order?
The event ids always first, etc.
Thanks for shedding some light on the situation.
If you are in control of the endpoint API then you can hardcode the order in which you render the properties. Though I have to ask why exactly do you need the JSON properties in a particular order? You will finally be accessing the properties via there property names so the order in which they appear in the JSON should not ideally matter.
EDIT : Since your bosses insist on this (what can one say now?):
You can try and see if any of the following suits your needs:
Try hardcoding the display order in the view's representation. This means you will need to echo/print each property name explicitly in the view script. In PHP it could be something like echo $variable_representing_json["id"]; and so forth. Note that with this approach you needn't change the original JSON representation.
If you want the original JSON representation to be changed then depending on how you are doing the process it varies in difficulty:
If it's string concatenation that you are using to represent the json then hard-code the order in which the json properties get concatenated in the string.
In some languages the display order of properties is actually a representation of the order in which the properties were defined. In simple words if $var is an empty json representation then you should define $var["id"] = {some_val} first to display it first.
If you are using a framework for processing the JSON data it may have its own quirks irrespective of how you define your representation. In such cases you will have to try and see if you can work around the issue or if it gives any helper methods.
On JSON.org the essential data structures that JSON represents are given as
A collection of name/value pairs, and
An ordered list of values.
I have not been able to find anywhere whether a second member having the same name as one already parsed into the current object should (a) throw an exception or (b) replace the existing member.
Is this specified anywhere?
What do existing parsers do with repeated names?
EDIT: I am looking to define correct behavior for my parser.
JSON is simply a subset of the object literal notation of JavaScript and as such, is constrained by the same rules - the latest value for repeated keys will override any previously assigned value for that key, within the specific object. Think in terms of assigning a value to an object property; A later assignment will override an earlier one.
To demonstrate this, I have set up an example here. The code is displayed on the page, and as can be seen, the messagebox has the name 'Barney' in it.
Code here -
$(function() {
$('#myButton').click(function(e)
{
var myJsonString = "Person = {'firstName':'Fred','lastName':'Flintstone','firstName':'Barney'}";
eval("(" + myJsonString + ")");
alert(Person.firstName);
});
});
By the Way, I have used eval() here for ease of use. I would recommend using a JSON parser instead of eval() due to security issues.
They last name found by the parser is replaced by the new one. It doesn't throw an expection.
It is simply a Javascript syntax thing.
var json = {};
// lets augment the object
json.one = 1;
json.one = 2; // it gets replaced
I am pretty sure that both behaviors you list would be accepted, along with others (use the first one, use any of them). :-)
That is, such behavior is undefined from JSON specification POV.
As a practical matter, implementations I have used do either one of suggestions you mentioned, or "use the first one".
So no, I would not count on specific behavior given that tools can choose what to do.
Because JSON is simply a subset of Javascript, it largely depends upon the Javascript specification. I don't know personally what the answer is, but I would highly suggest not relying upon the behavior if at all possible.