JSON String Parse

macnlkc

Member
Licensed User
Longtime User
I am trying to work with the following return string to parse it to fit the enclosed object. Is there an easy way to map an object to a JSON string so that the returned string can be easily mapped into the object?

Returned string...
{"results": [
{
"priceTags": "$",
"servingTags": [
"TimeofDay",
"TimeofDay"
],
"stateToken": "token-value-here",
"heroTags": [
"Food Item Type 1",
"Food Item Type 2",
"Food Item Type 3"
],
"primaryPhoneNumber", "tel: 555-555-1212"
"activeFoodMenu": [
{
"id": 1,
"menuItems": [
{
"id": 1,
"name": "Single Beef Taco",
"price": 9.99
},
{
"id": 2,
"name": "Single Beef Taco with double sour cream",
"price": 5.99
}
],
"description": "Fresh taco with good to eat stuff in it.",
"name": "Single Beef Taco",
"primaryImage": {
"type": null,
"downloadURL": "http:\\www.blahblahblah.com\picture.png",
"size": null
}
},
{
"id": 2,
"menuItems": [
{
"id": 3,
"name": "Single Beef Taco",
"price": 9.99
},
{
"id": 4,
"name": "Single Beef Taco with double sour cream",
"price": 5.99
}
],
"description": "Fresh taco with good to eat stuff in it.",
"name": "Single Beef Taco",
"primaryImage": {
"type": null,
"downloadURL": "http:\\www.blahblahblah.com\picture.png",
"size": null
}
},
"id": "1234",
"canFavorite": true,
"pickuplocation": {
"addresslineOne": "123 Somewhere street",
"addressLineTwo": "Anytown, State 12345",
"mapURL": "http://www.google.com/maps"
},
"description": "this is an awesome venue",
"isFavorite": null,
"name": "Taco Hell",
"primaryPhoneNumber": "555-555-5555",
"websiteURL": "http",
"acceptedPaymentTags": [
"CreditCard",
"Cash"
]
}
],
"SessionID": "ijlj-9876-fjjf-7120-qapo"
}

Object

ID
stateToken
name
description
isFavorite
canFavorite
heroTags

  • servingTages

    • acceptedPaymentTags

      • priceTag
        websiteURL
        pickupLocation [address object]
        activeFoodMenu

        • primaryImage
 

macnlkc

Member
Licensed User
Longtime User
I am not quite sure how to handle the sub to build the objects from the maps or lists.

Heck, I have also attempted numerous times to parse the entire thing and I get errors most of the time. The problem is that there are nested structures in here from the object and I can get the maps to create pretty routinely but seem to get tripped up on the arrays in the objects nested in the original JSON stream coming back. I think part of the problem is that the string comes back in alphabetical order as opposed to the order that the object is actually created. If one of them doesn't use the alphabetical then I am toast.

Is there a "parser" that will look to see whether it is an object or a list. If it is a list then parse the next block and do it iteratively until the list of objects is exhausted?

:BangHead:
 
Upvote 0

macnlkc

Member
Licensed User
Longtime User
Thanks for the offer. Here is what I have finally got to work in code.

I took one of the "easier" JSON structures and wrote a series of For loops to pick it apart. I guess I need a couple of things addressed here that I am too new to the process to figure out myself and any help would be appreciated.

1) Can I use a For Each loop for both the Lists and Maps?
2) Is there a way to map the structure to an object and have it populate the object?

Here is one of the simpler structures...
{"results":
[
{
"id":1,
"lineItems":
[
{
"name":"Cheeseburger with Cheese",
"price":10.00,
"quantity":5
},
{
"name":"Avacodo Mustard Tuna Fries",
"price":11.99,
"quantity":100
}
],
"orderNumber":"1234",
"placedDate":"10-21-2005 03:00",
"portalAddressLineOne":"123 Sesame Street",
"portalAddressLineTwo":"SomeCity, State 12345",
"portalName":"Bubba's",
"stateToken":null,
"total":250.99
}
],
"sessionId":"22cb749e-0caa-11e2-af41-1c6f65228be7"
}

And the code that I wrote to decompose it...
Dim m As Map
Dim sessionId As String
Dim MenuItems As List

sessionId = Map1.Get("sessionId")
Log (sessionId)

MenuItems.Initialize
MenuItems = Map1.Get("results")
Log(MenuItems)
m = MenuItems.Get(0)

For i = 0 To m.Size-1
Dim Key, Value As String
Key = m.GetKeyAt(i)
Value = m.GetValueAt(i)
Log(Key & ":" & Value)
If Key = "lineItems" Then
Dim lineItems As List
lineItems.Initialize
lineItems = m.Get("lineItems")
For j = 0 To lineItems.Size-1
Log(lineItems.Get(j))
Dim orderItems As Map
orderItems = lineItems.Get(j)
For k = 0 To orderItems.Size-1
Dim liKey, liValue As String
liKey = orderItems.GetKeyAt(k)
liValue = orderItems.GetValueAt(k)
Log(liKey & " : " & liValue)
Next
Next​
End If
Next



Surely there is a cleaner way than how I have accomplished it! It works but it is UGLY and will be difficult to reproduce with all the other models I need to decompose. I would love to put these into classes and use the classes to map to the JSON scripts and then place them into a local database.

Any help would be greatly appreciated.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Please use [ code ] [ /code ] tags (without spaces) when posting code.

You can create a class with the following Initialize method:
B4X:
Public Sub Initialize(m As Map)
 'Name and Price are global variables
 Name = m.Get("name") 
 Price = m.Get("price")
 ...
End Sub

You should initialize such an object for each "object map".
 
Upvote 0
Top