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']
Related
I have a scenario where I can have multiple different types of json objects coming into my system. I do not know the object type ahead of time and based upon object type, will route to a different processor in my flow
{
"book": {
"id": "1234",
"name": "book1"
}
}
or
{
"video": {
"id": "3214",
"name": "video1"
}
}
or
{
"magazine": {
"id": "3233",
"name": "magazine1"
}
}
how can I evaluate if the object is a book, or a video, or a magazine to route to the correct processor
I've tried using evaluatejsonpath using the ~ but it just outputs the entire json object
Current flow :
One way is to extract all top level fields using EvaluateJsonPath processor, set the extracted field values to dynamic properties, and use the properties in RouteOnAttribute processor to route the flow to correct downstream processor.
EvaluateJsonPath:
Please don't forget to set
'Destination' to 'flowfile-attribute' and
'Return Type' to 'json'
If EvaluateJsonPath processor could not find the field or element, then the value of dynamic property will be set to empty string.
All we need to do is to use the dynamic properties in RouteOnAttribute processor.
RouteOnAttribute:
Using equals() and not()
or using isEmpty() and not()
Please don't forget to set
'Routing Strategy' to 'Route to Property Name'.
Apache NiFi expression language guide
Example Flow:
I am using PutFile processor as a downstream processor, for an example. It could be any processor.
I am struggling to select a property from a JSON array that I've stored in a variable (as an array). I receive the following error:
The execution of template action 'Select' failed: The evaluation of 'query' action >'where' expression '{
"Response": "#variables('UserEvents').responseStatus.response",
"trest": ""
}' failed: 'The template language expression >'variables('UserEvents').responseStatus.response' cannot be evaluated because property >'responseStatus' cannot be selected. Array elements can only be selected using an > integer index. Please see https://aka.ms/logicexpressions for usage details.'.
The JSON is below:
[
{
"value": [
{
"responseStatus": {
"response": "notResponded",
"time": "0001-01-01T00:00:00Z"
}
}
]
}
]
I'm trying to select the 'response' property only by using the following expression:
#variables('UserEvents').responseStatus.response
I have tried adding [0] to various parts of the above expression but it doesn't seem to make any difference. I am sure it's pretty simple and I'm just getting the syntax wrong, but am completely stuck!
Any help appreciated - thanks.
Adrian
#{
variables('UserEvents') ? ['value'] ? [0] ? ['response']
}
Try that. The integer index mentioned in the error is the way around this. May need to play around with the structure to make it match your data but [0] will make it select the first object within your value array.
There are 2 ways to get the properties inside a nested JSON
WAY - 1 (Try to get properties using For-each loop)
For this we need to use 2 for-each loops to retrieve the property inside the nested JSON After Parsing the JSON. Below is the screenshot of my logic app for your reference.
WAY - 2 (Using Dynamic Expression)
Here is the Expression that worked for me.
body('Parse_JSON')?[0]?['value']?[0]?['responseStatus']?['response']
Since it is in Array of Array format we need to mention the index of the array. Below is the screenshot of my logic app for your reference :
output :
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.
I'm trying to access a property of a JSON object using TypeScript. The JSON object is obtained from a server in this format:
{
"1111": {
"id": 1111,
"name": "NAME",
"available": 3,
}
}
This JSON object has property names that match my typescript class, used to deserialise the JSON object into this class.
I've been able to access a property is this way:
jsonObj['1111'].name //this correctly returns "NAME"
However, I would prefer to use the id of the JSON object as a variable, as opposed to hardcoding the id into the call to get the property. Is there a way to do something like this?
let idOfJsonObj = '1111'
jsonObj[idOfJsonObj].name //this implementation throws an error
Simply use:
let idOfJsonObj = 1111
jsonObj[idOfJsonObj].name
Don't use quotes.
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.