Parsing non consistent json response length in excel vba - json

Using VBA-JSON v2.0.1 in excel VBA
Here is the JSON response I get from API query
{
"currency": {
"code": "USD",
"name": "US Dollar",
"prefix": "$",
"postfix": null
},
"products": [
{
"product_id": xxxxx,
"model_code": "xxxxx",
"quantity": 1,
"price": "45.60",
"total": "45.60",
"retail_price": "63.84"
}
],
"shipping": [
{
"name": "UPS",
"price": 43.83,
"delivery": "3 -10 Days delivery"
},
{
"name": "DHL",
"price": 20.29,
"delivery": "2-6 days"
},
{
"name": "FedEx",
"price": 31.46,
"delivery": "2-6 days"
},
{
"name": "EMS",
"price": 25.74,
"delivery": "7 - 25 Days delivery"
},
{
"name": "Air Mail",
"price": 11.85,
"delivery": "10 - 25 Days delivery"
}
]
}
Here is a part of my code to parse the price from "Air Mail" element.
result = objHTTP.responseText
Dim Json As Object
Dim resultAirmailprice As String
Set Json = JsonConverter.ParseJson(result)
resultAirmailprice = Json("shipping")(5)("price")
Cells(2, 2).Value = resultAirmailprice
The code runs fine when the "Air Mail" element is in (5) of "shipping" element. The problem is sometimes there are no "UPS" and "Air Mail" elements, so I got an error.
How to write code to parse the "Air Mail" price and if not exists, parse from "EMS" price(or the cheapest price out of all)?

Looking at Json parser code, it returns a Dictionary Object that contains other Dictionary Objects (sub keys) and, for arrays, Collection Objects. In the Json I see that "shipping" is an array and so the parser returns a Collection Object.
So you can use all the Collection members and methods to manipulate and access it. In particular, you can use Json("shipping").Count to check how many elements the Shipping collection has. Or you can iterate over the collection with For each x in Json("shipping").
To check whether you have a Dictionary or a Collection, you could use the TypeName function or the TypeOf..Is operator.

Related

Convert Java Object into JSON Object

We are using Airbyte to sync MongoDB data into Snowflake. For some reason, our JSON lists are synched as what appear to be Java Objects.
I am trying to get the data into a JSON format, so I can work with the properties.
Example of Java object row in our cost column:
"[Document{{currency=USD, value=815.00}}, Document{{currency=EUR, value=671.00}}, Document{{currency=GBP, value=579.00}}, Document{{currency=DKK, value=4992.00}}, Document{{currency=SEK, value=6760.00}}]"
I want to convert the row into the following format
[{
"currency": "USD",
"value": 815.00
}, {
"currency": "EUR",
"value": 671.00
}, {
"currency": "GBP",
"value": 579.00
}, {
"currency": "DKK",
"value": 4992.00
}, {
"currency": "SEK",
"value": 6760.00
}]
How can I accomplish that in Snowflake?
You can use regex but it's not the most elegant way:
set term='[Document{{currency=USD, value=815.00}}, Document{{currency=EUR, value=671.00}}, Document{{currency=GBP, value=579.00}}, Document{{currency=DKK, value=4992.00}}, Document{{currency=SEK, value=6760.00}}]';
select regexp_replace(regexp_replace(regexp_replace($term, 'Document',''), '}}', '}'), '{{', '{');
I get:
[{currency=USD, value=815.00}, {currency=EUR, value=671.00}, {currency=GBP, value=579.00}, {currency=DKK, value=4992.00}, {currency=SEK, value=6760.00}]
This can be further extended to replace currency with "currency".

Optimum Serializing in Django Rest Framework and parsing in Javascript

I am trying to adapt an event calendar vuejs module called dayspan calendar. Current entry object for an event as json is a bit strange and I want to balance the parsing of the payload before the post request and handling of data in DRF serializers. So I can get an optimum and performant client-server rest API communication. Json output is as below before any parsing:
{
"data": {
"title": "YOK",
"description": "",
"location": "",
"color": "#1976d2",
"forecolor": "#ffffff",
"calendar": "",
"busy": true,
"icon": ""
},
"schedule": {
"times": [
"17"
],
"dayOfMonth": [
11
],
"year": [
2021
],
"month": [
5
]
}
}
There are more schedule fields like "dayOFWeek", "duration" etc. that is to be expected for different entries.
What would be the best approach in terms of parsing json payload before posting to DRF and in deserializing stage before saving into database? I appreciate any ideas.

Spring - Ignore JSON properties in request but not in response

This is a valid Entry object retrieved from a GET request http://domain/entry/{id}:
{
"id": 1,
"description": "ML Books",
"dueDate": "2017-06-10",
"paymentDate": "2017-06-10",
"note": "Distribution de lucros",
"value": 6500,
"type": "INCOME",
"category": {
"id": 2,
"name": "Food"
},
"person": {
"id": 3,
"name": "User",
"active": true,
"address": {
// properties suppressed for better reading
}
}
}
In a POST request I want to save the foreing objects Category and Person just sending the respective Id's, like this:
{
"description": "NEW ENTRY",
"dueDate": "2019-06-22",
"paymentDate": "2019-06-22",
"note": "Coloured pens",
"value": 10,
"type": "INCOME",
"categoryId": 5,
"personId": 5
}
To save the objects without Spring saying the person and category objects were null, I've added #JsonIgnore to them in the model, and followed this thread.
It partially worked:
now it saves de object just with the Id
but not retrieves the object in GET requests
Now, when retrieving a Entry with the same GET request http://domain/entry/{id}:
{
"id": 23,
"description": "Pens",
"dueDate": "2019-06-22",
"paymentDate": "2019-06-22",
"note": "Coloured pens",
"value": 10,
"type": "INCOME",
"categoryId": null, // It supposed to bring the entire object
"personId": null // It supposed to bring the entire object
}
PS: categoryId and personId are marked with #Transient, that's why it are null.
So as the title states, I want to ignore the properties Category and Person just in POST request (saving them), not in GET requests (retrieving them).
Any help will be welcome.
Thanks in advance
Jackson have added READ_ONLY and WRITE_ONLY annotation arguments for JsonProperty. So you could also do something like:
#JsonProperty(access = JsonProperty.Access.READ_ONLY)
#Id
#GeneratedValue
private Long id;

Google json style guide: How to send single item response?

There is an items node in the specifications which says it is for an array of items, like paging items, youtube video list
What if I have GET request on a single item, how should the response be formatted ?
Just to one item in the array?
items:[item]
https://google.github.io/styleguide/jsoncstyleguide.xml
I don't think #tanmay_vijay's answer is correct or nuanced enough as it seems that single item responses are in arrays in the YouTube example in the docs.
{
"apiVersion": "2.0",
"data": {
"updated": "2010-02-04T19:29:54.001Z",
"totalItems": 6741,
"startIndex": 1,
"itemsPerPage": 1,
"items": [
{
"id": "BGODurRfVv4",
"uploaded": "2009-11-17T20:10:06.000Z",
"updated": "2010-02-04T06:25:57.000Z",
"uploader": "docchat",
"category": "Animals",
"title": "From service dog to SURFice dog",
"description": "Surf dog Ricochets inspirational video ...",
"tags": [
"Surf dog",
"dog surfing",
"dog",
"golden retriever",
],
"thumbnail": {
"default": "https://i.ytimg.com/vi/BGODurRfVv4/default.jpg",
"hqDefault": "https://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg"
},
"player": {
"default": "https://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata",
"mobile": "https://m.youtube.com/details?v=BGODurRfVv4"
},
"content": {
"1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
"5": "https://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata",
"6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
},
"duration": 315,
"rating": 4.96,
"ratingCount": 2043,
"viewCount": 1781691,
"favoriteCount": 3363,
"commentCount": 1007,
"commentsAllowed": true
}
]
}
}
It could however be that it depends on the resource being targeted from the request. This is the way it is in the competing JSONAPI standard.
From JSONAPI standard:
A logical collection of resources MUST be represented as an array, even if it only contains one item or is empty.
You don't need to have items field for showing single item. If you're sure your API is always going to return single object, you can return it as data itself.
{
"data": {
"kind": "user",
"fields": "author,id",
"id": "bart",
"author": "Bart"
}
}
Fields such as data.kind data.fields data.etag data.id data.lang data.updated data.deleted can still be used here.
Source for snippet docs

Access deeper elements of a JSON using postgresql 9.4

I want to be able to access deeper elements stored in a json in the field json, stored in a postgresql database. For example, I would like to be able to access the elements that traverse the path states->events->time from the json provided below. Here is the postgreSQL query I'm using:
SELECT
data#>> '{userId}' as user,
data#>> '{region}' as region,
data#>>'{priorTimeSpentInApp}' as priotTimeSpentInApp,
data#>>'{userAttributes, "Total Friends"}' as totalFriends
from game_json
WHERE game_name LIKE 'myNewGame'
LIMIT 1000
and here is an example record from the json field
{
"region": "oh",
"deviceModel": "inHouseDevice",
"states": [
{
"events": [
{
"time": 1430247045.176,
"name": "Session Start",
"value": 0,
"parameters": {
"Balance": "40"
},
"info": ""
},
{
"time": 1430247293.501,
"name": "Mission1",
"value": 1,
"parameters": {
"Result": "Win ",
"Replay": "no",
"Attempt Number": "1"
},
"info": ""
}
]
}
],
"priorTimeSpentInApp": 28989.41467999999,
"country": "CA",
"city": "vancouver",
"isDeveloper": true,
"time": 1430247044.414,
"duration": 411.53,
"timezone": "America/Cleveland",
"priorSessions": 47,
"experiments": [],
"systemVersion": "3.8.1",
"appVersion": "14312",
"userId": "ef617d7ad4c6982e2cb7f6902801eb8a",
"isSession": true,
"firstRun": 1429572011.15,
"priorEvents": 69,
"userAttributes": {
"Total Friends": "0",
"Device Type": "Tablet",
"Social Connection": "None",
"Item Slots Owned": "12",
"Total Levels Played": "0",
"Retention Cohort": "Day 0",
"Player Progression": "0",
"Characters Owned": "1"
},
"deviceId": "ef617d7ad4c6982e2cb7f6902801eb8a"
}
That SQL query works, except that it doesn't give me any return values for totalFriends (e.g. data#>>'{userAttributes, "Total Friends"}' as totalFriends). I assume that part of the problem is that events falls within a square bracket (I don't know what that indicates in the json format) as opposed to a curly brace, but I'm also unable to extract values from the userAttributes key.
I would appreciate it if anyone could help me.
I'm sorry if this question has been asked elsewhere. I'm so new to postgresql and even json that I'm having trouble coming up with the proper terminology to find the answers to this (and related) questions.
You should definitely familiarize yourself with the basics of json
and json functions and operators in Postgres.
In the second source pay attention to the operators -> and ->>.
General rule: use -> to get a json object, ->> to get a json value as text.
Using these operators you can rewrite your query in the way which returns correct value of 'Total Friends':
select
data->>'userId' as user,
data->>'region' as region,
data->>'priorTimeSpentInApp' as priotTimeSpentInApp,
data->'userAttributes'->>'Total Friends' as totalFriends
from game_json
where game_name like 'myNewGame';
Json objects in square brackets are elements of a json array.
Json arrays may have many elements.
The elements are accessed by an index.
Json arrays are indexed from 0 (the first element of an array has an index 0).
Example:
select
data->'states'->0->'events'->1->>'name'
from game_json
where game_name like 'myNewGame';
-- returns "Mission1"
select
data->'states'->0->'events'->1->>'name'
from game_json
where game_name like 'myNewGame';
This did help me