Android Question JSON parsing crash when map is not present

SCIS

Active Member
Licensed User
Longtime User
Hi,

I'm trying to parse a JSON from Facebook which contains information about different events, like parties or festivals. I started out with the code from the online JSON Parse Tool which helped a lot.
Most of the events have their information in the JSON like this (this is just a sample with the information changed for privacy reasons, the lay-out has stayed exactly the same):

B4X:
{
  "events": {
    "data": [
      {
        "name": "Birthday Party",
        "place": {
          "name": "A Friend's House",
          "location": {
            "city": "Antwerp",
            "country": "Belgium",
            "latitude": 51.2605159,
            "longitude": 4.217295,
            "street": "streetname of my house",
            "zip": "2000"
          },
          "id": "012345678901234"
        },
       "id": "012345678901234"",
        "rsvp_status": "unsure"
      },
      {
        "name": "Brother's Wedding",
        "place": {
          "name": "A park",
          "location": {
            "city": "Antwerp",
            "country": "Belgium",
            "latitude": 51.2605159,
            "longitude": 4.217295,
            "street": "streetname of the park",
            "zip": "2000"
          },
          "id": "012345678901234"
        },
       "id": "012345678901234"",
        "rsvp_status": "attending"
      }
     ],
    },
    "id": "012345678901234"
}

Here is part of the B4A code which puts the JSON's information into a list:

B4X:
Dim parser As JSONParser
parser.Initialize(File.ReadString(File.DirAssets, "file.json"))
Dim root As Map = parser.NextObject
Dim UserId As String = ""
If root.Get("id") <> Null Then UserId = root.Get("id")

Log("User Id: " & UserId)
Dim events As Map = root.Get("events")
Dim data As List = events.Get("data")
Dim i As Int = 0
For Each coldata As Map In data

Dim rsvp_status As String
If coldata.Get("rsvp_status") <> Null Then rsvp_status = coldata.Get("rsvp_status")
EventArray(i).EventStatus = rsvp_status
Log("Status: " & rsvp_status)

Dim name As String
If coldata.Get("name") <> Null Then name = coldata.Get("name")
EventArray(i).EventName = name
Log("Name: " & name)

Dim place As Map
If coldata.Get("place") <> Null Then place = coldata.Get("place")

Dim location As Map
If place.Get("location") <> Null Then location = place.Get("location")

Dim latitude As Double
If location.Get("latitude") <> Null Then latitude = location.Get("latitude")
EventArray(i).EventLocationlatitude = latitude
Log("Latitude: " & latitude)

Dim longitude As Double
If location.Get("longitude") <> Null Then longitude = location.Get("longitude")
EventArray(i).EventLocationLongitude = longitude
Log("Longitude: " & longitude)


i = i + 1
Next

This works fine. I used to do just
B4X:
latitude = location.Get("latitude")
Sometimes events don't have a longitude - latitude included so I've found the way to solve this is by doing:

B4X:
If location.Get("latitude") <> Null Then latitude = location.Get("latitude")

This solves the errors on most points where events don't have a specific location set but they do have a "location name" set by the organiser, it's just not an actual place recognised by Facebook so they don't include a place ID and no longitude, latitude or other information.

I've done this with all the elements of the JSON, so if for some reason an event wouldn't have a name it still should not give any problems.

Now, here comes the actual problem: There's some events that don't have any location at all, which looks like this in JSON:

B4X:
 {
        "name": "event",
        "id": "012345678901234",
        "rsvp_status": "unsure"
  },

My program can handle a value not being present, but if a complete map is not there it crashes (I hope I understand the whole JSON naming a bit, and if not I hope you'll get what I mean)
I've tried using the same way as above, with If () <> Null, but that doesn't fix it.
I also read somewhere else to use .GetDefault("location","") but same as above.

Is there a way to have B4A also check if the map is present before trying to navigate to it? I think that would fix the problem I have. I've searched around but if this has been said somewhere, I don't seem to know the right search terms to find that thread ;)

Thanks for taking the time to read my question, I hope to get answer from this great community soon!
 

SCIS

Active Member
Licensed User
Longtime User
So in this case the it's not a "map" but a "key", that would be why I couldn't find any answers. Thanks a lot Erel!
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

SCIS

Active Member
Licensed User
Longtime User
it is a key in the map.

Oh, ok. I find it complicated to remember what is what, this is the first time I use JSON, so thanks! It seems to work now, for anyone interested I'll put the part of the code that's fixed it here

B4X:
Dim place As Map
If coldata.ContainsKey("place") Then
    place = coldata.Get("place")
    Dim location As Map
    If place.ContainsKey("location") Then location = place.Get("location")
   
    If place.ContainsKey("id") Then EventArray(i).EventPlaceID = place.Get("id")
    Log("Place ID: " & EventArray(i).EventPlaceID)
   
    If place.ContainsKey("location") AND location.ContainsKey("latitude") Then EventArray(i).EventLocationlatitude = location.Get("latitude")
    Log("Latitude: " & EventArray(i).EventLocationlatitude)
   
    If place.ContainsKey("location") AND location.ContainsKey("longitude") Then EventArray(i).EventLocationLongitude = location.Get("longitude")
    Log("Longitude: " & EventArray(i).EventLocationLongitude)
End If


Thanks for the help!
 
Upvote 0
Top