Unique sub-Json of a Json - json

let me start from a JSon object like
[
{
"id": 32837732,
"composer": {
"id": 536,
"name": "Francis Poulenc"
},
"title": "Of Thee I Sing: Overture (radio version)"
},
{
"id": 32837735,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : I. Allegro"
},
{
"id": 32837739,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : II. Adagio"
}
]
is it possible to get, in a clean, declarative way, a Json like
{
'composer': [
{
'id': '536',
'name': 'Francis Poulenc'
},
{
'id': '245',
'name': 'George Gershwin'
},
]
}
That is the unique sub-values for each composer (id and name)?

var arr= [
{
"id": 32837732,
"composer": {
"id": 536,
"name": "Francis Poulenc"
},
"title": "Of Thee I Sing: Overture (radio version)"
},
{
"id": 32837735,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : I. Allegro"
},
{
"id": 32837739,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : II. Adagio"
}
];
var composers=[];
arr.forEach(function(arrElem){
if(arrElem.composer && !composers.some(function(comp) { return comp.id === arrElem.composer.id && comp.name === arrElem.composer.name }))
composers.push(arrElem.composer);
});
alert( JSON.stringify( composers ));

Related

Card_V2 display issue in Google Chat

I have the following JSON to display Card_V2 for Google Chat, (note: words with "let_" are variables):
{
"cards_v2": [
{
"card": {
"header": {
"title": "Create campaign",
"subtitle": "Please complete the following information",
"imageType": "CIRCLE",
"imageUrl": "let_avatar"
},
"sections": [
{
"widgets": [
{
"textInput": {
"label": "Campaign name",
"type": "SINGLE_LINE",
"name": "nCampaign",
"value": "let_campaign"
}
},
{
"textInput": {
"label": "Campaign subject",
"type": "SINGLE_LINE",
"name": "subject",
"value": "let_subject"
}
},
{
"textInput": {
"label": "User name",
"type": "SINGLE_LINE",
"name": "userName",
"value": "let_userName"
}
},
{
"buttonList": {
"buttons": [
{
"text": "Create campaign",
"color": {
"red": 0.502,
"green": 1,
"blue": 0.733,
"alpha": 1
},
"onClick": {
"action": {
"function": "create",
"parameters": []
}
}
},
{
"text": "Cancel",
"color": {
"red": 0.502,
"green": 1,
"blue": 0.733,
"alpha": 1
},
"onClick": {
"action": {
"function": "cancel",
"parameters": []
}
}
}
]
},
"horizontalAlignment": "CENTER"
}
]
}
]
}
}
]
}
My problem is that the "textInput" screen does not appear, but last week it did. Does anyone have any idea what's going on?
PS: the Card is the return of the onMessage(event) function in Google Apps Script

Mapping the value of a json array using filter and groupby

My json is like below. I am trying to group my objects based on the role id for target id equal to 1083.
My json:
[ {
"id" :1,
"role": {
"id": "25",
},
"target": {
"id": "1083",
}
},
{
"id" :2,
"role": {
"id": "25",
},
"target": {
"id": "1083",
}
},
{
"id" :3,
"role": {
"id": "25",
},
"target": {
"id": "1084",
}
},
{
"id" :4,
"role": {
"id": "3",
},
"target": {
"id": "1083",
}
}
]
Expected result:
{
"25" : [
{
"id": 1
"role": {
"id": "25",
},
"target": {
"id": "1083",
}
},
{ "id": 2
"role": {
"id": "25",
},
"target": {
"id": "1083",
}
}
],
"3": [
{
"id" :4,
"role": {
"id": "3",
},
"target": {
"id": "1083",
}
}]
}
So for my result json, it's grouped by 25 and 3. The third record doesn't exist in my expected result as it's target id is 1084
I tried filter to get only target id 1083, but when I tried to use grouby, I am getting errors
data.filter(o => {
return o.target.id === "1083"
})
With lodash via filter and groupBy:
var data = [{ "id": 1, "role": { "id": "25", }, "target": { "id": "1083", } }, { "id": 2, "role": { "id": "25", }, "target": { "id": "1083", } }, { "id": 3, "role": { "id": "25", }, "target": { "id": "1084", } }, { "id": 4, "role": { "id": "3", }, "target": { "id": "1083", } } ]
const groupIt = (targetId) => _.chain(data)
.filter(x => x.target.id ===targetId)
.groupBy('role.id')
.value()
console.log(groupIt('1083'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
You could achieve the same without lodash via filter and then reduce:
var data = [{ "id": 1, "role": { "id": "25", }, "target": { "id": "1083", } }, { "id": 2, "role": { "id": "25", }, "target": { "id": "1083", } }, { "id": 3, "role": { "id": "25", }, "target": { "id": "1084", } }, { "id": 4, "role": { "id": "3", }, "target": { "id": "1083", } } ]
const groupIt = (targetId) => data.filter(x => x.target.id === targetId)
.reduce((r, c) => (r[c.role.id] = [...r[c.role.id] || [], c], r), {})
console.log(groupIt('1083'))

Returning metadata value from JSON API Response

I have an api request that returns JSON data which is then used to populate an html table. I am able to populate the table with item.name ... I would like to add the metadata value for player.field but I have not been able to access it. Here is the JSON response:
{
"list": [
{
"id": 55,
"name": "0046GS (RMS03241708)",
"description": "S 12-7 M-S 10-9",
"uuid": "6f4b5bfd-6d17-4095-9e48-7b9313f7f8c6",
"previewPlayer": false,
"enabled": true,
"mac": "00-00-00-00-00-00",
"type": "CHROMEBOX",
"distributionServer": {
"id": 2,
"name": "Main",
"driver": "IP_P2P"
},
"playergroups": [
{
"id": 2,
"name": "GameStop",
"numberOfPlayers": 454
}
],
"playerDisplays": [
{
"id": 55,
"name": "Display 1",
"channel": {
"id": 53,
"name": "GameStop TV"
},
"screenCounter": 1
}
],
"requestLogs": false,
"downloadThreads": 1,
"unusedFilesCache": 24,
"planDeliveryMethod": "CONTENT_MANAGER_DIRECT",
"pollingInterval": 1,
"pollingUnit": "MINUTES",
"logLevel": "normal",
"metadataValue": [
{
"id": 12512,
"value": "true",
"playerMetadata": {
"id": 34,
"name": "Player.field",
"datatype": "BOOLEAN",
"valueType": "ANY",
"order": 4
}
},
{
"id": 1085,
"value": "77056",
"playerMetadata": {
"id": 31,
"name": "Player.ZipCode",
"datatype": "STRING",
"valueType": "ANY",
"order": 30
}
},
{
"id": 1071,
"value": "22:15",
"playerMetadata": {
"id": 10,
"name": "Player.ScreenOff_Wednesday",
"datatype": "STRING",
"valueType": "ANY",
"order": 12
}
}
],
"usedPairingKey": "HBVULW",
"active": "ACTIVE",
"lastModified": "2017-04-03 20:12:43",
"timezoneOffset": "0"
}
],
"offset": 0,
"count": 68
}
Here is the ajax request:
$.ajax({
type: 'GET',
url: "https://sampleserver.com:8080/ContentManager/api/rest/players?limit=1&offset=0&sort=name&filters=%7BplayerStatus%20:%20%7Bvalues:%5B'ACTIVE'%5D,%20comparator%20:%20'eq'%7D%7D",
dataType: "json",
success: function(data) {
$.each(data.list, function(i, item) {
var tr = $('<tr><td>'+item.name+'</td><td>'+some.JSONResponse+'</td></tr>').appendTo('#scalaapi');
});
}
});
I am stuck on how to specifically display the value for player.field ... "value": "true",
It feels like it should be simple, but my attempts have all been met with undefined.
Attempted if statement...
success: function(data) {
$.each(data.list, function(i, item) {
var tr = $('<tr><td>'+item.name+'</td><td class="val">...</td></tr>').appendTo('#scalaapi');
var bool = function(i,item) {if (item.metadataValue.id = '12512');
tr.find('.val').text(bool);};
});
}
});

How to get a value of a object from its foreign key?

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

How to parse Json response and truncate child nodes

This is the JSON response I am trying to parse:
{
"data": {
"Content": {
"id": 26,
"name": "Dashboard1"
},
"List": [
{
"ListContent": {
"id": 178,
"name": "Card-144"
},
"cards": [
{
"id": 1780,
"configuration": {
"id": 7178,
"name": "Emp"
}
}
]
},
{
"ListContent": {
"id": 179,
"name": "Card-14"
},
"cards": [
{
"id": 1798,
"configuration": {
"id": 1789,
"name": "RandomColumns"
}
}
]
},
{
"ListContent": {
"id": 180,
"name": "Card-1"
},
"cards": [
{
"id": 18080,
"configuration": {
"id": 1080,
"allow": true
}
}
]
},
{
"ListContent": {
"id": 181,
"name": "Card-14"
},
"cards": [
{
"id": 18081,
"configuration": {
"id": 1881,
"name": "Functions"
}
}
]
},
{
"ListContent": {
"id": 182,
"name": "Card-1443"
},
"cards": [
{
"id": 1782,
"configuration": {
"id": 1802,
"name": "Emp-O"
}
}
]
}
]
}
}
From the Json, I need to extract "id"s under the "ListContent" nodes and store it in an array. Also, will need to ignore "id"s under the child nodes.
Here is a groovy script I am trying to achieve this with,
def CList = ""
import groovy.json.JsonSlurper
def jsonRespData = context.expand( '${TestStep#Response#$.data.List}' )
def outputResp = new JsonSlurper().parseText(jsonRespData)
outputResp.id.each()
{log.info( ":"+ it)
CList=CList.concat(it.toString()).concat(',')}
log.info (CList)
So, the array that I am expecting is CList [178,179,180,181,182]
but I am currently getting null.
What should be the correct groovy to only read "id" from "ListContent" and write it to an array?
Any help would be really appreciated.
Thanks in advance.
You can just use the (implicit) spread operator like this:
def json = new groovy.json.JsonSlurper().parse('/tmp/x.json' as File)
//
def i = json.data.List.ListContent.id
assert i == [178, 179, 180, 181, 182]
// with explicit spread operator
def e = json.data.List*.ListContent*.id
assert e == [178, 179, 180, 181, 182]
def str = '''
{
"data": {
"Content": {
"id": 26,
"name": "Dashboard1"
},
"List": [
{
"ListContent": {
"id": 178,
"name": "Card-144"
},
"cards": [
{
"id": 1780,
"configuration": {
"id": 7178,
"name": "Emp"
}
}
]
},
{
"ListContent": {
"id": 179,
"name": "Card-14"
},
"cards": [
{
"id": 1798,
"configuration": {
"id": 1789,
"name": "RandomColumns"
}
}
]
},
{
"ListContent": {
"id": 180,
"name": "Card-1"
},
"cards": [
{
"id": 18080,
"configuration": {
"id": 1080,
"allow": true
}
}
]
},
{
"ListContent": {
"id": 181,
"name": "Card-14"
},
"cards": [
{
"id": 18081,
"configuration": {
"id": 1881,
"name": "Functions"
}
}
]
},
{
"ListContent": {
"id": 182,
"name": "Card-1443"
},
"cards": [
{
"id": 1782,
"configuration": {
"id": 1802,
"name": "Emp-O"
}
}
]
}
]
}
}
'''
def outputResp = new groovy.json.JsonSlurper().parseText(str)
outputResp.data.List.collect { it.ListContent.id }
As you already have List from (context.expand( '${TestStep#Response#$.data.List}' )) , you can simply do:
outputResp.collect { it.ListContent.id }
Above returns an ArrayList.