ReactJS material-UI tableData to parse nested JSON - json

My client is ReactJS and server is Java Jersey based.
Java Jersey produces the following nested JSON.
[
{
"projectname": "BMI",
"testRun": "5934391890034305",
"numberOfTestcases": "3",
"timeNowString": "Mon Sep 21 21:17:34 IST 2020",
"oidobjList": [
{
"oid": "5f68cb16f01c7607230d1fcd"
},
{
"oid": "5f68cb16f01c7607230d1fcf"
},
{
"oid": "5f68cb16f01c7607230d1fd1"
}
],
"fileNameObjList": [
{
"fileName": "Basispath_BMI_0_out.gif"
},
{
"fileName": "Basispath_BMI_1_out.gif"
},
{
"fileName": "Basispath_BMI_2_out.gif"
}
]
},
{
"projectname": "BMI",
"testRun": "3320691551029718",
"numberOfTestcases": "3",
"timeNowString": "Mon Sep 21 18:37:54 IST 2020",
"oidobjList": [
{
"oid": "5f68a5aaf01ca8f40b42a4e7"
},
{
"oid": "5f68a5aaf01ca8f40b42a4e9"
},
{
"oid": "5f68a5aaf01ca8f40b42a4eb"
}
],
"fileNameObjList": [
{
"fileName": "Basispath_BMI_0_out.gif"
},
{
"fileName": "Basispath_BMI_1_out.gif"
},
{
"fileName": "Basispath_BMI_2_out.gif"
}
]
}
]
My ReactJS code is as follows:
{this.props.articles.map((el, index) => (
<Table
tableHeaderColor="primary"
tableHead={["Parameter", "Value"]}
tableData={[
["Project Name: ", el.projectname],
["Test Run: ", el.testRun],
["No Of TestCases: ", el.numberOfTestcases],
// ["File Name: ", el.fileNameObjList],
["Time Stamp: ", el.timeNowString],
]}
/>
))}
The response received in client side is attached in the image
Questions:
How to render nested JSON elements in ReactJS material-ui based tableData?
How to get filenames using map and index?
Please provide solution to this issue.

1 - First you need to decide how you will render your table. If you just want to render a single table for all your nested arrays, you can generate a single array of it and render normally. You can also render multipla tables, one for each nested array, it's your choice as a programmer.
2 - You can get filenames field by doing an simple map in fileNameObjList. But if you want a single array of filenames, you can either use Array.reduce or combine the mapped arrays with Array.concat or by pushing every item with an for loop
and also, I'm not sure but i don't think Material UI table is used that way. You may be using another data-table component that uses MUI

Related

How to write JSON Path to get particular value based on string filter?

I am new to JSON Path and I am trying to get 'id' corresponding to name='Candy' using JsonPath in below JSON payload.
{
"responsePayload": [
{
"content": {
"id": "101",
"name": "Candy"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/101",
"id": "101"
}
]
},
{
"content": {
"id": "102",
"name": "Chocolate"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/102",
"id": "102"
}
]
}
]
}
For this I tried Jsonpath $.responsePayload[0].content[?(#.name=='Candy')].id but that is not working. I am using https://jsonpath.com/ for testing this JsonPath. Please guide me how I can achieve required result.
You're really close. You need more of the path inside the expression.
$.responsePayload[?(#.content.name=='Candy')].content.id
The [0] you have in your response isolates the first element only, but it sounds like you want to iterate over the whole array in responsePayload. To do that, the filter expression selector [?(...)] must act on that array.
Next, the # represents the current item, and you can build a full path off of it. You can see how that works above.
Finally, the filter expression selector returns the full item when the expression returns true. So you then need to navigate into .content.id again to get the value you're after.

Apache VTL - Copy node

Is there a way to do deep copy using apache VTL?
I was trying to use x-amazon-apigateway-integration using requestTemplates.
The input JSON is as shown below,
{
"userid": "21d6523137f6",
"time": "2020-06-16T15:22:33Z",
"item": {
"UserID" : { "S": "21d6523137f6" },
<... some complex json nodes here ...>,
"TimeUTC" : { "S": "2020-06-16T15:22:33Z" },
}
}
The requestTemplate is as shown below,
requestTemplates:
application/json: !Sub
- |
#set($inputRoot = $input.path('$'))
{
"TableName": "${tableName}",
"ConditionExpression": "attribute_not_exists(TimeUTC) OR TimeUTC > :sk",
"ExpressionAttributeValues": {
":sk":{
"S": "$util.escapeJavaScript($input.path('$.time'))"
}
},
"Item": "$input.path('$.item')", <== Copy the entire item over to Item.
"ReturnValues": "ALL_OLD",
"ReturnConsumedCapacity": "INDEXES",
"ReturnItemCollectionMetrics": "SIZE"
}
- {
tableName: !Ref EventsTable
}
The problem is, the item gets copied like,
"Item": "{UserID={S=21d6523137f6}, Lat={S=37.33180957}, Lng={S=-122.03053391}, ... other json elements..., TimeUTC={S=2020-06-16T15:22:33Z}}",
As you can see, the whole nested json become a single atribute. While I expected it to become a fully blown json node on its own like below,
"Item": {
"UserID" : { "S": "21d6523137f6" },
"Lat": { "S": "37.33180957" },
"Lng": { "S": "-122.03053391" },
<.... JSON nodes ...>
"TimeUTC" : { "S": "2020-06-20T15:22:33Z" }
},
Is it possible to deep/nested copy operation on a json node like above without doing the kung-fu of iterating the node and appending the childs o a json node variable etc...
btw, I'm using AWS API Gateway request template, so it may not support all the Apache VTL templating options.
You need to use the $input.json method instead of $input.path.
"Item": $input.json('$.item'),
Note that I removed the double quotes.
If you had the double quotes because you want to stringify $.item, you can do that like so:
"Item": "$util.escapeJavaScript($input.json('$.item'))",

Logstash json field removal

We have a heavily nested json document containing server metrcs, the document contains > 1000 fields some of which are completely irrelevant to us for analytic purposes so i would like to remove them before indexing the document in Elastic.
However i am unable to find the correct filter to use as the fields i want to remove have common names in multiple different objects within the document.
The source document looks like this ( reduced in size for brevity)
[
{
"server": {
"is_master": true,
"name": "MYServer",
"id": 2111
},
"metrics": {
"Server": {
"time": {
"boundary": {},
"type": "TEXT",
"display_name": "Time",
"value": "2018-11-01 14:57:52"
}
},
"Mem_OldGen": {
"used": {
"boundary": {},
"display_name": "Used(mb)",
"value": 687
},
"committed": {
"boundary": {},
"display_name": "Committed(mb)",
"value": 7116
}
"cpu_count": {
"boundary": {},
"display_name": "Cores",
"value": 4
}
}
}
}
]
The data is loaded into logstash using the http_poller input plugin and needs to be processed before sending to Elastic for indexing.
I am trying to remove the fields that are not relevant for us to track for analytical purposes, these include the "display_name" and "boundary" fields from each json object in the different metrics.
I have tried using the mutate filter to remove the fields but because they exist in so many different objects it requires to many coded paths to be added to the logstash config.
I have also looked at the ruby filter, which seems promising as it can look the event, but i am unable to get it to crawl the entire json document, or more importantly actually remove the fields.
Here is what i was trying as a test
filter {
split{
field => "message"
}
ruby {
code => '
event.get("[metrics][Mem_OldGen][used]").to_hash.keys.each { |k|
logger.info("field is:", k)
if k.include?("display_name")
event.remove(k)
end
if k.include?("boundary")
event.remove(k)
end
}
'
}
}
It first splits the input at the message level to create one event per server, then tries to remove the fields from a specific metric.
Any help you be greatly appreciated.
If I get the point, you want to keep just the value key.
So, considering the response hash:
response = {
"server": {
"is_master": true,
"name": "MYServer",
"id": 2111
},
"metrics": {
...
You could do:
response[:metrics].transform_values { |hh| hh.transform_values { |h| h.delete_if { |k,v| k != :value } } }
#=> {:server=>{:is_master=>true, :name=>"MYServer", :id=>2111}, :metrics=>{:Server=>{:time=>{:value=>"2018-11-01 14:57:52"}}, :Mem_OldGen=>{:used=>{:value=>687}, :committed=>{:value=>7116}, :cpu_count=>{:value=>4}}}}

dynamic json for datatables

I've been working with datatables and I'm able to load the datatable using getJson with strongly typed classes etc and it works just great. Until I hit one snag.
There are times I want to populate a datatable with data that "I don't know about" but I always know that it will be one row of data - it is simply a json string with dynamic content.
Now with datatables you can simply populate the table with aaData and aaCol by assigning a json string to it but my json string contains a column and data IE:
First_name:bob and so on.
A column - on Datatables would be populated with sTitle:Column1 etc and assigned to aaCol.
Does anyone know of a plug in that parses a json string into aaCol and aaData for use with datatables?
I believe you can solve your problem using this approach:
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "scripts/objects.php",
"columns": [
{ "data": "first_name" },
{ "data": "last_name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "start_date" },
{ "data": "salary" }
]
} );
} );
In the example above the dataTables uses a serverSide processing, the ajax return a object like this:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
{
"first_name": "Airi",
"last_name": "Satou",
"position": "Accountant",
"office": "Tokyo",
"start_date": "28th Nov 08",
"salary": "$162,700"
}, ...
You can also set the column name using the "name" property inside the specification of each column.
You can the full example in the following link. If you need more assistance I can make a code on my own later today =)
You can check this JsFiddle to understand how to set the columns names

How to load multidimensional / nested json into a store?

So I'm trying to load the data received from a webservice into a sencha touch 2 store.
The data is nested JSON, however it is made to include multiple dataArrays.
I am working with sencha touch 2.3.1, somewhat equal to Ext JS 4.2. I don't have that much experience with sencha yet, but I'm getting there. I decided to go for MVC, so I'd like the answers to be as close to this as possible :).
This is the example JSON I am using:
[
{
"DataCollection": {
"DataArrayOne": [
{
"Name": "John Smith",
"Age": "19"
},
{
"Name": "Bart Smith",
"Age": "16"
}
],
"DataArrayTwo": [
{
"Date": "20110601",
"Product": "Apple",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Orange",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Pear",
"Descr": "",
"Remark": ""
}
],
"DataArrayThree": [
{
"SomeTotalCost": "400,50",
"IntrestPercentage": "3"
}
]
}
}
]
Through only one call, I get this json. I don't want to cause any unnecessary traffic so I hope to be able to use the data somehow.
I want to be able to use each DataArray on its own.
The data gets sent to the store through its proxy:
Ext.define("MyApp.store.myDataObjects", {
extend: "Ext.data.Store",
config: {
model: "MyApp.model.myDataObject",
proxy: {
reader: {
type: "json",
rootProperty: "DataCollection"
},
type: "ajax",
api: {
read: "https://localhost/Service.svc/json"
},
limitParam: false,
startParam: false,
pageParam: false,
extraParams: {
id: "",
token: "",
filter: ""
},
writer: {
encodeRequest: true,
type: "json"
}
}
}
});
I am a bit stuck with the model here. I tried using mappings which would look like this:
config: {
fields: [ {
name: "IntrestPercentage",
mapping: "Calculation.IntrestPercentage",
type: "string"
}
]}
I tried associations as well but to no avail.
According to google chrome console, it doesn't make any objects containing data. I get only 1 object with all values "null".
My endgoal is to be able to show each dataArray in a separate table. So a table for DataArrayOne, a table for DatarrayTwo... The data itself isn't linked. They are only details that have to be shown on a view.
John Smith isn't related to the apples, as in he didn't buy. The apples are just there as an item to be shown.
The possible solutions I've seen yet not understood due to them being outdated are:
ChildStores: You have a master store that receives the data, and then
you split the data to other stores according to rootProperty. I have
no idea how to do this however and I'm not sure if it will work at
all.
Associations, in case I was doing them wrong. I don't think they
are needed because the data isn't linked to each other but it is part
of "DataCollection" though.
Could someone please post an example on how to deal with this unusual(?) kind of nested json.
Or any other solution which will lead to being able to use the 3 dataArrays at will.
Thanks in advance
The best would be to load the complete data with a separate Ext.Ajax.request and then use store.loadData in the success callback. For example:
var data = Ext.decode(response.responseText);
store1.loadData(data[0].DataCollection.DataArrayOne);
store2.loadData(data[0].DataCollection.DataArrayTwo);
store3.loadData(data[0].DataCollection.DataArrayThree);