3

I am trying to parse a JSON response from google. All the fields are populating with the exception of 'lat' and 'lng'. Not sure what I need to do to get the coordinates. Any help is much appreciated.


JSON

"results" : [
      {
         "geometry" : {
            "location" : {
               "lat" : 41.156457,
               "lng" : -64.730457
            }
         },
         "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/shopping.png",
         "id" : "7c0ddc371afea935f81863ddfd9ebc1e813121b2",
         "name" : "Establishment",
         "opening_hours" : {
            "open_now" : false
         },
         "place_id" : "ChIJ_bErEeHjt4kRlErHPKNZjAA",
         "price_level" : 2,
         "rating" : 4.1,
         "reference" : "CoQBdAAAAF6"
         "scope" : "GOOGLE",
         "types" : [ "store", "establishment" ],
         "vicinity" : "7077 Main St, Chicago"
      }

Parse the response:

JSONparser parser = JSON.createparser(Results);
        while (parser.nextToken() != null) {
            if (parser.getCurrentToken() == JSONToken.START_ARRAY){
                while(parser.nextToken() != null){
                    if(parser.getCurrentToken() == JSONToken.START_OBJECT){
                        storages sto = (storages)parser.readvalueas(storages.class);
                        storagelist.add(sto);
                        system.debug('*****Serialized storage: ' + storagelist);
                    }
                }
            }
        }

Inner classes used to parse:

public class storages {
        public string id {get;set;}
        public string lat {get;set;}
        public string lng {get;set;}
        public string name {get;set;}
        public string vicinity {get;set;}
        public string place_id {get;set;}

        public storages(string recordid, string lt, string lg, string nm, string address, string place){
            id = recordid;
            lat = lt;
            lng = lg;
            name = nm;
            vicinity = address;
            place_id = place;
        }
    }
  • Are you sure that lat and lng are reachables this way ? Because they're not at the same level than the other fields. – SF_user Aug 8 '14 at 13:59
  • The documentation says that you can set these fields by appending "__latitude__s" or "__longitude__s" to the field name: Double theLatitude = myObject__c.aLocation__latitude__s; myObject__c.aLocation__longitude__s = theLongitude; Are you setting them this way? – SineadCoyle Aug 8 '14 at 14:15
  • 2
    You should consider moving to using JSON.deserialize and just writing small Apex classes to hold the data. That way the result of your parse is a graph of simple Apex objects with the correct 1:1 or 1:many relationships. – Keith C Aug 8 '14 at 14:22
  • Added JSON.deserialize approach as an answer. – Keith C Aug 8 '14 at 19:11
3

You need to represent each inner object of the JSON, with an actual object, in your case it should be look something like this: debug output:

Serialized storage: (storage:[geometry=myGeometry:[location=myLocation:[lat=41.156457, lng=-64.730457]], id=7c0ddc371afea935f81863ddfd9ebc1e813121b2, name=Establishment, place_id=ChIJ_bErEeHjt4kRlErHPKNZjAA, vicinity=7077 Main St, Chicago])

public class myLocation
{
    public Double lat {get;set;}
    public Double lng {get;set;}
    public myLocation(Double lat, Double lng)
    {
        this.lat = lat;
        this.lng = lng;
    }
}

public class myGeometry
{
    public myLocation location {get;set;}
    public myGeometry(myLocation location)
    {
        this.location = location;
    }
}

public class storage 
{
    public myGeometry geometry {get;set;}
    public String id {get;set;}
    public String name {get;set;}
    public String vicinity {get;set;}
    public String place_id {get;set;}

    public storage(myGeometry geometry, String id, 
                    String name, String vicinity, String place_id)
    {
        this.geometry = geometry;
        this.id = id;
        this.name = name;
        this.vicinity = vicinity;
        this.place_id = place_id;
    }
}

List<storage> storagelist = new List<storage>();
JSONparser parser = JSON.createparser(Results);
while (parser.nextToken() != null) 
{
    if (parser.getCurrentToken() == JSONToken.START_ARRAY)
    {
        while(parser.nextToken() != null)
        {
            if(parser.getCurrentToken() == JSONToken.START_OBJECT)
            {
                storage sto = (storage)parser.readValueAs(storage.class);
                storagelist.add(sto);
                System.debug('*****Serialized storage: ' + storagelist);
            }
        }
    }
}
  • All, thanks for your posts. I ended up using @GoldenAxe post to parse the JSON and get the lat and lng. I received an error "malformed json: expected '[' at the beginning of list/set" when using JSON.deserialize. Thanks again!! – Berg Aug 11 '14 at 13:15
4

You can directly invoke JSON.deserialize and leave it up to the platform to do all the parsing work. This generally involves the least code and leaves you with easy to use Apex classes representing all the parts of the JSON you are interested in. Those classes can also be used to create JSON via JSON.serialize or JSON.serialializePretty. See the JSON class.

Here is that approach as a test: you can move the inner classes out into whatever classes you are actually doing this in:

@isTest
private class DeserializeTest {
    // Field names and types must match JSON; class names can be arbitrary
    public class Location {
        public Decimal lat;
        public Decimal lng;
    }
    public class Geometry {
        public Location location;
    }
    public class Storage {
        public Geometry geometry;
        public String id;
        public String name;
        public String vicinity;
        public String place_id;
    }
    @isTest
    static void test() {

        String s = '[{"geometry" : {"location" : {"lat" : 41.156457,"lng" : -64.730457}},"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/shopping.png","id" : "7c0ddc371afea935f81863ddfd9ebc1e813121b2","name" : "Establishment", "opening_hours" : {"open_now" : false},"place_id" : "ChIJ_bErEeHjt4kRlErHPKNZjAA", "price_level" : 2, "rating" : 4.1, "reference" : "CoQBdAAAAF6", "scope" : "GOOGLE", "types" : [ "store", "establishment" ], "vicinity" : "7077 Main St, Chicago"}]';

        Storage[] actuals = (Storage[]) JSON.deserialize(s, Storage[].class);

        System.assertEquals(1, actuals.size());
        Storage actual = actuals[0];
        System.assertEquals(41.156457, actual.geometry.location.lat);
        System.assertEquals(-64.730457, actual.geometry.location.lng);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.