Related
I am trying to display Notion content such as texts, dates, booleans and images on flutter app.. For texts, dates, and booleans, everything is working.. but I am stuck at displaying images. Please kindly take a look at my JSON file and my code.. and let me know where I am doing wrong..
JSON file that I got from my Notion database
{
"object": "list",
"results": [
{
"object": "page",
"id": "0f2aad20-225a-4d40-b853-fb5943e01636",
"created_time": "2022-09-01T05:14:00.000Z",
"last_edited_time": "2022-09-03T09:56:00.000Z",
"created_by": {
"object": "user",
"id": "33138aa4-0670-49f9-a118-daaef0698369"
},
"last_edited_by": {
"object": "user",
"id": "33138aa4-0670-49f9-a118-daaef0698369"
},
"cover": null,
"icon": null,
"parent": {
"type": "database_id",
"database_id": "f24cee3c-bd2f-466a-bc5f-a505e83b348f"
},
"archived": false,
"properties": {
"Price Range": {
"id": "BiJQ",
"type": "select",
"select": {
"id": "]erF",
"name": "< 2000 Lakh",
"color": "default"
}
},
"On Market": {
"id": "Bxp%60",
"type": "checkbox",
"checkbox": false
},
"Longitude ": {
"id": "CGYh",
"type": "number",
"number": 96.113146
},
"Asking Price in Lakh": {
"id": "Gv%7D%7D",
"type": "number",
"number": 590
},
"Township": {
"id": "MP%7D%3D",
"type": "select",
"select": {
"id": "qwfy",
"name": "Mingaladon - YGN",
"color": "default"
}
},
"Owner Phone": {
"id": "Mqhp",
"type": "phone_number",
"phone_number": "09448840549"
},
"Images": {
"id": "OLC%3B",
"type": "files",
"files": [
{
"name": "31_AUG-22.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/04b39e7e-c2c4-4ccd-a653-348933fa613e/31_AUG-22.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=2db13c256bfd191fc3fbc0941438a4a1c75a8da128b6f69b6e2a63002140327b&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.168Z"
}
},
{
"name": "31_AUG-21.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/06ce697d-af96-4f3e-b26e-bc092cacfdf8/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=33d5c21d71113008f3fbc4f95bf311515e4d42a3eb1f8c6c10fccc355e4e2d9a&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.209Z"
}
},
{
"name": "31_AUG-23.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/32ec9466-fe8a-4eb9-8c1b-0d0abbe8637b/31_AUG-23.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=059545c77b9a2330483d34292d2b7e4503d3e9f7ceac67cd44f63d56d6d8a0f0&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.271Z"
}
}
]
},
"Zone": {
"id": "O_ui",
"type": "select",
"select": {
"id": "bWGg",
"name": "13",
"color": "default"
}
},
"Progress": {
"id": "P%3C%7BM",
"type": "multi_select",
"multi_select": []
},
"Category": {
"id": "PM%5EA",
"type": "select",
"select": {
"id": "kLgI",
"name": "Residential",
"color": "default"
}
},
"Status": {
"id": "R%7B%5Dl",
"type": "select",
"select": {
"id": ":huS",
"name": "For Sale",
"color": "default"
}
},
"Latitude ": {
"id": "TUmm",
"type": "number",
"number": 16.955839
},
"Flooring": {
"id": "U%3FS%5D",
"type": "rich_text",
"rich_text": []
},
"Bathroom": {
"id": "WPEe",
"type": "number",
"number": 1
},
"Price Per Sqft": {
"id": "%5C%3Alg",
"type": "number",
"number": 21000
},
"Address": {
"id": "%5DSz%7C",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
"href": null
}
]
},
"Type": {
"id": "%5E%3E%40F",
"type": "select",
"select": {
"id": "Hb_}",
"name": "House",
"color": "default"
}
},
"State": {
"id": "%5E%7DP%60",
"type": "select",
"select": {
"id": ":fMv",
"name": "YGN",
"color": "default"
}
},
"Year Built": {
"id": "a%5C%5Ce",
"type": "number",
"number": 2014
},
"Data Source": {
"id": "awp%5B",
"type": "select",
"select": {
"id": "Ohch",
"name": "Facebook",
"color": "default"
}
},
"Electricity": {
"id": "bCpc",
"type": "select",
"select": {
"id": "=^]Q",
"name": "1 Single",
"color": "default"
}
},
"Cover Photo": {
"id": "bDDW",
"type": "files",
"files": [
{
"name": "31_AUG-21.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/b2784859-34d3-41c2-a88a-3311d8886804/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=eb7ab8e22917357922dfa939c250c5106f8e496888b564f17c622d804045f4ff&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.297Z"
}
}
]
},
"Contact": {
"id": "d_%5E%3E",
"type": "relation",
"relation": []
},
"Car Parking": {
"id": "gIBP",
"type": "number",
"number": 2
},
"Water System": {
"id": "gfRJ",
"type": "multi_select",
"multi_select": [
{
"id": "08a52b0a-cbbf-4e7d-8756-c2edb40a8ed9",
"name": "ဂျိုးဖြူရေ",
"color": "gray"
}
]
},
"Sold Date": {
"id": "giQA",
"type": "date",
"date": null
},
"Air Con": {
"id": "mP%5Dd",
"type": "number",
"number": 0
},
"Bedrooms": {
"id": "ptfQ",
"type": "select",
"select": {
"id": "O}`U",
"name": "3",
"color": "default"
}
},
"Owner Direct": {
"id": "py%40O",
"type": "checkbox",
"checkbox": false
},
"Lot Size (Sqft)": {
"id": "t%3AwQ",
"type": "number",
"number": 2795
},
"Type of Ownership": {
"id": "vgED",
"type": "select",
"select": {
"id": "37a4fbaa-955f-48d0-9a4d-4f5a28a8ca9a",
"name": "အရပ်စာချုပ်",
"color": "red"
}
},
"Added Time": {
"id": "x%3Byd",
"type": "last_edited_time",
"last_edited_time": "2022-09-03T09:56:00.000Z"
},
"ခြံအကျယ် (ပေ)": {
"id": "z%3D%3D%40",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "43x65",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "43x65",
"href": null
}
]
},
"Structure": {
"id": "%7Cj%5Er",
"type": "select",
"select": {
"id": "ad149505-37a9-4464-8d13-7ff1e34cef3f",
"name": "ပျဉ်ထောင်အိမ်",
"color": "blue"
}
},
"Property Title": {
"id": "%7Cn%3F%3E",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
"href": null
}
]
},
"360 Photo ": {
"id": "~yOp",
"type": "url",
"url": "https://kuula.co/share/collection/7vSsM?logo=0&info=1&fs=1&vr=0&sd=1&thumbs=1"
},
"Name": {
"id": "title",
"type": "title",
"title": [
{
"type": "text",
"text": {
"content": "YGN-13C-06",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "YGN-13C-06",
"href": null
}
]
}
},
"url": "https://www.notion.so/YGN-13C-06-0f2aad20225a4d40b853fb5943e01636"
},
How I get data from Notion
class NotionAPI {
final http.Client _client;
static const String _baseUrl = 'https://api.notion.com/v1/';
NotionAPI({http.Client? client}) : _client = client ?? http.Client();
void dispose() {
_client.close();
}
Future<List<NotionPropertyModel>> getProperties() async {
try {
final url =
'${_baseUrl}databases/${dotenv.env['NOTION_DATABASE_ID']}/query';
final response = await _client.post(
Uri.parse(url),
headers: {
HttpHeaders.authorizationHeader:
'Bearer ${dotenv.env['NOTION_API_KEY']}',
'Notion-Version': '2022-06-28',
},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
return (data['results'] as List)
.map((e) => NotionPropertyModel.fromMap(e))
.toList()
..sort((a, b) => b.date.compareTo(a.date));
} else {
throw const Failure(message: 'Something went wrong..STW!');
}
} catch (_) {
throw const Failure(message: 'Something went wrong..++++!');
}
}
}
My fromJson method
factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
final properties = map['properties'] as Map<String, dynamic>;
final dateStr = properties['Date']?['date']?['start'];
return NotionPropertyModel(
pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
priceInLakh:
(properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],
);
}
How I display on the screen
child: Column(
children: [
Image.network(itemData.coverPhoto),
Text(itemData.pptID),
Text(itemData.dataSource),
if (itemData.ownerDirect == true)
const Text(
'Owner Direct',
style: TextStyle(fontSize: 20),
)
],
),
Your cover image is a list of file so change this:
coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],
to
factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
final properties = map['properties'] as Map<String, dynamic>;
final dateStr = properties['Date']?['date']?['start'];
List coverList = properties['Cover Photo']?['files'] ?? [];
return NotionPropertyModel(
pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
priceInLakh:
(properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
coverPhoto: (coverList != null && coverList.isNotEmpty) ? coverList[0]['file']?['url'] : '',
);
}
I am trying to Extract and sum a particular value using group by from json collection in azure logic app. Trying to achieve this by applying "Condition" connector. My Json file looks like below:
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1",
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1",
},
]
}
]
I want to calculate the sum of Qty group by I_Id from array Res using logic app connector "Condition".
Note: As Res is an array, there can be repetition I_Id with same value, hence, the requirement to get the Qty count based on I_Id
There are few ways to achieve your requirement but here is one of the workaround that worked when reproduced from our end.
Firstly, I have initialised a temporary integer variable to iterated inside the "Res" Array using Until Loop by checking the length of "Res" using the below expression.
length(body('Parse_JSON')?['Release']?[0]?['Res'])
Inside Until I have used condition action to check if I_Id is same using the below expression to the left.
body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']
and below expression to the right
body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']
Then if the condition satisfies I'm adding the Qty using the expression as below.
add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])
Here is the flow of my logic app
[Optional step]
Considering the bigger picture, I have initialzed another variable quantity and added the resultant of Compose 4 to Qty variable
RESULTS:
Considering the below sample JSON
{
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
}
Here is the result
To avoid confusion try the below code view in your resource
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
},
"runAfter": {},
"type": "Compose"
},
"Compose_3": {
"inputs": "#variables('Qty')",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "temp",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Qty",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"Release": {
"items": {
"properties": {
"O_Id": {
"type": "string"
},
"R_ID": {
"type": "string"
},
"Res": {
"items": {
"properties": {
"A_Id": {
"type": "string"
},
"F_Qty": {
"type": "integer"
},
"I_Id": {
"type": "string"
},
"OL_Id": {
"type": "string"
},
"Qty": {
"type": "integer"
},
"RL_Id": {
"type": "string"
},
"Unique_Identifier": {
"type": "string"
}
},
"required": [
"A_Id",
"F_Qty",
"I_Id",
"OL_Id",
"Qty",
"RL_Id",
"Unique_Identifier"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"O_Id",
"R_ID",
"Res"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Condition": {
"actions": {
"Compose_2": {
"inputs": "#add(outputs('Compose_4'),variables('Qty'))",
"runAfter": {
"Compose_4": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_4": {
"inputs": "#add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])",
"runAfter": {},
"type": "Compose"
},
"Set_variable": {
"inputs": {
"name": "Qty",
"value": "#outputs('Compose_2')"
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"expression": {
"and": [
{
"equals": [
"#body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']",
"#body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "temp",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('temp'), length(body('Parse_JSON')?['Release']?[0]?['Res']))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
Im trying to use jq on kubernetes json output, to create new json object containing list of objects - container and image per pod, however im getting cartesian product.
my input data (truncated from sensitive info):
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2021-06-30T12:45:40Z",
"name": "pod-1",
"namespace": "default",
"resourceVersion": "757679286",
"selfLink": "/api/v1/namespaces/default/pods/pod-1"
},
"spec": {
"containers": [
{
"image": "image-1",
"imagePullPolicy": "Always",
"name": "container-1",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"readOnly": true
}
]
},
{
"image": "image-2",
"imagePullPolicy": "Always",
"name": "container-2",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"enableServiceLinks": true,
"priority": 0,
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "default-token-b954f",
"secret": {
"defaultMode": 420,
"secretName": "default-token-b954f"
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"message": "containers with unready status: [container-1 container-2]",
"reason": "ContainersNotReady",
"status": "False",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"message": "containers with unready status: [container-1 container-2]",
"reason": "ContainersNotReady",
"status": "False",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2021-06-30T12:45:40Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"image": "image-1",
"imageID": "",
"lastState": {},
"name": "container-1",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "Back-off pulling image \"image-1\"",
"reason": "ImagePullBackOff"
}
}
},
{
"image": "image-2",
"imageID": "",
"lastState": {},
"name": "container-2",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "Back-off pulling image \"image-2\"",
"reason": "ImagePullBackOff"
}
}
}
],
"qosClass": "BestEffort",
"startTime": "2021-06-30T12:45:40Z"
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": "",
"selfLink": ""
}
}
my command:
jq '.items[] | { "name": .metadata.name, "containers": [{ "name": .spec.containers[].name, "image": .spec.containers[].image }]} '
desired output:
{
"name": "pod_1",
"containers": [
{
"name": "container_1",
"image": "image_1"
},
{
"name": "container_2",
"image": "image_2"
}
]
}
output I get:
{
"name": "pod-1",
"containers": [
{
"name": "container-1",
"image": "image-1"
},
{
"name": "container-1",
"image": "image-2"
},
{
"name": "container-2",
"image": "image-1"
},
{
"name": "container-2",
"image": "image-2"
}
]
}
Could anyone explain what am I doing wrong?
Best Regards, Piotr.
The problem is "name": .spec.containers[].name and "image": .spec.containers[].image:
Both expressions generate a sequence of each value for name and image which will than be combined.
Simplified example of why you get a Cartesian product:
jq -c -n '{name: ("A", "B"), value: ("C", "D")}'
outputs:
{"name":"A","value":"C"}
{"name":"A","value":"D"}
{"name":"B","value":"C"}
{"name":"B","value":"D"}
You get the desired output using this jq filter on your input:
jq '
.items[]
| {
"name": .metadata.name,
"containers": .spec.containers
| map({name, image})
}'
output:
{
"name": "pod-1",
"containers": [
{
"name": "container-1",
"image": "image-1"
},
{
"name": "container-2",
"image": "image-2"
}
]
}
Here is my code:
<tbody class="mat-color--white tdw-card-thin tdw-border-2">
<tr class="tdw-hover-up-thin" *ngFor="let item of _mData | tdwSearchfilter: _mSearchField: _mSearchQuery | orderBy: order:reverse:'case-insensitive'; let iRow=index">
<th *ngIf="_mIsCheckable" class="tdw--text-align-right sort-remove">
<mat-checkbox [(ngModel)]="_mIsCheckedList[i]" ></mat-checkbox>
</th>
<th class="tdw-bottom-line-light tdw-padding-v-16 tdw-font-14 tdw-font-open-sans tdw-font-normal mat-color-text--grey-800"
*ngFor="let prop of _mColumns">{{item[prop.key]}}</th>
<th class=" tdw-bottom-line-light tdw-text-align-right" *ngIf="_mOptions">
<button mat-icon-button [matMenuTriggerFor]="optionMenu" (menuClosed)="onMenuClosed(iRow)">
<mat-icon>more_vert</mat-icon>
</button>
</th>
</tr>
</tbody>
and Typescript file will have following data fetched from server.
on server call am assigning these values
this._mColumns = this.tempData.headers;//success.headers;
this._mData = this.tempData.dataList.content;//success.dataList.content;
backend data:
tempData = {
"headers": [
{
"label": "User name",
"key": "userName"
},
{
"label": "First name",
"key": "userInfoDetails.firstName"
},
{
"label": "Middle name",
"key": "userInfoDetails.middleName"
},
{
"label": "Last name",
"key": "userInfoDetails.lastName"
},
{
"label": "Gender",
"key": "userInfoDetails.gender"
},
{
"label": "Personal number",
"key": "userInfoDetails.personalNumber"
},
{
"label": "Email",
"key": "userInfoDetails.emailAddress"
},
{
"label": "Home country",
"key": "userInfoDetails.homeCountry"
},
{
"label": "Career Level",
"key": "userInfoDetails.careerLevel"
},
{
"label": "Career PathwayDesc",
"key": "userInfoDetails.careerPathwayDesc"
},
{
"label": "Business UnitCode",
"key": "userInfoDetails.businessUnitCode"
},
{
"label": "business UnitDescription",
"key": "userInfoDetails.businessUnitDescription"
},
{
"label": "Dept number",
"key": "userInfoDetails.deptNumber"
},
{
"label": "Dept name",
"key": "userInfoDetails.deptName"
},
{
"label": "Operation Code",
"key": "userInfoDetails.operationCode"
},
{
"label": "Operation Description",
"key": "userInfoDetails.operationDescription"
},
{
"label": "DateOf joining",
"key": "userInfoDetails.dateOfJoining"
},
{
"label": "Address",
"key": "userInfoDetails.address"
},
{
"label": "Is contract employee",
"key": "userInfoDetails.isContractEmployee"
},
{
"label": "State",
"key": "userInfoDetails.state"
},
{
"label": "Contact number",
"key": "userInfoDetails.contactNumber"
},
{
"label": "Site name",
"key": "userInfoDetails.site.siteName"
}],
"dataList": {
"content": [
{
"userName": "Syed",
"userInfoDetails": {
"id": 1,
"firstName": "Syed", "middleName": "Akmal", "lastName": "Pasha",
"gender": "male", "personalNumber": 9589489884, "emailAddress": "syed#gmail.com",
"homeCountry": "India"
}
},
{
"userName": "Ryan",
"userInfoDetails": {
"id": 2,
"firstName": "Ryan", "middleName": "Sheiq", "lastName": "Samar",
"gender": "male", "personalNumber": 9589489848, "emailAddress": "syed#gmail.com",
"homeCountry": "Dubai"
}
}
],
"last": true,
"totalPages": 1,
"totalElements": 2,
"size": 20,
"number": 0,
"first": true,
"sort": null,
"numberOfElements": 2
}
};
The issue is it's not able to display the nested object like "userInfoDetails.firstName" but its showing the content of immediate object but not the child object.
Im using Backand to store my data. I have an object, Events, that references another object, Locations.
{
"name": "events",
"fields": {
"eventCommentsId": {
"collection": "comments",
"via": "eventId"
},
"tags": {
"collection": "events_tags",
"via": "event"
},
"users": {
"collection": "users_events",
"via": "event"
},
"name": {
"type": "string"
},
"date": {
"type": "datetime"
},
"time": {
"type": "datetime"
},
"info": {
"type": "text"
},
"locationId": {
"object": "locations"
}
},
{
"name": "locations",
"fields": {
"events": {
"collection": "events",
"via": "locationId"
},
"name": {
"type": "text"
},
"geo": {
"type": "point"
}
}
}
When I try to display the location of the event, I can only get the value of locationID. I want the actual name of the location, not the id. How do I do that?
<ion-list>
<ion-item class="item item-thumbnail-left" ng-repeat="event in events" type="item-text-wrap" href="#/event-detail/{{event.id}}">
<h2>{{event.name}}</h2>
<p><i class="ion-location"></i> {{event.locationId.name}}</p>
<ion-option-button class="button-assertive" ng-click="deleteEvent(event.id)">
Delete
</ion-option-button>
</ion-item>
</ion-list>
angular code
.service('EventService', function ($http, Backand) {
var baseUrl = '/1/objects/';
var objectName = 'events/';
function getUrl() {
return Backand.getApiUrl() + baseUrl + objectName;
}
function getUrlForId(id) {
return getUrl() + id;
}
getEvents = function () {
return $http.get(getUrl());
};
addEvent = function(event) {
return $http.post(getUrl(), event);
}
deleteEvent = function (id) {
return $http.delete(getUrlForId(id));
};
getEvent = function (id) {
return $http.get(getUrlForId(id));
};
return {
getEvents: getEvents,
addEvent: addEvent,
deleteEvent: deleteEvent,
getEvent: getEvent
}
})
.controller('FeedCtrl', ['$scope', '$ionicModal', '$ionicSideMenuDelegate', 'EventService', function($scope, $ionicModal, $ionicSideMenuDelegate, EventService) {
$scope.events = [];
$scope.input = {};
function getAllEvents() {
EventService.getEvents()
.then(function (result) {
$scope.events = result.data.data;
});
}
$scope.addEvent = function() {
EventService.addEvent($scope.input)
.then(function(result) {
$scope.input = {};
getAllEvents();
});
}
$scope.deleteEvent = function(id) {
EventService.deleteEvent(id)
.then(function (result) {
getAllEvents();
});
}
getAllEvents();
}])
There are two options. You can either use the descriptive value in the __metadata of each object like this:
request: https://api.backand.com/1/objects/events?pageSize=20&pageNumber=1
response:
{
"totalRows": 2,
"data": [
{
"__metadata": {
"id": "1",
"fields": {
"id": {
"type": "int",
"unique": true
},
"name": {
"type": "string"
},
"date": {
"type": "datetime"
},
"time": {
"type": "datetime"
},
"info": {
"type": "text"
},
"locationId": {
"object": "locations"
}
},
"descriptives": {
"locationId": {
"label": "Madison Square Garden",
"value": "1"
}
},
"dates": {
"date": "",
"time": ""
}
},
"id": 1,
"name": "knicks vs warriors",
"date": null,
"time": null,
"info": "",
"locationId": "1"
},
{
"__metadata": {
"id": "2",
"fields": {
"id": {
"type": "int",
"unique": true
},
"name": {
"type": "string"
},
"date": {
"type": "datetime"
},
"time": {
"type": "datetime"
},
"info": {
"type": "text"
},
"locationId": {
"object": "locations"
}
},
"descriptives": {
"locationId": {
"label": "Madison Square Garden",
"value": "1"
}
},
"dates": {
"date": "",
"time": ""
}
},
"id": 2,
"name": "knicks vs cavs",
"date": null,
"time": null,
"info": "",
"locationId": "1"
}
]
}
or you can do a deep request and get the value in the relatedObjects
request: https://api.backand.com/1/objects/events?pageSize=20&pageNumber=1&deep=true
response:
{
"totalRows": 2,
"data": [
{
"__metadata": {
"id": "1",
"fields": {
"id": {
"type": "int",
"unique": true
},
"name": {
"type": "string"
},
"date": {
"type": "datetime"
},
"time": {
"type": "datetime"
},
"info": {
"type": "text"
},
"locationId": {
"object": "locations"
}
},
"descriptives": {
"locationId": {
"label": "Madison Square Garden",
"value": "1"
}
},
"dates": {
"date": "",
"time": ""
}
},
"id": 1,
"name": "knicks vs warriors",
"date": null,
"time": null,
"info": "",
"locationId": "1"
},
{
"__metadata": {
"id": "2",
"fields": {
"id": {
"type": "int",
"unique": true
},
"name": {
"type": "string"
},
"date": {
"type": "datetime"
},
"time": {
"type": "datetime"
},
"info": {
"type": "text"
},
"locationId": {
"object": "locations"
}
},
"descriptives": {
"locationId": {
"label": "Madison Square Garden",
"value": "1"
}
},
"dates": {
"date": "",
"time": ""
}
},
"id": 2,
"name": "knicks vs cavs",
"date": null,
"time": null,
"info": "",
"locationId": "1"
}
],
"relatedObjects": {
"locations": {
"1": {
"__metadata": {
"id": "1",
"fields": {
"id": {
"type": "int",
"unique": true
},
"events": {
"collection": "events",
"via": "locationId"
},
"name": {
"type": "text"
},
"geo": {
"type": "point"
}
},
"descriptives": {},
"dates": {}
},
"id": 1,
"events": null,
"name": "Madison Square Garden",
"geo": [
40.7505,
73.9934
]
}
}
}
}
search for Madison Square Garden as the name of the location to understand the JSON structure.
You can set the descriptive field in the Object Settings