How to get the key name in json? - json

My previous problem was I'm unable to arrange the json structure like what I wanted. And I found some answers that looks like it almost satisfy my needs but unfortunately I don't know if it's working or not because another problem has occurred.
Below, I arranged my own json data based on the json structure by someone named Programmer.
{
"dialog_type": {"human": {"inner": "He is so scary"}}
}
Here, I have a key called "human". I have two keys in my data. First is "human" and second is "non_human". Now if I have two data in my json file, it will become like this :
{
"dialog_type": {"human": {"inner": "He is so scary"}}
},
{
"dialog_type": {"non_human": "Once upon a time..."}
}
This case is maybe simillar to someone asked here. But unfortunately I have no idea if it's possible to do that in unity. I want to make a method like this answer. So I can determine what action to take by comparing those keys.
Now the question is how do I get the key name as a string in my json data using C# ?

To access the property names of a Unity javascript object, you can use:
for(var property in obj) {}
For instance, this will log all keys (i.e. property names) of all the property key-value pairs in a Unity javascript object (e.g. "key1" and "key2"):
function Start () {
var testObject = {
"key1": "value 1",
"key2": "value 2"
};
for(var property in testObject) {
Debug.Log(property.Key);
};
}
That should give you a way to check objects for any matching property names you are interested in.

Related

Flutter Nested JSON with a List String as a Value in the Key Pair

I'm hoping someone can help me. I've been stuck on this for a while now. I am reading a JSON from an API but I have not been successful in converting it and sending it back to my typeahead/autocomplete class. I have attempted several different ways of doing this including JSON Serializable until it wouldn't work and I figured out it won't do nested JSON. The JSON I am reading is not like any of the examples that I have found. I have watched multiple tutorials and read all over stackoverflow. The key value pair I need to read has a key as normal but the value is a list of strings. All of the examples I have found have an object with a key:value pair in the list[]. Can someone please tell me how to read and decode this the easiest way?
Here is an example of the exact JSON:
callback(
{
"status": {
"code": 0
},
"total": 6,
"dictionary_terms": {
"compound": [
"aspirin",
"Aspirine",
"Aspirin sodium",
"Aspirin anhydride",
"Aspirin methyl ester",
"Aspirin calcium"
]
}
}
)
Once you have the object that json.decode(callback) gives, you have a Map<String, dynamic>. So to access compounds in there:
_dynamicMap = json.decode(callback);
List<String> dictionary_terms_compound = _dynamicMap['dictionary_terms']['compound'];
Depending on where you are in null safety, you probably need to either check to make sure each key isn't null. ie, this would fail if dictionary_terms or compound don't exist...so you would need to check for it before you can get the value from it.
So assuming they exist, you might need to put:
List<String> dictionary_terms_compound = _dynamicMap['dictionary_terms']!['compound']!;
The dart definition of your dictionary_terms object is a
Map<String, Map<String,List<String>>>

Unable to get a key value called properties "properties": "Value" Groovy

I'm making API requests to a service which returns a JSON object within the body.
I can't seem to get the value of a key called "properties" within groovy.
Everytime I call obj.properties i get the following back
{
"class": "org.json.JSONObject"
}
but if I call just the obj I get the expected JSON object
{
"dummy1": ,
"dummy2": false,
"dummy3": etsad,
"dummy4": asdfw,
"dummy5": qweqwe,
"dummy6": 123123,
"properties": {
"country": UK,
}
}
Likewise if I obj.dummy2 i get false it's only when I obj.properties do I get the above mentioned response
Notice groovy have a special handling for Object's properties, for example for number:
def y = 25
print y.properties
It will print [class:class java.lang.Integer]
So it's part of basic groovy object
See also an answer about getting non-synthetic properties from groovy object
As #daggett comment, you can use
obj.get('properties')
Check out this answer here on how to access the properties of objects.
The reason obj.properties isn't working is most likely due to the fact that every object will have properties, and in your case obj.properties is getting the properties of the JSON object and not the value associated with the key.
Instead of obj.properties, consider obj['properties']

Return nested JSON in AWS AppSync query

I'm quite new to AppSync (and GraphQL), in general, but I'm running into a strange issue when hooking up resolvers to our DynamoDB tables. Specifically, we have a nested Map structure for one of our item's attributes that is arbitrarily constructed (its complexity and form depends on the type of parent item) — a little something like this:
"item" : {
"name": "something",
"country": "somewhere",
"data" : {
"nest-level-1a": {
"attr1a" : "foo",
"attr1b" : "bar",
"nest-level-2" : {
"attr2a": "something else",
"attr2b": [
"some list element",
"and another, for good measure"
]
}
}
},
"cardType": "someType"
}
Our accompanying GraphQL type is the following:
type Item {
name: String!
country: String!
cardType: String!
data: AWSJSON! ## note: it was originally String!
}
When we query the item we get the following response:
{
"data": {
"genericItemQuery": {
"name": "info/en/usa/bra/visa",
"country": "USA:BRA",
"cardType": "visa",
"data": "{\"tourist\":{\"reqs\":{\"sourceURL\":\"https://travel.state.gov/content/passports/en/country/brazil.html\",\"visaFree\":false,\"type\":\"eVisa required\",\"stayLimit\":\"30 days from date of entry\"},\"pages\":\"One page per stamp required\"}}"
}}}
The problem is we can't seem to get the Item.data field resolver to return a JSON object (even when we attach a separate field-level resolver to it on top of the general Query resolver). It always returns a String and, weirdly, if we change the expected field type to String!, the response will replace all : in data with =. We've tried everything with our response resolvers, including suggestions like How return JSON object from DynamoDB with appsync?, but we're completely stuck at this point.
Our current response resolver for our query has been reverted back to the standard response after none of the suggestions in the aforementioned post worked:
## 'Before' response mapping template on genericItemQuery query; same result as the 'After' listed below **
#set($result = $ctx.result)
#set($result.data = $util.parseJson($ctx.result.data))
$util.toJson($result)
## 'After' response mapping template **
$util.toJson($ctx.result)
We're trying to avoid a situation where we need to include supporting types for each nest level in data (since it changes based on parent Item type and in cases like the example I gave it can have three or four tiers), and we thought changing the schema type to AWSJSON! would do the trick. I'm beginning to worry there's no way to get around rebuilding our base schema, though. Any suggestions to the contrary would be helpful!
P.S. I've noticed in the CloudWatch logs that the appropriate JSON response exists under the context.result.data response field, but somehow there's the following transformedTemplate (which, again, I find very unusual considering we're not applying any mapping template except to transform the result into valid JSON):
"arn": ...
"transformedTemplate": "{data={tourist={reqs={sourceURL=https://travel.state.gov/content/passports/en/country/brazil.html, visaFree=false, type=eVisa required, stayLimit=30 days from date of entry}, pages=One page per stamp required}}, resIds=USA:BRA, cardType=visa, id=info/en/usa/bra/visa}",
"context": ...
Apologies for the lengthy question, but I'm stumped.
AWSJSON is a JSON string type so you will always get back a string value (this is what your type definition must adhere to).
You could try to make a type for data field which contains all possible fields and then resolve fields to a corresponding to a parent type or alternatively you could try to implement graphQL interfaces

CPP REST SDK JSON - How to create JSON w/ Array and write to file

I'm having troubles with the JSON classes of the CPP REST SDK. I can't figure out when to use json::value, json::object and json::array. Especially the latter two seem very alike. Also the usage of json::array is rather unintuitive to me. Finally I want to write the JSON to a file or at least to stdcout, so I can check it is correct.
It was way easier for me to use json-spirit, but since I want to make REST requests later on I thought I'd save me the string/wstring madness and use the json classes of the CPP REST SDK.
What I want to achieve is a JSON file like this:
{
"foo-list" : [
{
"bar" : "value1",
"bob" : "value2"
}
]
}
This is the code I tried:
json::value arr;
int i{0};
for(auto& thing : things)
{
json::value obj;
obj[L"bar"] = json::value::string(thing.first);
obj[L"bob"] = json::value::string(thing.second);
arr[i++] = obj;
}
json::value result;
result[L"foo-list"] = arr;
Do I really need this extra counter variable i? Seems rather inelegant. Would using json::array/json::object make things nicer? And how do I write my JSON to a file?
This could help you:
json::value output;
output[L"foo-list"][L"bar"] = json::value::string(utility::conversions::to_utf16string("value1"));
output[L"foo-list"][L"bob"] = json::value::string(utility::conversions::to_utf16string("value2"));
output[L"foo-list"][L"bobList"][0] = json::value::string(utility::conversions::to_utf16string("bobValue1"));
output[L"foo-list"][L"bobList"][1] = json::value::string(utility::conversions::to_utf16string("bobValue1"));
output[L"foo-list"][L"bobList"][2] = json::value::string(utility::conversions::to_utf16string("bobValue1"));
If you want to create list, like bobList, you really need to use some iterator variable.
Otherwise you will get only bunch of separate variables.
For output to console use
cout << output.serialize().c_str();
And finally, this will lead to
{
"foo-list":{
"bar":"value1",
"bob":"value2",
"bobList":[
"bobValue1",
"bobValue1",
"bobValue1"
]
}
}
-- To answer your first question, in arrays, JSON values are stored at ordered indices. Thus, arrays can be traversed efficiently compared to objects as objects are more like hashmaps where the input key goes through hashing mechanism every time and a match within a hashtable is found to reach the value of that key. Thus, arrays are efficient especially when we are trying to traverse through a large JSON.
-- To answer your second question. As you mentioned you need to create something like this.
{
"foo-list" : [
{
"bar" : "value1",
"bob" : "value2"
}
]
}
-- If we were to have json::object with these two json values {"bar":"value1"} and {"bob":"value2"} as the value of the key foo-list,(if we were to have curly braces instead of the square above) it can be implemented as
result[U("foo-list")][U("bar")] = "value1";
result[U("foo-list")][U("bob")] = "value2";
-- But here json::object with these two JSON values {"bar":"value1"} and {"bob":"value2"} is at index 0 of a json::array; and this array is the value of the key foo-list. Thus you need the index variable to implement something like
result[U("foo-list")][0][U("bar")] = "value1";
result[U("foo-list")][0][U("bob")] = "value2";
-- To answer your third question, as correctly pointed out by #Zdeno you can use serialize to convert json::value to string and dump it to the file

TJSONUnMarshal: how to track what is actually unmarshalled

Is there another way to track what is unmarshalled than write own reverter for each field?
I'm updating my local data based on json message and my problem is (simplified):
I'm expecting json like
{ "items": [ { "id":1, "name":"foobar", "price":"12.34" } ] }
which is then unmarshaled to class TItems by
UnMarshaller.TryCreateObject( TItems, TJsonObject( OneJsonElement ), TargetItem )
My problem is that I can't make difference between
{ "items": [ { "id":1, "name":"", "price":"12.34" } ] }
and
{ "items": [ { "id":1, "price":"12.34" } ] }
In both cases name is blank and i'd like to update only those fields that are passed on json message. Of course I could create a reverted for each field, but there are plenty of fields and messages so it's quite huge.
I tried to look REST.Jsonreflect.pas source, but couldn't make sense.
I'm using delphi 10.
In Rest.Json unit there is a TJson class defined that offers several convenience methods like converting objects to JSON and vice versa. Specifically, it has a class function JsonToObject where you can specify options like for example ignore empty strings or ignore empty arrays. I think the TJson class can serve you. For unmarshalling complex business objects you have to write custom converters though.
Actually, my problem was finally simple to solve.
Instead of using TJSONUnMarshal.tryCreateObject I use now TJSONUnMarshal.CreateObject. First one has object parameters declared with out modifier, but CreateObject has Object parameter var modifier, so I was able to
create object, initalize it from database and pass it to CreateObject which only modifies fields in json message.