Closed Ma-Trim closed 6 years ago
I found this- https://github.com/VBA-tools/VBA-Web/issues/63 and looked at this example:
' Dim Items As New Collection ' Dim Item As Dictionary ' Dim Id As Long ' ' For Id = 1 To 2 ' Set Item = New Dictionary ' Item("iditem") = Id ' Item("amount") = 1 ' Items.Add Item ' Next Id ' ' Request.AddBodyParameter "id", 5633 ' Request.AddBodyParameter "items", Items
and came up with this try- (haven't ran it yet) :)
Dim Prices As New Collection
Dim Price As Dictionary
Set Price = New Dictionary
Price("amount") = dPrice
Price("currency") = m_sCurrency
Prices.Add Price
Request.AddBodyParameter "prices", Price
BUT- now I need to do this as well, and am really not sure what to do!
"shipping": { "rates": [ { "rate": { "amount":"10.00" "currency": "USD" }, "region_code": "US_CON" }, { "rate": { "amount":"20.00" "currency": "USD" }", //USD "region_code": "Non_US_CON" }, ] "local": true } }
If the desired output is at the bottom of your last message (fixing typos) that could be achieved via:
Public Sub BuildDeepDictionary()
Dim fullObj As Dictionary
Set fullObj = New Dictionary
Dim shippingObj As Dictionary
Set shippingObj = New Dictionary
Dim rates As Collection
Set rates = New Collection
Dim aRate As Dictionary
Dim anAmount As Dictionary
Set anAmount = New Dictionary
anAmount("amount") = "10.00"
anAmount("currency") = "USD"
Set aRate = New Dictionary
Set aRate("rate") = anAmount
aRate("region_code") = "US_CON"
rates.Add aRate
Set anAmount = New Dictionary
anAmount("amount") = "20.00"
anAmount("currency") = "USD"
Set aRate = New Dictionary
Set aRate("rate") = anAmount
aRate("region_code") = "Non_US_CON"
rates.Add aRate
Set shippingObj("rates") = rates
shippingObj("local") = True
Set fullObj("shipping") = shippingObj
Debug.Print ConvertToJson(fullObj)
End Sub
{"shipping":{"rates":[{"rate":{"amount":"10.00","currency":"USD"},"region_code":"US_CON"},{"rate":{"amount":"20.00","currency":"USD"},"region_code":"Non_US_CON"}],"local":true}}
Thank you! Does my attempt for the first one look about right? (for the Price, amount, currency?)
You are referring to:
Dim Prices As New Collection
Dim Price As Dictionary
Set Price = New Dictionary
Price("amount") = dPrice
Price("currency") = m_sCurrency
Prices.Add Price
Request.AddBodyParameter "prices", Price
So Price will be [ {"amount": 100, "currency": "xxx" } ]
and you're setting the prices parameter so you'll get
prices="something here"
in your request. But I have to admit, I don't use the Request bits of this library, just the JSON bits. So I'm not sure if you need
Request.AddBodyParameter "prices", Price
or
Request.AddBodyParameter "prices", ConvertToJson(Price)
to fill the form properly.
Usually these APIs either take forms or a JSON body as a whole, so you may have to do:
Dim r As New WebRequest
Set r.Body = fullObj
Where you pass in your whole dictionary (or collection) to the request.
(edit) If they expect the price as a string (e.g. "10.00") and not a number (e.g. 10.00) you may have to change the datatype of dPrice or CStr() it to get the value in a format they are expecting.
Here is the JSON in it's entirety, this is for a POST... maybe I am more lost than I thought... :)
curl -XPOST -H "Authorization: Bearer [oauth_token]" -H "Accept-Version: 3.0" -H "Content-Type: application/hal+json" https://api.reverb.com/api/listings --data '
{
"make": "Fender",
"model": "Stratocaster",
"categories": [{
"uuid": "get these values from /api/categories/flat"
}],
"condition": {
"uuid": "get these from /api/listing_conditions
},
"photos": [
"http://i.stack.imgur.com/Sv4BC.png",
"http://i.stack.imgur.com/foo.png"
],
"description": "Awesome guitar",
"finish": "Sunburst",
"price": {
"amount": "5000.00",
"currency": "USD
},
"title": "my favorite fender stratocaster",
"year": "1960s",
"sku": "12345",
"has_inventory": true,
"inventory": 5,
"handmade": true,
"location": { // will default to shop address if not passed in
"country_code": "USA",
"region": "IL",
"locality": "Chicago"
},
"exclusive_channel": "none" // for Reverb Sites customers only. Set to "seller_site", "reverb", or "none" or leave blank
"shipping_profile_id": 123, // instead of shipping rates
"shipping": { // only use this if not using shipping profiles
"rates": [
{
"rate": {
"amount":"10.00"
"currency": "USD"
},
"region_code": "US_CON" // Continental US
},
{
"rate": {
"amount":"20.00"
"currency": "USD"
}", //USD
"region_code": "XX" // Everywhere Else
},
]
"local": true
}
}
'
This is the code I have so far-
Dim Client As New WebClient
Client.BaseUrl = "https://api.reverb.com/api/"
Dim Request As New WebRequest
Request.Resource = "listings"
Request.Method = WebMethod.Httppost
Request.Format = WebFormat.Json
Request.AddHeader "Authorization", m_sToken
Request.AddHeader "Content-Type", "application/hal+json"
Request.AddHeader "Accept", "application/hal+json"
Request.AddHeader "Accept-Version", "3.0"
Request.AddBodyParameter "make", sMake
Request.AddBodyParameter "model", sModel
Request.AddBodyParameter "categories", sCategory
Request.AddBodyParameter "condition", sCondition
Request.AddBodyParameter "description", sDescription
Request.AddBodyParameter "finish", vFinish
Dim Prices As New Collection
Dim Price As Dictionary
Set Price = New Dictionary
Price("amount") = dPrice
Price("currency") = m_sCurrency
Prices.Add Price
Request.AddBodyParameter "prices", Price
Request.AddBodyParameter "title", sTitle
Request.AddBodyParameter "year", vYear
Request.AddBodyParameter "sku", sSKU
Request.AddBodyParameter "has_inventory", sHasInventory
Request.AddBodyParameter "inventory", dInventoryQTY
Request.AddBodyParameter "handmade", sHandMade```
When you are looking at JSON, is there a way to know when it's a dictionary and when it's a collection? Is there a good tutorial online you can point us too? I want to learn how to understand what I am trying to do, this is all new to me. VBA I am pretty good at, but the API thing is brand new. Thanks again for your excellent help!
When you see { }
it is a dictionary. When you see [ ]
it is a collection. Everything else is a value.
[ { "foo": "bar", "abc": [1,2,3], "xyzzy":[ "one", "two", "three" ] "test": null }, { "foo": "bar", "abc": [1,2,3], "xyzzy":[ "one", "two", "three" ] "test": null } ]
Is a Collection of Dictionary that contains properties as well as Collections of numbers and strings
Given the cURL example, it looks to me like you want to create a single Dictionary of all your values, and then POST that as the body instead of using parameters. Your code will do
make=The Make&model=The Model&etc....
which is how you POST a FORM and that's not what they want.
You want to set your Request.Body to be the JSON object you'll constructing and pass that as a whole thing.
ohhhhhh well that makes more sense now haha. I will try to do that.
Okay- here is my new and improved code, but it's not debugging... I am not sure what I am doing wrong. I get "argument not optional" on this line "Listing.Add Condition".
` Dim Client As New WebClient Client.BaseUrl = "https://api.reverb.com/api/" Dim Request As New WebRequest Request.Resource = "listings" Request.Method = WebMethod.Httppost Request.Format = WebFormat.Json Request.AddHeader "Authorization", m_sToken Request.AddHeader "Content-Type", "application/hal+json" Request.AddHeader "Accept", "application/hal+json" Request.AddHeader "Accept-Version", "3.0" Dim Listing As New Dictionary Set Listing = New Dictionary
Listing("make") = sMake
Listing("model") = sModel
Listing("publish") = False
Dim Categories As New Collection
Set Categories = New Collection
Dim Category As Dictionary
Set Category = New Dictionary
Category("uuid") = sCategory
Categories.Add Category
Listing("sold_as_is") = sSoldAsIs
'photos- skip and use web UI to upload
Dim Condition As Dictionary
Set Condition = New Dictionary
Condition("uuid") = sCondition
Listing.Add Condition
Listing("hasinventory") = sHasInventory
Listing("inventory") = dInventoryQTY
Listing("description") = sDescription
Listing("finish") = vFinish
Listing("title") = stitie
Listing("year") = vYear
Listing("sku") = sSKU
Listing("upc") = vUPC
Listing("upc_does_not_apply") = sUPCDoesNotApply
Listing("offers_enabled") = sOffersEnabled
Listing("shipping_profile_id") = vShippingProfileID
Listing("shipping_frofile_name") = vShippingProfileName
'location - skip and default to store address
Listing("origin_country_code") = vOriginCountry
Dim shippingObj As Dictionary
Set shippingObj = New Dictionary
shippingObj("local") = True
Dim rates As Collection
Set rates = New Collection
Dim aRate As Dictionary
Dim anAmount As Dictionary
Set anAmount = New Dictionary
anAmount("amount") = dShippingRateAmountUS
anAmount("currency") = sShippingRateCurrencyUS
Set aRate = New Dictionary
Set aRate("rate") = anAmount
aRate("region_code") = sShippingRateRegionUS
rates.Add aRate
Set anAmount = New Dictionary
anAmount("amount") = dShippingRateAmountNotUS
anAmount("currency") = sShippingRateCurrencyNotUS
Set aRate = New Dictionary
Set aRate("rate") = anAmount
aRate("region_code") = sShippingRateRegionNotUS
rates.Add aRate
Set shippingObj("rates") = rates
Listing.Add("shipping") = shippingObj
Dim Seller As Dictionary
Set Seller = New Dictionary
Seller("paypal_email") = m_sPayPalEmail
Listing.Add Seller
'sellercost - skipping
Listing("tax_exempt") = m_sTaxExempt
Dim Price As Dictionary
Set Price = New Dictionary
Price("amount") = dPrice
Price("currency") = m_sCurrency
Listing.Add Price
'video - skip, use web UI for uploading
Listing("exclusive_channel") = sSellerSite
Debug.Print ConvertToJson(Listing)`
I am working with this JSON:
`{
"make":"string",
"model":"string",
"publish":true,
"categories":[
{
"uuid":"string"
}
],
"sold_as_is":true,
"photos":[
"string"
],
"condition":{
"uuid":"string"
},
"has_inventory":true,
"inventory":0,
"storage_location":"string",
"description":"string",
"finish":"string",
"title":"string",
"year":"string",
"sku":"string",
"upc":"string",
"upc_does_not_apply":"string",
"offers_enabled":true,
"shipping_profile_id":"string",
"shipping_profile_name":"string",
"location":{
"locality":"string",
"region":"string",
"country_code":"string"
},
"origin_country_code":"string",
"shipping":{
"local":true,
"rates":[
{
"region_code":"string",
"rate":{
"amount":"string",
"currency":"string"
}
}
]
},
"seller":{
"paypal_email":"string"
},
"seller_cost":"string",
"tax_exempt":true,
"price":{
"amount":"string",
"currency":"string"
},
"videos":[
{
"link":"string"
}
],
"exclusive_channel":"seller_site"
}`
Set Listing("condition") = Condition
You only Add to collections. You need the Key for a Dictionary.
oh- ok
Well- I debugged to here! Yay! I have installed VBA-JSON, is there something else I need to do to get this working? @zgrose , Thanks for your help!!
You have more than one Function/Sub called ConvertToJson. Do a Find in your modules and it should be apparent what the issue is.
well, actually I don't and that was the confusing part.
The compiler don't lie. :) Maybe you imported the module twice or something? Or you have an object named ConvertToJson. It's gotta be something.
well, this is the only other one :) in "web helpers" Do i need to set some kind of library or something? Should I reinstall the modules?
I don't have your source code so I really can't say other than the compiler is rarely wrong about something.
Well, I installed the VBA-Web tool, and I don't have any object or another sub named "ConvertToJson"
I do agree the compiler is rarely wrong :/ It compiles if i comment the debug.print line :)
Again, I can't do anything with screenshots. You can try googling why the compiler would give you this message.
Hi @Ma-Trim if you're not able to find the duplicate variable, function, sub, etc. you can namespace the call with:
Debug.Print JsonConverter.ConvertToJson(Listing)
It looks like you're doing a great job with nested arrays/values, so I'm going to close this.
@zgrose Thanks for working through it with them!
Hello- this made it happy, but I will change it to your suggestion - Debug.Print WebHelpers.ConvertToJson(Listing)
THANK YOU @zgrose and @timhall I would be lost without you! :)
Hello, I am getting the error "argument not optional" on this line:
Pretty sure you always need to Set
when you're putting or getting an object in VB(A).
Set Dictionary(key) = ObjectVariable
Set ObjectVariable = Dictionary(key)
Ok, I got it :)
Ok- getting closer! For some reason, my JSON is missing the "category" part.
My code-
The sample I am trying to reproduce-
I see you adding the uuid to a category dictionary. I see you adding that dictionary to the categories collection. Do you have Set Listing("categories") = Categories
anywhere?
no! That fixed it... Thanks!!!
Okay- update, I have been trying lots of variations and going in circles, I am really not sure how to get this in the proper order. I have been following the general concept of "{" = dictionary and "[" = collection, but clearly I don't yet understand what to do!
My Json produces this - (just focusing on the shipping object here)
And I am trying to do this: (with the exception that I need one for US and one for Non US)
current code- ` Dim ShippingObj As Dictionary Set ShippingObj = New Dictionary
ShippingObj("local") = True
Dim rates As Collection
Set rates = New Collection
Dim RatesDetail As Dictionary
Set RatesDetail = New Dictionary
RatesDetail("region_code") = vShippingRateRegionUS
Set RatesDetail("region_code") = rates
rates.Add RatesDetail
Dim aRate As Dictionary
Set aRate = New Dictionary
aRate("amount") = dShippingRateAmountUS
aRate("currency") = sShippingRateCurrencyUS
Set ShippingObj("rate") = aRate
rates.Add aRate
Set Listing("shipping") = ShippingObj
`
Thank you for your help! @zgrose, I am still not able to quite understand how to get the proper JSON structure. See above current code and samples :)
Your above code should read:
Dim Listing As New Dictionary
Dim Shipping As New Dictionary
Dim Rates As New Collection
Dim RateDetails As New Dictionary
Dim Rate As New Dictionary
Rate("amount") = "..."
Rate("currency") = "..."
' Rate: { amount: "...", current: "..." }
RateDetails("region_code") = "..."
Set RateDetails("rate") = Rate
' RateDetails: { region_code: "...", rate: { amount: "...", current: "..." } }
Rates.Add RateDetails
' Rates: [{ region_code: "...", rate: ... }]
Shipping("local") = True
Set Shipping("rates") = Rates
' Shipping: { local: true, rates: [{ region_code: "...", rate: ... }] }
Set Listing("shipping") = Shipping
' Listing: { shipping: { local: true, rates: ... } }
Please address any further general usage questions to Stack Overflow or Code Review as there should be more people that can help there and this isn't really specific to VBA-Web.
Thank you very much!
Sent from my iPhone Charleen Trimmer Trimmer agency 541-840-6846
On Apr 10, 2018, at 10:56 AM, Tim Hall notifications@github.com wrote:
Your above code should read:
Dim Listing As New Dictionary Dim Shipping As New Dictionary Dim Rates As New Collection Dim RateDetails As New Dictionary Dim Rate As New Dictionary
Rate("amount") = "..." Rate("currency") = "..."
' Rate: { amount: "...", current: "..." }
RateDetails("region_code") = "..." Set RateDetails("rate") = Rate
' RateDetails: { region_code: "...", rate: { amount: "...", current: "..." } }
Rates.Add RateDetails
' Rates: [{ region_code: "...", rate: ... }]
Shipping("local") = True Set Shipping("rates") = Rates
' Shipping: { local: true, rates: [{ region_code: "...", rate: ... }] }
Set Listing("shipping") = Shipping
' Listing: { shipping: { local: true, rates: ... } } Please address any further general usage questions to Stack Overflow or Code Review as there should be more people that can help there and this isn't really specific to VBA-Web.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Hello, how would I do the following-
This is the code I have started-