Flutter: parsing json response that has multiple keys - json

I'm trying to get the values of these keys from this json response:
{
"pro": {
"groups": [
"1": {
"name": "Base",
"fields": [
{
"id": 3,
"value": {
"raw": "Name",
}
},
{
"id": 4,
"value": {
"raw": "avatar",
}
},
]
},
"2": {
"name": "Base",
"fields": [
{
"id": 6,
"value": {
"raw": "Name",
}
},
{
"id": 7,
"value": {
"raw": "avatar",
}
},
]
}
]
}
}
I could get the values "name": "Base"
json['pro']['groups']["1"]['name'],
But I can't get the values of key "raw".
How can I get the values of key "raw"?

The values of fields are a list, so you will get a list of raw values:
List<String> raw = json['pro']['groups']['1']['fields'].map((v) => v['value']['raw'];
Also, it seems like groups is an array but as an object? then you can do something like this:
List<String> raw = [];
Map<String, dynamic> groups = json['pro']['groups'];
for (var key in groups.keys) {
raw.add(groups[key]['fields'].map((v) => v['value']['raw']);
}
or
List<String> raw = groups.keys.map((key) => groups[key]['fields'].map((v) => v['value']['raw']);
I haven't tested the code, but hopefully, it works as expected :)

first thing first. your json is invalid.
try to paste your json here it will show why is your json is invalid
after you fix the json the new structure json will be looked like this
{
"pro": {
"groups": [
{
"name": "Base",
"fields": [
{
"id": 3,
"value": {
"raw": "Name",
}
},
{
"id": 4,
"value": {
"raw": "avatar",
}
},
]
},
{
"name": "Base",
"fields": [
{
"id": 6,
"value": {
"raw": "Name",
}
},
{
"id": 7,
"value": {
"raw": "avatar",
}
},
]
}
]
}
}
and then in order to grab the value of raw, you have to parse the json first using jsonDecode(), then you can use something like this:
Map<String, dynamic> groupOne = json['pro']['groups'][0];
Map<String, dynamic> groupOneFieldOne = groupOne['fields'][0];
print(groupOneFieldOne['value']['raw']);
but that's just an example. if you want to access them easily you can use .map() like this:
List<Map<String, dynamic>> groups = json['pro']['groups'];
groups.map(
(Map<String, dynamic> group) => (group['fields'] as List<dynamic>).map(
(dynamic field) => field['value']['raw'],
),
);
that's it! if you want to ask anything just put a comment ;)
you can copy and paste on dartpad
List<Map<String, dynamic>> groups = json['pro']['groups'];
print(groups.map(
(Map<String, dynamic> group) => (group['fields'] as List<dynamic>).map(
(dynamic field) => field['value']['raw'],
),
));
}
Map<String, dynamic> json = {
"pro": {
"groups": [
{
"name": "Base",
"fields": [
{
"id": 3,
"value": {
"raw": "Name",
}
},
{
"id": 4,
"value": {
"raw": "avatar",
}
},
]
},
{
"name": "Base",
"fields": [
{
"id": 6,
"value": {
"raw": "Name",
}
},
{
"id": 7,
"value": {
"raw": "avatar",
}
},
]
}
]
}
};

Related

how to merge multiple json files with same structure into one json file with same structure (combined all into one with keeping same structure))

I need to merge file1.json file2.json (could be more) into onefile.json.
version is always the same value in all files. however vulnerabilities array and dependency_files array values different but there might be duplicate/which I want to remove if any after the merge
file1.json:
{
"version": "x.x.x",
"vulnerabilities": [
{
"id": "0000"
},
{
"id": "11111"
},
{
"id": "2222"
}
],
"dependency_files": [
{
"name": "name0000"
},
{
"name": "name1111"
},
{
"name": "name2222"
}
]
}
file2.json:
{
"version": "x.x.x",
"vulnerabilities": [
{
"id": "2222"
},
{
"id": "3333"
}
],
"dependency_files": [
{
"name": "name2222"
},
{
"name": "name3333"
}
]
}
onefile.json:
{
"version": "x.x.x",
"vulnerabilities": [
{
"id": "0000"
},
{
"id": "11111"
},
{
"id": "2222"
},
{
"id": "3333"
}
],
"dependency_files": [
{
"name": "name0000"
},
{
"name": "name1111"
},
{
"name": "name2222"
},
{
"name": "name3333"
}
]
}
I tried a lot with no luck
You could have a reduce on all files, initialized with the first, hence no need for the -n option:
jq '
reduce inputs as {$vulnerabilities, $dependency_files} (.;
.vulnerabilities = (.vulnerabilities + $vulnerabilities | unique_by(.id))
| .dependency_files = (.dependency_files + $dependency_files | unique_by(.name))
)
' file*.json
{
"version": "x.x.x",
"vulnerabilities": [
{
"id": "0000"
},
{
"id": "11111"
},
{
"id": "2222"
},
{
"id": "3333"
}
],
"dependency_files": [
{
"name": "name0000"
},
{
"name": "name1111"
},
{
"name": "name2222"
},
{
"name": "name3333"
}
]
}
Demo
Using this python code
import json
def merge_dicts(*dicts):
r = {}
skip = 'version'
for item in dicts:
for key, value in item.items():
if (key == skip):
r[skip] = value
else:
r.setdefault(key, []).extend(value)
unique = []
for obj in r[key]:
if obj not in unique:
unique.append(obj)
r[key] = unique
return r
with open("file1.json") as file_1:
data_1 = json.load(file_1)
with open("file2.json") as file_2:
data_2 = json.load(file_2)
with open('data.json', 'w') as merge_file:
json.dump(merge_dicts(data_1, data_2), merge_file, indent = 4)
Result
{
"version": "x.x.x",
"vulnerabilities": [
{
"id": "0000"
},
{
"id": "11111"
},
{
"id": "2222"
},
{
"id": "3333"
}
],
"dependency_files": [
{
"name": "name0000"
},
{
"name": "name1111"
},
{
"name": "name2222"
},
{
"name": "name3333"
}
]
}
This code is multiple json files support
import os, json
def merge_dicts(*dicts):
r = {}
skip = 'version'
for item in dicts:
for key, value in item.items():
if (key == skip):
r[skip] = value
else:
r.setdefault(key, []).extend(value)
unique = []
for obj in r[key]:
if obj not in unique:
unique.append(obj)
r[key] = unique
return r
json_files = [pos_json for pos_json in os.listdir('./') if pos_json.endswith('.json')]
a = []
print(type(a))
for json_file in json_files:
with open(json_file) as file_item:
read_data = json.load(file_item)
a.append(read_data)
file_item.close()
with open('data.json', 'w') as merge_file:
json.dump(merge_dicts(*tuple(a)), merge_file, indent = 4)

How to filter with console.log JSON?

I need to filter in the console.log the data that I get from the json that I show in the image. How could I do it?
Code
This is my .JSON
[
{
"category": "FORMULARIOS",
"items": [
{
"label": "Botones",
"url": "ui-botones"
},
{
"label": "Inputs",
"url": "ui-inputs"
}
]
},
{
"category": "CORREOS",
"items": [
{
"label": "Facturas",
"url": "ui-facturas"
},
{
"label": "Movimientos",
"url": "ui-movimientos"
}
]
},
{
"category": "ALERTAS",
"items": [
{
"label": "Toast",
"url": "ui-toast"
},
{
"label": "Toolips",
"url": "ui-toolips"
}
]
}
]
You can do like this:
var yourJSON ="......";
var newData = filterData('CORREOS');
function filterData(catalogyName) {
return yourJSON.filter(object => {
return object['category'] == catalogyName;
});
}
console.log(newData);

JSON query expression (JMESPath) to remove a key/value from a nested list of dictionaries

I have the below data structure in JSON, which is a dictionary where each element is a list of dictionaries.
{
"383e36d1-32e5-4705-8271-fa5e9e2ad538": [
{
"label": "blah",
"group_label": "group_a",
"id": "id_blah"
},
{
"label": "bloh",
"group_label": "group_b",
"id": "id_bloh"
}
],
"38b8293c-00c4-4bcf-91eb-440da656c653": [
{
"label": "bim",
"group_label": "group_c",
"id": "id_bim"
},
{
"label": "bam",
"group_label": "group_d",
"id": "id_bam"
},
...
}
and I need a JMESPath query expression to turn it into:
{
"383e36d1-32e5-4705-8271-fa5e9e2ad538": [
{
"label": "blah",
"group_label": "group_a",
},
{
"label": "bloh",
"group_label": "group_b",
}
],
"38b8293c-00c4-4bcf-91eb-440da656c653": [
{
"label": "bim",
"group_label": "group_c",
},
{
"label": "bam",
"group_label": "group_d",
},
...
}
Basically keeping the same structure but removing the id key from every entry
In Node.js, you could use the following code:
var json = {
"383e36d1-32e5-4705-8271-fa5e9e2ad538": [
{
"label": "blah",
"group_label": "group_a",
"id": "id_blah"
},
{
"label": "bloh",
"group_label": "group_b",
"id": "id_bloh"
}
],
"38b8293c-00c4-4bcf-91eb-440da656c653": [
{
"label": "bim",
"group_label": "group_c",
"id": "id_bim"
},
{
"label": "bam",
"group_label": "group_d",
"id": "id_bam"
}
]
};
for (var key in json) {
for (var index = 0; index < json[key].length; index++) {
delete json[key][index].id;
}
}
console.log(json);

How to iterate on json fields and insert new values using json4s?

I have a simple json file:
val myJson = {
"field1": [
{
"name": "john",
"lname": "knight"
},
{
"name": "jack",
"lname": "samuel"
},
{
"name": "elinor",
"lname": "cooper"
}
],
"field2": [
{
...
},
{
...
},
{
...
}
],
"field3": [
{
...
},
{
...
},
{
...
}
]
}
and what i want is to be able to iterate on "field1" and for each name to call a method that returns some value and insert this value to the json under "fiel1".
// this returns a list of strings
val kids = getKids("john")
// this is will me the returned value
kids = List("amy", "tom")
now I want to insert it:
{
"field1": [
{
"name": "john",
"lname": "knight"
"kids": ["amy", "tom"]
},
{
"name": "jack",
"lname": "samuel"
"kids": ["edi", "keren"]
},
{
"name": "elinor",
"lname": "cooper"
"kids": ["lilly", "mag"]
}
]
...
but I want to iterate on all the names and do this for each one...how can I accomplish this with json4s?
so lets say i have the parsed json:
val myParsedJson = JsonMethods.parse(myJson)
how do I go from here?
thanks!

Linq to Json using Like Clause

I've got an MVC 3 web app and am returning a JSON object which I would like to use Linq against to limit the result returned to the client jquery.
The Json response takes the following structure:
{
"Data": {
"Items": [
{
"Result": {
"Id": "e2ba4912-c387-4f54-b55e-06742a6858db",
"Name": "SomeOtherSetting",
"Value": "500",
"Archived": false
},
"Result": {
"Id": "17c27584-cea8-42c2-b6c4-0b30625ac3ce",
"Name": "Setting2",
"Value": "600",
"Archived": false
},
"Result": {
"Id": "17c27584-cea8-42c2-b6c4-0b30625ac3ce",
"Name": "Setting3",
"Value": "700",
"Archived": false
}
}]
}
}
....
I need to return or grab just the json items that have a Name like 'Setting' for example. In the example, this would return just the 2 Json nodes.
My Linq is very limited and what I have is: Settings is where the Json response is stored.
NewtonSoft.Json.Linq.JObject data = NewtonSoft.Json.Linq.JObject.Parse(Settings);
var result = from p in data["Data"]["Items"].Children()
where (p["Result"]["Name"].Contains("Expenses.Help.Tip"))
select new { Name = (string)p["Result"]["Name"], Value = (string)p["Result"]["Value"] };
When I run this I get nothing in my result. Can anyone help and tell me what I'm doing wrong?
Thanks.
Well, I'm not a Json specialist, but I think your Json structure has some problems.
I tried an online parser, and parsing took only the third result... (try to copy past your code in the left window, and look at JS eval.
Instead of
"Items": [
{
"Result": {
},
"Result": {
},
"Result": {
}
}]
you should have each element of Items array (each 'Result') into {}.
"Items": [
{
{"Result": {
}
},
{"Result": {
}
},
{"Result": {
}
}]
I got it to work by changing your Json file to
{
"Data": {
"Items": [
{
"Result": {
"Id": "e2ba4912-c387-4f54-b55e-06742a6858db",
"Name": "SomeOtherSetting",
"Value": "500",
"Archived": false
}
},
{
"Result": {
"Id": "17c27584-cea8-42c2-b6c4-0b30625ac3ce",
"Name": "Setting2",
"Value": "600",
"Archived": false
}
},
{
"Result": {
"Id": "17c27584-cea8-42c2-b6c4-0b30625ac3ce",
"Name": "Setting3",
"Value": "700",
"Archived": false
}
}]
}
}
using
var data = JObject.Parse(test)["Data"]["Items"].Children()
.Where(m => m["Result"]["Name"].Value<string>().Contains("Setting"))
.Select(m => new
{
Name = m["Result"]["Name"].Value<string>(),
Value = m["Result"]["Value"].Value<int>()
})
.ToList();