How to extract text from json with parent siblings and substrings? - json

https://bern.korea.ac.kr/pubmed/32818866
$ jq -r '.[] | .denotations | .[] | select(.obj=="drug") | .span | [.begin, .end] | #tsv'
I am able to extract the following info from the above URL using the above jq command.
377 387
562 579
584 602
659 676
681 699
919 936
941 959
1032 1049
1054 1072
But the output that I really need is the following.
The last column is just the substring of text starting from begin+1 to end (suppose the string in text is indexed starting from 1.
I don't know how to extract this info using just jq as it involves taking a parent sibling element and the substring of another parent sibling element. Could anybody show me how to extract the output in this format? Thanks.
32818866 377 387 silica gel
32818866 562 579 7-methoxycoumarin
32818866 584 602 8-prenylkaempferol
32818866 659 676 7-methoxycoumarin
32818866 681 699 8-prenylkaempferol
32818866 919 936 7-methoxycoumarin
32818866 941 959 8-prenylkaempferol
32818866 1032 1049 7-methoxycoumarin
32818866 1054 1072 8-prenylkaempferol
The json txt is here for the completeness of this message.
[
{
"project": "BERN",
"sourcedb": "PubMed",
"sourceid": "32818866",
"text": "Identification of two bitter components in Zanthoxylum bungeanum Maxim. and exploration of their bitter taste mechanism through receptor hTAS2R14. Bitterness is an inherent organoleptic characteristic affecting the flavor of Zanthoxylum bungeanum Maxim. In this study, the vital bitter components of Z. bungeanum were concentrated through solvent extraction, sensory analysis, silica gel chromatography, and thin-layer chromatographic techniques and subsequently identified by UPLC-Q-TOF-MS. Two components with the highest bitterness intensities (BIs), such as 7-methoxycoumarin and 8-prenylkaempferol were selected. The bitter taste perceived thresholds of 7-methoxycoumarin and 8-prenylkaempferol were 0.062 mmol/L and 0.022 mmol/L, respectively. Moreover, the correlation between the contents of the two bitter components and the BIs of Z. bungeanum were proved. The results of siRNA and flow cytometry showed that 7-methoxycoumarin and 8-prenylkaempferol could activate the bitter receptor hTAS2R14. The results concluded that 7-methoxycoumarin and 8-prenylkaempferol contribute to the bitter taste of Z. bungeanum.",
"denotations": [
{
"id": [
"NCBI:txid328401"
],
"span": {
"begin": 43,
"end": 64
},
"obj": "species"
},
{
"id": [
"CUI-less"
],
"span": {
"begin": 128,
"end": 145
},
"obj": "gene"
},
{
"id": [
"NCBI:txid328401"
],
"span": {
"begin": 225,
"end": 246
},
"obj": "species"
},
{
"id": [
"NCBI:txid328401"
],
"span": {
"begin": 300,
"end": 312
},
"obj": "species"
},
{
"id": [
"MESH:D058428",
"BERN:315272203"
],
"span": {
"begin": 377,
"end": 387
},
"obj": "drug"
},
{
"id": [
"CHEBI:5679",
"BERN:4597103"
],
"span": {
"begin": 562,
"end": 579
},
"obj": "drug"
},
{
"id": [
"MESH:C532177",
"BERN:280529003"
],
"span": {
"begin": 584,
"end": 602
},
"obj": "drug"
},
{
"id": [
"CHEBI:5679",
"BERN:4597103"
],
"span": {
"begin": 659,
"end": 676
},
"obj": "drug"
},
{
"id": [
"MESH:C532177",
"BERN:280529003"
],
"span": {
"begin": 681,
"end": 699
},
"obj": "drug"
},
{
"id": [
"NCBI:txid328401"
],
"span": {
"begin": 841,
"end": 853
},
"obj": "species"
},
{
"id": [
"CHEBI:5679",
"BERN:4597103"
],
"span": {
"begin": 919,
"end": 936
},
"obj": "drug"
},
{
"id": [
"MESH:C532177",
"BERN:280529003"
],
"span": {
"begin": 941,
"end": 959
},
"obj": "drug"
},
{
"id": [
"CUI-less"
],
"span": {
"begin": 979,
"end": 994
},
"obj": "gene"
},
{
"id": [
"CUI-less"
],
"span": {
"begin": 995,
"end": 1003
},
"obj": "gene"
},
{
"id": [
"CHEBI:5679",
"BERN:4597103"
],
"span": {
"begin": 1032,
"end": 1049
},
"obj": "drug"
},
{
"id": [
"MESH:C532177",
"BERN:280529003"
],
"span": {
"begin": 1054,
"end": 1072
},
"obj": "drug"
},
{
"id": [
"NCBI:txid328401"
],
"span": {
"begin": 1107,
"end": 1119
},
"obj": "species"
}
],
"timestamp": "Wed Oct 28 21:43:04 +0000 2020",
"logits": {
"disease": [],
"gene": [
[
{
"start": 128,
"end": 145,
"id": "CUI-less"
},
0.7066106796264648
],
[
{
"start": 979,
"end": 994,
"id": "CUI-less"
},
0.9999749660491943
],
[
{
"start": 995,
"end": 1003,
"id": "CUI-less"
},
0.9052715301513672
]
],
"drug": [
[
{
"start": 377,
"end": 387,
"id": "MESH:D058428\tBERN:315272203"
},
0.999982476234436
],
[
{
"start": 562,
"end": 579,
"id": "CHEBI:5679\tBERN:4597103"
},
0.9999980926513672
],
[
{
"start": 584,
"end": 602,
"id": "MESH:C532177\tBERN:280529003"
},
0.9999980926513672
],
[
{
"start": 659,
"end": 676,
"id": "CHEBI:5679\tBERN:4597103"
},
0.9999980926513672
],
[
{
"start": 681,
"end": 699,
"id": "MESH:C532177\tBERN:280529003"
},
0.9999980330467224
],
[
{
"start": 919,
"end": 936,
"id": "CHEBI:5679\tBERN:4597103"
},
0.9999980926513672
],
[
{
"start": 941,
"end": 959,
"id": "MESH:C532177\tBERN:280529003"
},
0.9999980926513672
],
[
{
"start": 1032,
"end": 1049,
"id": "CHEBI:5679\tBERN:4597103"
},
0.9999980926513672
],
[
{
"start": 1054,
"end": 1072,
"id": "MESH:C532177\tBERN:280529003"
},
0.9999980926513672
]
],
"species": [
[
{
"start": 43,
"end": 64,
"id": "NCBI:txid328401"
},
0.9999997615814209
],
[
{
"start": 225,
"end": 246,
"id": "NCBI:txid328401"
},
0.9999998211860657
],
[
{
"start": 300,
"end": 312,
"id": "NCBI:txid328401"
},
0.9999998211860657
],
[
{
"start": 841,
"end": 853,
"id": "NCBI:txid328401"
},
0.9999998211860657
],
[
{
"start": 1107,
"end": 1119,
"id": "NCBI:txid328401"
},
0.9999998211860657
]
]
},
"elapsed_time": {
"tmtool": 0.991,
"ner": 0.453,
"normalization": 0.172,
"total": 1.617
}
}
]

Assuming the first column of the desired output is the "sourceid", we can adapt your solution as follows:
.[]
| .sourceid as $id
| .text as $text
| .denotations[]
| select(.obj=="drug")
| .span
| [$id, .begin, .end, $text[.begin : .end] ]
| #tsv

Related

Adding separate tweet data from JSON onto a List<String>

I've taken the following JSON example directly from Twitter's API example using Postman, my question is how would I be able to grab each tweets inside the "data" section and add each individual tweet onto a List < String > so that each individual tweet's sub JSON is saved as String in the List. Would this be possible? I was attempting to use the JSON parsing method decoding and encoding from Dart but that did not work, I'm not sure if its because the JSON example features the "data" section and the "errors" section. Any help would be greatly appreciated, thank you!
Example JSON:
{
"data": [
{
"author_id": "12",
"conversation_id": "20",
"created_at": "2006-03-21T20:50:14.000Z",
"id": "20",
"text": "just setting up my twttr"
},
{
"attachments": {
"media_keys": [
"16_1276500934466703361"
]
},
"author_id": "783214",
"conversation_id": "1275244210439028736",
"created_at": "2020-06-23T01:48:07.000Z",
"entities": {
"urls": [
{
"start": 112,
"end": 135,
"url": "https://twitter.com/Twitter/status/1275244210439028736/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1275244210439028736/photo/1",
"display_url": "pic.twitter.com/dpI2lRmj9F"
}
]
},
"id": "1275244210439028736",
"text": "Need to follow what’s happening in real time? Change your timeline to show latest Tweets instead of top Tweets."
},
{
"attachments": {
"media_keys": [
"3_1274087263073255425"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:32.000Z",
"entities": {
"mentions": [
{
"start": 13,
"end": 22,
"username": "YoliZama"
}
],
"urls": [
{
"start": 23,
"end": 46,
"url": "https://twitter.com/Twitter/status/1274087695145332736/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1274087695145332736/photo/1",
"display_url": "pic.twitter.com/lcGDLzAJIn"
}
]
},
"id": "1274087695145332736",
"referenced_tweets": [
{
"type": "replied_to",
"id": "1274087694105075714"
}
],
"text": "📍 Oakland\n🗣️ #YoliZama"
},
{
"attachments": {
"media_keys": [
"3_1274086977952833536"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:32.000Z",
"entities": {
"mentions": [
{
"start": 19,
"end": 31,
"username": "Afrikkana95"
}
],
"urls": [
{
"start": 32,
"end": 55,
"url": "https://twitter.com/Twitter/status/1274087694105075714/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1274087694105075714/photo/1",
"display_url": "pic.twitter.com/tEfs27p7xu"
}
]
},
"id": "1274087694105075714",
"referenced_tweets": [
{
"type": "replied_to",
"id": "1274087692003770368"
}
],
"text": "📍 New York City\n🗣️ #Afrikkana95"
},
{
"attachments": {
"media_keys": [
"3_1274086862907305984"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:31.000Z",
"entities": {
"mentions": [
{
"start": 13,
"end": 25,
"username": "JoshuaKissi"
}
],
"urls": [
{
"start": 26,
"end": 49,
"url": "https://twitter.com/Twitter/status/1274087692003770368/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1274087692003770368/photo/1",
"display_url": "pic.twitter.com/ZeD3XvJUbX"
}
]
},
"id": "1274087692003770368",
"referenced_tweets": [
{
"type": "replied_to",
"id": "1274087690758090752"
}
],
"text": "📍 Chicago\n🗣️ #JoshuaKissi"
},
{
"attachments": {
"media_keys": [
"3_1274086703272038401"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:31.000Z",
"entities": {
"mentions": [
{
"start": 18,
"end": 33,
"username": "Imani_Barbarin"
}
],
"urls": [
{
"start": 34,
"end": 57,
"url": "https://twitter.com/Twitter/status/1274087690758090752/photo/1",
"display_url": "pic.twitter.com/ZRDUipsu38",
"expanded_url": "https://twitter.com/Twitter/status/1274087690758090752/photo/1",
"display_url": "pic.twitter.com/ZRDUipsu38"
}
]
},
"id": "1274087690758090752",
"referenced_tweets": [
{
"type": "replied_to",
"id": "1274087689487134720"
}
],
"text": "📍 Philadelphia\n🗣️ #Imani_Barbarin "
},
{
"attachments": {
"media_keys": [
"3_1274086530919718917"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:30.000Z",
"entities": {
"mentions": [
{
"start": 13,
"end": 25,
"username": "BerniceKing"
}
],
"urls": [
{
"start": 26,
"end": 49,
"url": "https://twitter.com/Twitter/status/1274087688321200128/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1274087688321200128/photo/1",
"display_url": "pic.twitter.com/83upyVnwIS"
}
]
},
"id": "1274087688321200128",
"referenced_tweets": [
{
"type": "replied_to",
"id": "1274087687469715457"
}
],
"text": "📍 Atlanta\n🗣️ #BerniceKing "
},
{
"attachments": {
"media_keys": [
"3_1274086027544498176"
]
},
"author_id": "783214",
"conversation_id": "1274087687469715457",
"created_at": "2020-06-19T21:12:30.000Z",
"entities": {
"mentions": [
{
"start": 17,
"end": 29,
"username": "FredTJoseph"
}
],
"urls": [
{
"start": 30,
"end": 53,
"url": "https://twitter.com/Twitter/status/1274087687469715457/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1274087687469715457/photo/1",
"display_url": "pic.twitter.com/lNTOkyguG1"
}
]
},
"id": "1274087687469715457",
"text": "📍 Minneapolis\n🗣️ #FredTJoseph"
},
{
"author_id": "783214",
"conversation_id": "1274034244700930049",
"created_at": "2020-06-19T17:40:09.000Z",
"entities": {
"hashtags": [
{
"start": 106,
"end": 115,
"tag": "BlackJoy"
}
],
"mentions": [
{
"start": 3,
"end": 14,
"username": "Blackbirds"
}
]
},
"id": "1274034244700930049",
"referenced_tweets": [
{
"type": "retweeted",
"id": "1274014870707437570"
}
],
"text": "RT #Blackbirds: Juneteenth is a celebration. It’s about our freedom. And within that freedom is our joy.\n\n#BlackJoy is a form of resistance…"
},
{
"author_id": "773578328498372608",
"conversation_id": "1275473478779469825",
"created_at": "2020-06-23T16:59:09.000Z",
"entities": {
"mentions": [
{
"start": 3,
"end": 10,
"username": "Policy"
}
]
},
"id": "1275473478779469825",
"referenced_tweets": [
{
"type": "retweeted",
"id": "1275192966953476100"
}
],
"text": "RT #Policy: Statement on US high-skilled immigration proclamation: \n\n\"This proclamation undermines America’s greatest economic asset: its d…"
}
],
"errors": [
{
"detail": "Could not find tweet with ids: [1276230436478386177].",
"title": "Not Found Error",
"resource_type": "tweet",
"parameter": "ids",
"value": "1276230436478386177",
"type": "https://api.twitter.com/2/problems/resource-not-found"
}
]
}
Output: List < String > where one element in the list could look like this:
{
"attachments": {
"media_keys": [
"16_1276500934466703361"
]
},
"author_id": "783214",
"conversation_id": "1275244210439028736",
"created_at": "2020-06-23T01:48:07.000Z",
"entities": {
"urls": [
{
"start": 112,
"end": 135,
"url": "https://twitter.com/Twitter/status/1275244210439028736/photo/1",
"expanded_url": "https://twitter.com/Twitter/status/1275244210439028736/photo/1",
"display_url": "pic.twitter.com/dpI2lRmj9F"
}
]
},
"id": "1275244210439028736",
"text": "Need to follow what’s happening in real time? Change your timeline to show latest Tweets instead of top Tweets."
},
It would essentially grab one whole tweet's subJson and save it onto the List. This goes hand in hand with an issue I was facing a few days back concerning this problem , but I think the problem is that the JSON response I get back using the HTTP library is not able to be added properly onto a List.
List<Map<String, dynamic>> jsonRes =
(inputMap['data'] as List<Map>).map((t) => {
if (t.containsKey('attachments')) 'attachments': t['attachments'],
if (t.containsKey('author_id')) 'author_id': t['author_id'],
if (t.containsKey('conversation_id')) 'conversation_id': t['conversation_id'],
if (t.containsKey('created_at')) 'created_at': t['created_at'],
if (t.containsKey('entities')) 'entities': t['entities'],
if (t.containsKey('id')) 'id': t['id'],
if (t.containsKey('text')) 'text': t['text'],
}).toList();
List<String> stringRes = jsonRes.map((e) => jsonEncode(e)).toList();
Alternatively:
final List<String> wantedKeys = [
'attachments',
'author_id',
'conversation_id',
'created_at',
'entities',
'id',
'text'
];
List<Map<String, dynamic>> jsonRes = (inputMap['data']
as List<Map<String, dynamic>>)
.map((m) => Map.fromEntries(m.entries.where((e) => wantedKeys.contains(e.key))))
.toList();
List<String> stringRes = jsonRes.map((e) => jsonEncode(e)).toList();

JSON transformation with JQ / pyjq. Move objects from an object array to another array, matched by a identity field

I would like to add the orders[].packages[].status field to the orders[].contents[] with the matching packagenumber.
Input JSON:
{
"orders": [
{
"code": 2389,
"packages": [
{
"packagenumber": 3929,
"status": 100
},
{
"packagenumber": 3930,
"status": 110
}
],
"contents": [
{
"contentid": 398,
"description": "closet",
"packagenumber": 3929
},
{
"contentid": 399,
"description": "rice",
"packagenumber": 3929
},
{
"contentid": 400,
"description": "foo",
"packagenumber": 3930
}
]
},
{
"code": 2390,
"packages": [
{
"packagenumber": 3930,
"status": 110
},
{
"packagenumber": 3931,
"status": 150
}
],
"contents": [
{
"contentid": 500,
"description": "bar",
"packagenumber": 3931
},
{
"contentid": 501,
"description": "snicker",
"packagenumber": 3931
},
{
"contentid": 502,
"description": "mars",
"packagenumber": 3930
}
]
}
]
}
Desired output JSON:
{
"orders": [
{
"code": 2389,
"contents": [
{
"contentid": 398,
"description": "closet",
"packagenumber": 3929,
"status": 100
},
{
"contentid": 399,
"description": "rice",
"packagenumber": 3929,
"status": 100
},
{
"contentid": 400,
"description": "foo",
"packagenumber": 3930,
"status": 110
}
]
},
{
"code": 2390,
"contents": [
{
"contentid": 500,
"description": "bar",
"packagenumber": 3931,
"status": 150
},
{
"contentid": 501,
"description": "snicker",
"packagenumber": 3931,
"status": 150
},
{
"contentid": 502,
"description": "mars",
"packagenumber": 3930,
"status": 110
}
]
}
]
}
This moves the packages to the contents:
{shipments: [.orders[] | .packages as $packages | {code: .code, contents: [(.contents[] | ., $packages )] } ]}
With select, it is possible to get the a package, but I don't get the package that matches the packagenumber of the content work.
packages: .packages[] | select(.packagenumber==3930)
Question:
How can the input transformed to the desired output format? Using pyjq or jqplay.org?
You're looking for something like this:
.orders[] |= (
( .packages | INDEX(.packagenumber) ) as $r
| .contents[] |= . + ($r[.packagenumber | tostring] | {status})
| del(.packages)
)
Online demo

Hapi.js response with "type":"Buffer"

I have hapi.js, sequelize with mysql with script like this :
method: 'GET',
path: `/${GROUP_NAME}`,
options: {
tags: ['api', GROUP_NAME],
description: 'Mendapatkan jumlah tempat tidur berdasarkan kelas',
notes: 'Mendapatkan jumlah tempat tidur',
handler: async (request, h) => {
return jlhttidurbyjenis.findAll({ attributes: ['VIP','KELAS 1','KELAS 2','KELAS 3','ICU','NICU','PICU','HCU','ICCU','ISOLASI']})
},
validate: {
},
response: {
}
}
when I test with postman it response like this :
[
{
"VIP": {
"type": "Buffer",
"data": [
50,
47,
50,
50
]
},
"KELAS 1": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"KELAS 2": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"KELAS 3": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"ICU": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"NICU": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"PICU": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"HCU": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"ICCU": {
"type": "Buffer",
"data": [
48,
47,
48
]
},
"ISOLASI": {
"type": "Buffer",
"data": [
48,
47,
48
]
}
}
]
How to fix the script so the response will be the same with database content, it will be like this :
[
{
"VIP": "12/22",
"KELAS 1": "0/0",
"KELAS 2": "0/0",
"KELAS 3": "0/0",
"ICU": "0/0",
"NICU": "0/0",
"PICU": "0/0",
"HCU": "0/0",
"ICCU": "0/0",
"ISOLASI": "0/0"
}
]
That looks like a serialization issue from sequilize. Look at available configurations for JSON serialization with regards to buffer.

Modify array elements while grouping by a specific key using jq

Is it possible to modify/replace array elements while grouping by a specific key (.[].Parameter.Id) such that this array:
[{
"Id": 48,
"Parameter": {
"Id": 17
}
}, {
"Id": 196,
"Parameter": {
"Id": 17
}
}]
becomes this:
[
{
"p17": [48, 196]
}
]
Here is the source JSON file for a complete example:
[{
"Id": 78,
"PromotionType": 2,
"Amount": "100",
"UpperLimit": null,
"Variables": [{
"Id": 100,
"Parameter": {
"Id": 30
}
}]
}, {
"Id": 84,
"PromotionType": 2,
"Amount": null,
"UpperLimit": null,
"Variables": [{
"Id": 48,
"Parameter": {
"Id": 17
}
}, {
"Id": 196,
"Parameter": {
"Id": 17
}
}, {
"Id": 59,
"Parameter": {
"Id": 21
}
}, {
"Id": 60,
"Parameter": {
"Id": 21
}
}, {
"Id": 62,
"Parameter": {
"Id": 21
}
}]
}, {
"Id": 59,
"PromotionType": 2,
"Amount": "666.6",
"UpperLimit": null,
"Variables": [{
"Id": 96,
"Parameter": {
"Id": 8
}
}, {
"Id": 47,
"Parameter": {
"Id": 17
}
}]
}]
What I want to achieve is this:
[{
"Id": 78,
"PromotionType": 2,
"Amount": "100",
"UpperLimit": null,
"Variables": [{
"p30": [100]
}]
}, {
"Id": 84,
"PromotionType": 2,
"Amount": null,
"UpperLimit": null,
"Variables": [{
"p17": [48, 196]
}, {
"p21": [59, 60, 62]
}]
}, {
"Id": 59,
"PromotionType": 2,
"Amount": "666.6",
"UpperLimit": null,
"Variables": [{
"p8": [96]
}, {
"p17": [47]
}]
}]
I am reading through jq manual, jq cookbook and found some functions (e.g. with_entries, unique_by, inputs) that might help but could not figure out how to make it work.
Number of objects/inner objects are also not fixed. So I cannot simply replace using array indexes.
Any help would be appreciated.
Thanks,
Emre
jq solution:
jq 'map(.Variables
|= (group_by(.Parameter.Id)
| map(("p" + (.[0].Parameter.Id | tostring)) as $pid
| { ($pid) : map(.Id) }
)
)
)' input.json
The output:
[
{
"Id": 78,
"PromotionType": 2,
"Amount": "100",
"UpperLimit": null,
"Variables": [
{
"p30": [
100
]
}
]
},
{
"Id": 84,
"PromotionType": 2,
"Amount": null,
"UpperLimit": null,
"Variables": [
{
"p17": [
48,
196
]
},
{
"p21": [
59,
60,
62
]
}
]
},
{
"Id": 59,
"PromotionType": 2,
"Amount": "666.6",
"UpperLimit": null,
"Variables": [
{
"p8": [
96
]
},
{
"p17": [
47
]
}
]
}
]

How to do ngFor loop on nested json object?

It seems to be simple thing to do, but somehow i did not get inner array element to do ngFor loop on Angular 2.
I have json array as below, and i need to iterate through available 'routes' in my response array which is nested element.
Now can any one let me know how can i get route which should be simple and i am trying like this.routes=respondeJson[0].routes Or this.routes=resonseJson[0]['routes'] but no luck. Please help considering my entry level here on Angular 2 or say working with JSON.
[
{
"routes": {
"0": {
"budget": 326,
"toCity": "United States",
"QuoteIds": [
1,
2
],
"options": 2
},
"1": {
"budget": 374,
"toCity": "Thailand",
"QuoteIds": [
3,
4
],
"options": 2
},
"2": {
"budget": 382,
"toCity": "Singapore",
"QuoteIds": [
5,
6
],
"options": 2
},
"3": {
"budget": 451,
"toCity": "Taiwan",
"QuoteIds": [
7
],
"options": 1
},
"5": {
"budget": 112,
"toCity": "Turkey",
"QuoteIds": [
8
],
"options": 1
},
"6": {
"budget": 314,
"toCity": "Saudi Arabia",
"QuoteIds": [
9
],
"options": 1
},
"8": {
"budget": 518,
"toCity": "Indonesia",
"QuoteIds": [
10
],
"options": 1
},
"10": {
"budget": 384,
"toCity": "Hong Kong",
"QuoteIds": [
11,
12
],
"options": 2
},
"11": {
"budget": 232,
"toCity": "Qatar",
"QuoteIds": [
13
],
"options": 1
},
"22": {
"budget": 254,
"toCity": "Algeria",
"QuoteIds": [
14
],
"options": 1
},
"23": {
"budget": 241,
"toCity": "Kuwait",
"QuoteIds": [
15
],
"options": 1
},
"24": {
"budget": 175,
"toCity": "Israel",
"QuoteIds": [
16,
17
],
"options": 2
},
"25": {
"budget": 266,
"toCity": "Oman",
"QuoteIds": [
18,
19
],
"options": 2
},
"28": {
"budget": 762,
"toCity": "Argentina",
"QuoteIds": [
20,
21
],
"options": 2
},
"30": {
"budget": 78,
"toCity": "Iceland",
"QuoteIds": [
22
],
"options": 1
},
"37": {
"budget": 327,
"toCity": "Canada",
"QuoteIds": [
23,
24
],
"options": 2
},
"39": {
"budget": 238,
"toCity": "Iran",
"QuoteIds": [
25
],
"options": 1
},
"40": {
"budget": 129,
"toCity": "Cyprus",
"QuoteIds": [
26
],
"options": 1
},
"41": {
"budget": 267,
"toCity": "United Arab Emirates",
"QuoteIds": [
27,
28
],
"options": 2
},
"42": {
"budget": 252,
"toCity": "Lebanon",
"QuoteIds": [
29
],
"options": 1
},
"43": {
"budget": 427,
"toCity": "Iraq",
"QuoteIds": [
30
],
"options": 1
},
"50": {
"budget": 142,
"toCity": "Montenegro",
"QuoteIds": [
31
],
"options": 1
},
"55": {
"budget": 418,
"toCity": "Cuba",
"QuoteIds": [
32
],
"options": 1
},
"56": {
"budget": 492,
"toCity": "China",
"QuoteIds": [
33,
34
],
"options": 2
},
"57": {
"budget": 444,
"toCity": "India",
"QuoteIds": [
35
],
"options": 1
},
"62": {
"budget": 477,
"toCity": "Japan",
"QuoteIds": [
36,
37
],
"options": 2
},
"63": {
"budget": 3377,
"toCity": "Costa Rica",
"QuoteIds": [
38
],
"options": 1
},
"65": {
"budget": 210,
"toCity": "Georgia",
"QuoteIds": [
39
],
"options": 1
},
"66": {
"budget": 391,
"toCity": "Sri Lanka",
"QuoteIds": [
40,
41
],
"options": 2
},
"67": {
"budget": 258,
"toCity": "Russia",
"QuoteIds": [
42
],
"options": 1
},
"68": {
"budget": 82,
"toCity": "Poland",
"QuoteIds": [
43
],
"options": 1
},
"71": {
"budget": 104,
"toCity": "Finland",
"QuoteIds": [
44
],
"options": 1
},
"72": {
"budget": 150,
"toCity": "Austria",
"QuoteIds": [
45,
46
],
"options": 2
},
"73": {
"budget": 68,
"toCity": "Spain",
"QuoteIds": [
47
],
"options": 1
},
"75": {
"budget": 106,
"toCity": "Portugal",
"QuoteIds": [
48
],
"options": 1
},
"77": {
"budget": 37,
"toCity": "Romania",
"QuoteIds": [
49
],
"options": 1
},
"78": {
"budget": 66,
"toCity": "Sweden",
"QuoteIds": [
50
],
"options": 1
},
"79": {
"budget": 77,
"toCity": "Denmark",
"QuoteIds": [
51
],
"options": 1
},
"86": {
"budget": 440,
"toCity": "South Africa",
"QuoteIds": [
52,
53
],
"options": 2
},
"87": {
"budget": 176,
"toCity": "Morocco",
"QuoteIds": [
54,
55
],
"options": 2
},
"88": {
"budget": 231,
"toCity": "Serbia",
"QuoteIds": [
56
],
"options": 1
},
"89": {
"budget": 279,
"toCity": "Bosnia and Herzegovina",
"QuoteIds": [
57
],
"options": 1
},
"90": {
"budget": 35,
"toCity": "Italy",
"QuoteIds": [
58
],
"options": 1
},
"92": {
"budget": 72,
"toCity": "Hungary",
"QuoteIds": [
59
],
"options": 1
},
"93": {
"budget": 155,
"toCity": "Croatia",
"QuoteIds": [
60
],
"options": 1
},
"94": {
"budget": 160,
"toCity": "Malta",
"QuoteIds": [
61,
62
],
"options": 2
},
"95": {
"budget": 163,
"toCity": "Greece",
"QuoteIds": [
63,
64
],
"options": 2
},
"96": {
"budget": 67,
"toCity": "Ireland",
"QuoteIds": [
65
],
"options": 1
},
"97": {
"budget": 60,
"toCity": "Netherlands",
"QuoteIds": [
66
],
"options": 1
},
"98": {
"budget": 68,
"toCity": "Norway",
"QuoteIds": [
67
],
"options": 1
},
"99": {
"budget": 71,
"toCity": "Latvia",
"QuoteIds": [
68
],
"options": 1
},
"100": {
"budget": 261,
"toCity": "Belgium",
"QuoteIds": [
69
],
"options": 1
},
"101": {
"budget": 60,
"toCity": "Bulgaria",
"QuoteIds": [
70
],
"options": 1
},
"102": {
"budget": 130,
"toCity": "Switzerland",
"QuoteIds": [
71
],
"options": 1
},
"103": {
"budget": 140,
"toCity": "Ukraine",
"QuoteIds": [
72
],
"options": 1
},
"104": {
"budget": 72,
"toCity": "France",
"QuoteIds": [
73
],
"options": 1
},
"105": {
"budget": 56,
"toCity": "Lithuania",
"QuoteIds": [
74
],
"options": 1
},
"106": {
"budget": 51,
"toCity": "United Kingdom",
"QuoteIds": [
75
],
"options": 1
},
"109": {
"budget": 116,
"toCity": "Czech Republic",
"QuoteIds": [
76
],
"options": 1
},
"110": {
"budget": 59,
"toCity": "Germany",
"QuoteIds": [
77
],
"options": 1
},
"113": {
"budget": 272,
"toCity": "Bahrain",
"QuoteIds": [
78,
79
],
"options": 2
},
"128": {
"budget": 634,
"toCity": "New Zealand",
"QuoteIds": [
80
],
"options": 1
},
"147": {
"budget": 610,
"toCity": "Australia",
"QuoteIds": [
81
],
"options": 1
},
"167": {
"budget": 187,
"toCity": "Moldova",
"QuoteIds": [
82
],
"options": 1
},
"168": {
"budget": 87,
"toCity": "Slovakia",
"QuoteIds": [
83
],
"options": 1
},
"175": {
"budget": 119,
"toCity": "Gibraltar",
"QuoteIds": [
84
],
"options": 1
},
"178": {
"budget": 545,
"toCity": "Laos",
"QuoteIds": [
85
],
"options": 1
}
},
"misc": {
"QuoteDateTime": "2017-04-21T13:56:00",
"MinPrice": 326,
"Direct": false,
"QuoteId": 1,
"skyLink": "http://partners.api.skyscanner.net/apiservices/referral/v1.0/AU/AUD/en-US/anywhere/amd/2017-05-18/2017-05-22?apiKey=wc161029621991497683276175998396"
},
"price": [
326,
392,
374,
434,
382,
470,
451,
112,
314,
518,
384,
553,
232,
254,
241,
175,
199,
422,
266,
1125,
762,
78,
403,
327,
238,
129,
290,
267,
252,
427,
142,
418,
492,
641,
444,
477,
937,
3377,
210,
713,
391,
258,
82,
104,
160,
150,
68,
106,
37,
66,
77,
624,
440,
176,
287,
231,
279,
35,
72,
155,
210,
160,
163,
200,
67,
60,
68,
71,
261,
60,
130,
140,
72,
56,
51,
116,
59,
374,
272,
634,
610,
187,
87,
119,
545
],
"outbound": {
"DepartureDate": "2017-05-18T00:00:00",
"Carrier": "WOW air",
"DestinationId": "EWR",
"OriginId": "LGW"
},
"airline": [
"WOW air",
"Lufthansa",
"Gulf Air",
"EVA Air",
"Turkish Airlines",
"British Airways",
"Turkish Airlines",
"Pegasus Airlines",
"Pegasus Airlines",
"Singapore Airlines",
"Air India",
"British Airways",
"Pegasus Airlines",
"Vueling Airlines",
"Pegasus Airlines",
"Pegasus Airlines",
"Monarch",
"Oman Air",
"Turkish Airlines",
"British Airways",
"United",
"WOW air",
"Air Transat",
"WestJet",
"Pegasus Airlines",
"Cobalt",
"Royal Brunei ",
"Turkish Airlines",
"Pegasus Airlines",
"Pegasus Airlines",
"easyJet",
"KLM",
"Austrian Airlines",
"British Airways",
"Air India",
"Alitalia",
"British Airways",
"Avianca",
"Pegasus Airlines",
"SriLankan Airlines",
"Qatar Airways",
"Pegasus Airlines",
"Wizz Air",
"Norwegian",
"eurowings",
"eurowings",
"Vueling Airlines",
"Monarch",
"Blue Air",
"Norwegian",
"Norwegian",
"Virgin Atlantic",
"Ethiopian Airlines",
"Iberia",
"Thomson Airways",
"Wizz Air",
"Pegasus Airlines",
"Flybe",
"Wizz Air",
"Monarch",
"Air Malta",
"easyJet",
"Pegasus Airlines",
"Aegean Airlines",
"Aer Lingus",
"Vueling Airlines",
"Norwegian",
"Wizz Air",
"eurowings",
"Wizz Air",
"SWISS",
"Ukraine International",
"Vueling Airlines",
"Wizz Air",
"Flybe",
"Flybe",
"Flybe",
"British Airways",
"Pegasus Airlines",
"Qatar Airways",
"Royal Brunei ",
"Wizz Air",
"Wizz Air",
"Monarch",
"Singapore Airlines"
],
"inbound": {
"DepartureDate": "2017-05-22T00:00:00",
"Carrier": "Norwegian",
"OriginId": "JFK",
"DestinationId": "LGW"
}
},
{
"misc": {
"QuoteDateTime": "2017-04-19T06:33:00",
"MinPrice": 392,
"Direct": true,
"QuoteId": 2,
"skyLink": "http://partners.api.skyscanner.net/apiservices/referral/v1.0/AU/AUD/en-US/anywhere/amd/2017-05-18/2017-05-22?apiKey=wc161029621991497683276175998396"
},
"outbound": {
"DepartureDate": "2017-05-18T00:00:00",
"Carrier": "Lufthansa",
"DestinationId": "EWR",
"OriginId": "LHR"
},
"inbound": {
"DepartureDate": "2017-05-22T00:00:00",
"Carrier": "Austrian Airlines",
"OriginId": "EWR",
"DestinationId": "LHR"
}
}
]
You have gotten some good answers here, but all are manipulating your response and changing the build of it, instead of treating it as is. There is some other data in your response and want to retain the data, so here's a solution using Pipe instead.
You seem to have two objects in your array, but only one contains routes. Will this always be the case? If not, you might want to iterate the response and show all routes (if exists) for all objects, so I'd iterate the array first, and then iterate the routes:
<!-- Iterate array -->
<div *ngFor="let obj of jsonData">
<!-- iterate routes for each object using pipe -->
<div *ngFor="let route of obj.routes | keys">
{{route.toCity}}
</div>
</div>
And then the keys pipe:
#Pipe({ name: 'keys', pure: false })
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any[] {
// check if "routes" exists
if(value) {
// create instance vars to store keys and final output
let keyArr: any[] = Object.keys(value),
dataArr = [];
// loop through the object,
// pushing values to the return array
keyArr.forEach((key: any) => {
dataArr.push(value[key]);
});
// return the resulting array
return dataArr;
}
}
}
This way you have not manipulated your response, and you have access to all other data that is coming with the response.
Demo
You will want to convert your object to an iterable array.
this.http.get('data.json')
.subscribe((res) => {
let keyArr: any[] = Object.keys(res.json()[0].routes);
keyArr.forEach((key: any) => {
this.data.push(res.json()[0].routes[key]);
});
});
Here's a Plunker
Your routes should be defined as an json array however you have done a workaround to make routes as an array where you have explicitly given indexs (0, 1 ..) which is not correct.
Solution is attached below:
JSON should look like below:
[
{
"routes": [{
"budget": 326,
"toCity": "United States",
"QuoteIds": [
1,
2
],
"options": 2
}, {
"budget": 374,
"toCity": "Thailand",
"QuoteIds": [
3,
4
],
"options": 2
}
]
}
]
Way to assign it
this.routes=resonseJson[0]['routes']
Way to iterate it in html
<div *ngFor="let route of routes">
{{route.toCity}}
</div>
You have to iterate over object keys and not array elements. Hence either use
Object.keys(responseJson[0].routes)
that will return ["0","1", ..."178"]. Then use below:
in component .ts :
routes : any = responseJson[0].routes;
in template :
<div *ngFor="let key of Object.keys(routes)">
{{routes.key.budget}}
</div>