Unmarshal deeply nested json in golang - json

I have an ugly way of unmarshalling the following json, but it requires much manual work. I am looking for a more programmatic way to obtain the various team names, if I didn't know how many teams exactly there were originally. It's truly one of the most poorly structured api's I've come across.
data := []byte(`{
"fantasy_content": {
"copyright": "Data provided by Yahoo! and STATS, LLC",
"league": [
{
"allow_add_to_dl_extra_pos": 0,
"current_week": "1",
"draft_status": "predraft",
"edit_key": "1",
"end_date": "2017-12-25",
"end_week": "16",
"game_code": "nfl",
"is_cash_league": "0",
"is_pro_league": "0",
"league_id": "XXXXX",
"league_key": "XXXX",
"league_type": "private",
"league_update_timestamp": null,
"name": "XXXXXX",
"num_teams": 14,
"renew": "XXXX",
"renewed": "",
"scoring_type": "head",
"season": "2017",
"short_invitation_url": "XXXXX",
"start_date": "2017-09-07",
"start_week": "1",
"url": "XXXXXX",
"weekly_deadline": ""
},
{
"teams": {
"0": {
"team": [
[
{
"team_key": "XXXX"
},
{
"team_id": "1"
},
{
"name": "XXXXX"
},
[],
{
"url": "XXXXX"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"XXX"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXXXX",
"guid": "XX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"is_commissioner": "1",
"manager_id": "1",
"nickname": "Andrew"
}
}
]
}
]
]
},
"1": {
"team": [
[
{
"team_key": "XXXXX"
},
{
"team_id": "2"
},
{
"name": "XXXXX"
},
[],
{
"url": "XXXXX"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"url": "XXXX"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXXX#yahoo.com",
"guid": "XXXX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"manager_id": "2",
"nickname": "Andrew"
}
},
{
"manager": {
"email": "XXX#yahoo.com",
"guid": "XX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"is_comanager": "1",
"manager_id": "15",
"nickname": "XX"
}
}
]
}
]
]
},
"10": {
"team": [
[
{
"team_key": "XXX"
},
{
"team_id": "11"
},
{
"name": "XXX"
},
[],
{
"url": "https://football.fantasysports.yahoo.com/f1/XXX"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"url": "https://s.yimg.com/dh/ap/fantasy/nfl/img/icon_01_100.png"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXX#gmail.com",
"guid": "XX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"manager_id": "11",
"nickname": "XX"
}
}
]
}
]
]
},
"2": {
"team": [
[
{
"team_key": "371.l.102542.t.3"
},
{
"team_id": "3"
},
{
"name": "XXX"
},
[],
{
"url": "https://football.fantasysports.yahoo.com/f1/XX/3"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"url": "https://ct.yimg.com/cy/5603/30147468023_1c705edb29_192sq.jpg?ct=fantasy"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXXgmail.com",
"guid": "XXXX",
"image_url": "https://s.yimg.com/wv/images/6c93ed606f742d4c075bc091633cc072_64.jpg",
"manager_id": "3",
"nickname": "XX"
}
}
]
}
]
]
},
"3": {
"team": [
[
{
"team_key": "371.l.102542.t.4"
},
{
"team_id": "4"
},
{
"name": "XX"
},
[],
{
"url": "https://football.fantasysports.yahoo.com/f1/XX/4"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"url": "https://s.yimg.com/dh/ap/fantasy/nfl/img/icon_10_100.png"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXX#yahoo.com",
"guid": "XX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"manager_id": "4",
"nickname": "XX"
}
}
]
}
]
]
},
"8": {
"team": [
[
{
"team_key": "XXX"
},
{
"team_id": "9"
},
{
"name": "XxX"
},
[],
{
"url": "https://football.fantasysports.yahoo.com/f1/XX/9"
},
{
"team_logos": [
{
"team_logo": {
"size": "large",
"url": "https://ct.yimg.com/cy/8393/28682944304_33bda49603_192sq.jpg?ct=fantasy"
}
}
]
},
[],
{
"waiver_priority": ""
},
{
"faab_balance": "100"
},
{
"number_of_moves": 0
},
{
"number_of_trades": 0
},
{
"roster_adds": {
"coverage_type": "week",
"coverage_value": "1",
"value": "0"
}
},
[],
{
"league_scoring_type": "head"
},
[],
[],
{
"has_draft_grade": 0
},
[],
[],
{
"managers": [
{
"manager": {
"email": "XXX",
"guid": "XXX",
"image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
"manager_id": "9",
"nickname": "XXX"
}
}
]
}
]
]
},
"count": 14
}
}
],
"refresh_rate": "60",
"time": "110.55207252502ms",
"xml:lang": "en-US",
"yahoo:uri": "/fantasy/v2/league/XXXX/teams"
}
}`)
The following works, but it's a hassle and I have to hard code the different struct values per team, to get data for that team.
type TeamApi_ struct {
TeamKey string `json:"team_key"`
TeamId string `json:"team_id"`
Name string `json:"name"`
}
type LeaguesApi struct {
NumTeams int `json:"num_teams"`
TeamsApi struct {
Zero struct {
TeamsApi_ [][]TeamApi_ `json:"team"`
} `json:"0"`
One struct {
TeamsApi_ [][]TeamApi_ `json:"team"`
} `json:"1"`
Two struct {
TeamsApi_ [][]TeamApi_ `json:"team"`
} `json:"2"`
Three struct {
TeamsApi_ [][]TeamApi_ `json:"team"`
} `json:"3"`
} `json:"teams"`
}
type LeagueApiResult struct {
FantasyContent struct {
LeagueApi []LeaguesApi `json:"league"`
} `json:"fantasy_content"`
}
var Result LeagueApiResult
err := json.Unmarshal(data, &Result)
if err != nil {
fmt.Println(err)
}
fmt.Println(Result.FantasyContent.LeagueApi[1].TeamsApi.One.TeamsApi_[0][2].Name)

You probably want to use a custom JSON unmarshaller for this. You can see an example of how to use one here: http://choly.ca/post/go-json-marshalling/
Since the data is structured the way it is, with the teams section both containing teams and the count field, you'll likely need a fair bit of manual logic in there.
First, you can start by defining the League:
type League struct {
AllowAddToDlExtraPos int `json:"allow_add_to_dl_extra_pos,omitempty"`
CurrentWeek string `json:"current_week,omitempty"`
DraftStatus string `json:"draft_status,omitempty"`
EditKey string `json:"edit_key,omitempty"`
EndDate string `json:"end_date,omitempty"`
EndWeek string `json:"end_week,omitempty"`
GameCode string `json:"game_code,omitempty"`
IsCashLeague string `json:"is_cash_league,omitempty"`
IsProLeague string `json:"is_pro_league,omitempty"`
LeagueID string `json:"league_id,omitempty"`
LeagueKey string `json:"league_key,omitempty"`
LeagueType string `json:"league_type,omitempty"`
LeagueUpdateTimestamp interface{} `json:"league_update_timestamp,omitempty"`
Name string `json:"name,omitempty"`
NumTeams int `json:"num_teams,omitempty"`
Renew string `json:"renew,omitempty"`
Renewed string `json:"renewed,omitempty"`
ScoringType string `json:"scoring_type,omitempty"`
Season string `json:"season,omitempty"`
ShortInvitationURL string `json:"short_invitation_url,omitempty"`
StartDate string `json:"start_date,omitempty"`
StartWeek string `json:"start_week,omitempty"`
URL string `json:"url,omitempty"`
WeeklyDeadline string `json:"weekly_deadline,omitempty"`
Teams []Team `json:"-"`
}
Next, we can define the Team structure the way we want it to look.
type Team struct {
// Declare the fields of a Team
}
And finally, we declare a custom unmarshal function for the League.
func (l *League) UnmarshalJSON(data []byte) error {
type Alias League
aux := &struct {
*Alias
Teams map[string]interface{} `json:"teams"`
}{
Alias: (*Alias)(l),
}
if err := json.Unmarshal(data, aux); err != nil {
return err
}
var teams []Team
for num, team := range aux.Teams {
// Add your code to parse each of the teams from the
// map you declared above.
}
l.Teams = teams
return nil
}
The unmarshal function will be called by Golangs json library automatically when it hits the League structure inside the LeagueApiResult.

Related

Sort complex JSON object by specific property

How can I sort the given JSON object with property count. I want to sort the entire sub-object. The higher the count value should come on the top an so on.
{
"Resource": [
{
"details": [
{
"value": "3.70"
},
{
"value": "3.09"
}
],
"work": {
"count": 1
}
},
{
"details": [
{
"value": "4"
},
{
"value": "5"
}
],
"work": {
"count": 2
},
{
"details": [
{
"value": "5"
},
{
"value": "5"
}
],
"work": "null"
}
]
}
You can try this example to sort your data:
data = {
"data": {
"Resource": [
{
"details": [{"value": "3.70"}, {"value": "3.09"}],
"work": {"count": 1},
},
{"details": [{"value": "4"}, {"value": "5"}], "work": {"count": 2}},
]
}
}
# sort by 'work'/'count'
data["data"]["Resource"] = sorted(
data["data"]["Resource"], key=lambda r: r["work"]["count"]
)
# sort by 'details'/'value'
for r in data["data"]["Resource"]:
r["details"] = sorted(r["details"], key=lambda k: float(k["value"]))
# pretty print:
import json
print(json.dumps(data, indent=4))
Prints:
{
"data": {
"Resource": [
{
"details": [
{
"value": "3.09"
},
{
"value": "3.70"
}
],
"work": {
"count": 1
}
},
{
"details": [
{
"value": "4"
},
{
"value": "5"
}
],
"work": {
"count": 2
}
}
]
}
}

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'))

unable to extract value using ._find

I have the following node.js code where I want to extract the value "abc" chosen by user as a name. I get result as undefined when I run this code:
let input= [
{
"param": [
{
"id": "name",
"choice": [
{
"label": "abc",
"value": "abc",
"valueId": "abc"
}
]
},
{
"id": "alias",
"choice": [
{
"label": "dsf",
"value": "dsf",
"valueId": "dsf"
}
]
},
{
"id": "description",
"choice": [
{
"label": "",
"value": "",
"valueId": ""
}
]
},
{
"id": "Key",
"choice": [
{
"label": "K",
"value": "K",
"valueId": "K"
}
]
},
{
"id": "tagKey",
"choice": [
{
"label": "",
"value": "",
"valueId": ""
}
]
},
{
"id": "tagValue",
"choice": [
{
"label": "",
"value": "",
"valueId": ""
}
]
},
{
"id": "multiquantity",
"choice": [
{
"label": "1",
"valueId": "1",
"value": "1"
}
]
}
],
"old": [],
"current": null
}
]
let result = (_.find(input.param, {id: "name"})).choice[0].valueId;
console.log("value"+result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Seems that the logic is not able to extract the correct value. I need the output as abc. please help

How to exclude specific fields from JSON using groovy

I would like to exclude the items which don't have productModel property in the below JSON. How can we achieve this in groovy
I tried using hasProperty but not worked for me as expected. If possible can I get some sample snippet
I tried below code - but didn't work as I expected.
response.getAt('myData').getAt('data').getAt('product').hasProperty('productModel').each { println "result ${it}" }
Any help would be really appreciated.
{
"myData": [{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "6s"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
},
{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "7"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
},
{
"data": {
"product": {
"productId": "apple",
"productName": "Macbook"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
}
],
"metadata": {
"count": 3,
"offset": 0
}
}
If you want to exclude specific fields from JSON object then you have to recreate it using filtered data. The crucial part takes these two lines (assuming that json variable in the below example stores your JSON as text):
def root = new JsonSlurper().parseText(json)
def myData = root.myData.findAll { it.data.product.containsKey('productModel') }
What happens here is we access root.myData list and we filter it using findAll(predicate) method and predicate in this case says that only objects that have key productModel in path data.product are accepted. This findAll() method does not mutate existing list and that is why we store the result in variable myData - after running this method we will end up with a list of size 2.
In next step you have to recreate the object you want to represent as a JSON:
def newJsonObject = [
myData: myData,
metadata: [
count: myData.size(),
offset: 0
]
]
println JsonOutput.prettyPrint(JsonOutput.toJson(newJsonObject))
In this part we create newJsonObject and in the end we convert it to a JSON representation.
Here is the full example:
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def json = '''{
"myData": [{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "6s"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
},
{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "7"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
},
{
"data": {
"product": {
"productId": "apple",
"productName": "Macbook"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {}
}
],
"metadata": {
"count": 3,
"offset": 0
}
}'''
def root = new JsonSlurper().parseText(json)
def myData = root.myData.findAll { it.data.product.containsKey('productModel') }
def newJsonObject = [
myData: myData,
metadata: [
count: myData.size(),
offset: 0
]
]
println JsonOutput.prettyPrint(JsonOutput.toJson(newJsonObject))
And here is the output it produces:
{
"myData": [
{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "6s"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [
{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {
}
},
{
"data": {
"product": {
"productId": "apple",
"productName": "iPhone",
"productModel": "7"
},
"statusCode": "active",
"date": "2018-08-07T00:00:00.000Z"
},
"links": [
{
"productUrl": "test"
},
{
"productImage": "test"
}
],
"info": {
}
}
],
"metadata": {
"count": 2,
"offset": 0
}
}

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