Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dictionary Setup for multi-level json #134

Closed
rocketaero opened this issue Jul 9, 2015 · 12 comments
Closed

Dictionary Setup for multi-level json #134

rocketaero opened this issue Jul 9, 2015 · 12 comments

Comments

@rocketaero
Copy link

I need to build a dictionary for the body to pass the following to POSTJSON

{
  "fulfillment": {
    "tracking_number": "123456789",
    "notify_customer": true
  }
}

I am not sure how to do this. Any help would be awesome, thank you

FYI, this is my code, i have it working with a GET so I think my authentication is fine but can't seem to get this POST to work.

' Create a WebClient for executing requests
' and set a base url that all requests will be appended to
Dim OrdersClient As New WebClient
OrdersClient.BaseUrl = "https:/apikey:password@zhats.myshopify.com/admin/"

' Setup authenticator
Dim ShopifyAuth As New HttpBasicAuthenticator
ShopifyAuth.Setup _
    Username:="username", _
    Password:="password"
Set OrdersClient.Authenticator = ShopifyAuth

' Use GetJSON helper to execute simple request and work with response
Dim Url As String
Dim jsonBody As String
Dim Response As WebResponse

While Not recordset.EOF

    jsonBody = ""
    jsonBody = jsonBody & "{""tracking_Number"":"""
    jsonBody = jsonBody & recordset.Fields("trackingNumber")
    jsonBody = jsonBody & """,""notify_Customer"":true}"


    Dim Body As New Dictionary

    Body.Add "fulfillment", jsonBody

    Url = "orders.json/" & recordset.Fields("Purchase_Order_#") & "/fulfillments.json"

    Set Response = OrdersClient.PostJson(Url, Body)

(added syntax highlighting)

@timhall
Copy link
Member

timhall commented Jul 9, 2015

It looks like the problem is that jsonBody is a string so it will be wrapped in " when Body is converted to JSON. The best route is to add fulfillment as an additional Dictionary:

Dim Fulfillment As New Dictionary
Fulfillment.Add "tracking_number", recordset.Fields("trackingNumber")
Fulfillment.Add "notify_customer", True

Dim Body As New Dictionary
Body.Add "fulfillment", Fulfillment

VBA-JSON will handle the convert the nested Dictionaries to the expected JSON string.

@rocketaero
Copy link
Author

Fantastic, I will give this a try, thank you

@timhall timhall closed this as completed Jul 9, 2015
@rocketaero
Copy link
Author

Not sure how to do this in reverse to get the Returning JSON back to 2 different Dictionaries? I am trying but no luck, I can't Cstr the Dictionary so I am stuck.

Resource = "orders.json"
Set Response = OrdersClient.GetJson(Resource)

Dim newData As Dictionary
Dim newnewData As Dictionary


Set newData = ParseJson(CStr(Response.Content))
Set newnewData = ParseJson(newData)

Is there a way I can just reference the Response without needing to convert back to a dictionary? I tried that as well but no luck.

Debug.Print Response.Data("id")

@timhall
Copy link
Member

timhall commented Jul 10, 2015

I'm not quite sure what the response looks like, but, for example, to get the id of the first order in the example response below, you would use the following:

{
  "orders": [
    {"id": "123", ...}
  ]
}
Set Response = OrdersClient.GetJson(Resource)

' First id
Debug.Print Response.Data("orders")(1)("id") ' -> "123"

Dim FirstOrder As Dictionary
Set FirstOrder = Response.Data("orders")(1)

Debug.Print FirstOrder("id") ' -> "123"

@timhall
Copy link
Member

timhall commented Jul 10, 2015

Generally, you shouldn't need to directly use ConvertToJson or ParseJson since Body is automatically converted from Dictionary/Collection to JSON based on Request.Format = WebFormat.Json or Request.RequestFormat = WebFormat.Json and the response Content is automatically parsed to Dictionary/Collection based on Request.Format = WebFormat.Json or Request.ResponseFormat = WebFormat.Json. VBA-JSON can handle nested arrays/objects very well, so there is no need to make extra parse/convert calls after the root object/array has been converted.

Complex nesting example:

[
  {
    "a": [
      [1, "a", {"message": "Howdy!"}]
    ]
  }
]
Debug.Print Response.Data(1)("a")(1)(3)("message") ' -> Howdy!

@rocketaero
Copy link
Author

Yea I figured this out using the Collection object. The code is working very well for me, thank you so much!

@rocketaero
Copy link
Author

I am struggling with storing something like this in a dictionary object for posting. I need to have the same key more than once for the variants item. Any help you can provide would be awesome! Thank you

{
"product": {
"title": "Burton Custom Freestlye 151",
"body_html": "Good snowboard!</strong>",
"vendor": "Burton",
"product_type": "Snowboard",
"variants": [
{
"option1": "First",
"price": "10.00",
"sku": 123
},
{
"option1": "Second",
"price": "20.00",
"sku": "123"
}
]
}
}

@DamnDam
Copy link
Contributor

DamnDam commented Aug 18, 2015

Hi,

You should try something like this.

Dim Product As New Dictionary

Product.Add "title", "Burton Custom Freestlye 151"
'...

Dim Variants As New Collection
Dim aVariant As Dictionary
Set aVariant = New Dictionary
aVariant.Add "option1", "First"
'...
Variants.Add aVariant


Set aVariant = New Dictionary
aVariant.Add "option1", "Second"
'...
Variants.Add aVariant

Product.Add "variants", Variants

Dim Body As New Dictionary
Body.Add "product", Product

The trick is to remember to use Dictionnary for {} objects in JSON and Collection for [] ordered arrays.

@rocketaero
Copy link
Author

Fantastic, thank you so much for our help!

On Tue, Aug 18, 2015 at 4:05 PM Damien Thirion notifications@github.com
wrote:

Hi,

You should try something like this.

Dim Product As New Dictionary

Product.Add "title", "Burton Custom Freestlye 151"'...
Dim Variants As New CollectionDim aVariant As Dictionary
Set aVariant = New Dictionary
aVariant.Add "option1", "First"'...
Variants.Add aVariant

Set aVariant = New Dictionary
aVariant.Add "option1", "Second"'...
Variants.Add aVariant

Product.Add "variants", Variants
Dim Body As New Dictionary
Body.Add "product", Product

The trick is to remember to use Dictionnary for {} objects in JSON and
Collection for [] ordered arrays.


Reply to this email directly or view it on GitHub
#134 (comment).

@caffeinatedMike
Copy link

@DamnDam Thank you so much for the very helpful explanation, especially about which object to use for [ ] & { }

@Mantej-Singh
Copy link

@timhall , can you please explain me this?
Debug.Print Response.Data(1)("a")(1)(3)("message") ' -> Howdy!

@Mantej-Singh
Copy link

@timhall , no worries.
I understood it, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants