[SalesForce] Parse JSON into Lead

I'm trying to parse a JSON response and create Lead records from it.
The JSON is basically formatted as follows. Note, that this is not the complete data being parsed but is the general format of data. I had to exclude some data.

[
    {
        "first name":"one",
        "last name":"two",
        "gender":"Male",
        "location":"gf, vv, Alabama, vv",
        "Email":"Test1@gmail.com",
        "Zip Code":"88",
        "What describes you best (please select all that apply)":"Transportation\/Logistics",
        "What is the best contact number to reach you?":"88",
        "How long have you been in the industry?":"Just Starting",
        "company_pin":"502",
        "What Company do you work for?":"Santa Aurelia",
        "Secondary\/Personal Email":""
    },
    {
        "first name":"two",
        "last name":"bus",
        "gender":"Male",
        "location":"addeess, asdf, Alabama, sdd",
        "Email":"Test1@gmail.com",
        "Zip Code":"455",
        "What describes you best (please select all that apply)":"Other",
        "What is the best contact number to reach you?":"855",
        "How long have you been in the industry?":"Just Starting",
        "company_pin":"125",
        "What Company do you work for?":"A & A Produce Inc",
        "Secondary\/Personal Email":""
    },
    {
        "first name":"zeeshab",
        "last name":"ahmad",
        "gender":"Male",
        "location":"lahore, , Alabama, lahore",
        "Email":"Test1@gmail.com",
        "Zip Code":"54784",
        "What describes you best (please select all that apply)":"Retailer",
        "What is the best contact number to reach you?":"5555555555",
        "How long have you been in the industry?":"3-5 Years",
        "company_pin":"250",
        "What Company do you work for?":"Taylor Made Labels",
        "Secondary\/Personal Email":""
    }
]

My code so far is as follows.

global class ProdUnivParse implements database.AllowsCallouts {
//@future(callout=true)
global void parseJSONResponse() {        
    Http httpProtocol = new Http();
    // Create HTTP request to send.
    HttpRequest request = new HttpRequest();
    // Set the endpoint URL.
    String endpoint = 'http://URLRemoved';
    request.setEndPoint(endpoint);
    // Set the HTTP verb to GET.
    request.setMethod('GET');
    // Send the HTTP request and get the response.
    // The response is in JSON format.
    HttpResponse response = httpProtocol.send(request);
    //System.debug(response.getBody());


    // Parse JSON response to get all the totalPrice field values.
    // JSONParser parser = JSON.createParser(s));
    JSONParser parser = JSON.createParser(response.getBody());
    String firstName;
    String lastName;
    String gender;
    String location;
    String phone;
    String zip;
    String longIndustry;
    String description;
    String companyPin;
    String email;
    String companyName;
    String secEmail;
    List<Lead> lstLead;
    lstlead=new List<Lead>();

    while (parser.nextToken() != null) { 
     if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
       while (parser.nextToken() != null) {
           Lead leadobj = new Lead();
          if (parser.getCurrentToken() == JSONToken.START_OBJECT) {

    while (parser.nextToken() != null) {
        if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)) {
            // Get the value.
            String fieldName = parser.getText();
            parser.nextToken();

            if (fieldName == 'first name') {
                firstName = parser.getText();
                leadobj.FirstName = firstName;
            }
            else if (fieldName == 'last name') {
                lastName = parser.getText();
                if (lastName == Null){
                    lastName = 'EmptyFromParse';
                }
                leadobj.LastName = lastName;
            }
            else if (fieldName == 'gender') {
                gender = parser.getText();
            }
            else if (fieldName == 'location') {
                location = parser.getText();
            }
            else if (fieldName == 'What is the best contact number to reach you?') {
                phone = parser.getText();
                leadobj.Phone = phone;
            }
            else if (fieldName == 'Zip Code') {
                zip = parser.getText();
            }
            else if (fieldName == 'How long have you been in the industry?') {
                longIndustry = parser.getText();
            }
            else if (fieldName == 'What describes you best (please select all that apply)') {
                description = parser.getText();
            }
            else if (fieldName == 'company_pin') {
                companyPin = parser.getText();
                leadobj.Company = companyPin;
            }
            else if (fieldName == 'Email') {
                email = parser.getText();
                leadobj.Email = email;
            }
            else if (fieldName == 'What Company do you work for?') {
                companyName = parser.getText();
                if (companyName == Null){
                    companyName = 'EmptyFromParse';
                }
                //leadobj.Company = companyName;
            }


        }

        }
        //Add lead to list.
            lstlead.add(leadobj);
            System.debug('Lead Object: ' + leadobj);

        }

        }
        }
    }
    //Insert leads from list.
        if(lstlead!=null && lstlead.size()>0){
            System.debug('Lead List: ' + lstlead);
                insert lstlead;
        }

}   }

I can't seem to get the data written to the list correctly. In the code above, it seems to only add one item to the list as seen in the debug output below.

DEBUG|Lead List: (Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159})

If I move the lstlead.add(leadobj); code inside of the brackets just above where it is currently, it throws an error of "Before Insert or Upsert list must not have two identically equal elements." In the output, it seems to just keep adding the same item to the list over and over as displayed in the debug output below.

DEBUG|Lead List: (Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, Lead:{Phone=(555) 555 - 5555, Email=test1@gmail.com, FirstName=William, LastName=Test1, Company=159}, ...)

Any help would be appreciated. I feel like I'm close but just need a litle assistance.

Best Answer

Most of your variables are superfluous, and you could clean it up so it'd be easier to read.

The main problem is that you're never breaking out of your innermost loop, and so the same lead record keeps getting used over and over again. You need to test for the END_OBJECT, and when you get there, add the record to the list and then start over again. The innermost loop should read while(parser.nextToken() != JSONToken.END_OBJECT), and the one outside that should technically be while(parser.nextToken() != JSONToken.END_ARRAY). However, using a simple state machine, which I've included here, you can eliminate most of the complexity, along with a map that translates field names into values.

Here's a simple version of how I'd accomplish the same task:

Map<String, SobjectField> fieldMap = new Map<String, SObjectField> {
    'first name' => Lead.FirstName,
    'last name' => Lead.LastName,
    'email' => Lead.Email  // keep going!
};

Lead tempLead;
Lead[] leadList = new Lead[0];
String fieldName;

while(parser.nextToken() != null) {
    // Save field name, next round we'll get the value
    if(parser.getCurrentToken() == JsonToken.FIELD_NAME) {
        fieldName = parser.getText();
        continue;
    }
    // Special case-- if the field name isn't null, we know a value is here
    if(fieldName != null && fieldMap.containsKey(fieldName)) {
        tempLead.put(fieldMap.get(fieldName), parser.getText());
        fieldName = null;
        continue;
    }
    // We check for a new object later, because it's a rarer event.
    if(parser.getCurrentToken() == JsonToken.START_OBJECT) {
        tempLead = new Lead();
        continue;
    }
    // Once we know end of object, we can start a new record.
    if(parser.getCurrentToken() == JsonToken.END_OBJECT) {
        leadList.add(tempLead);
        tempLead = null;
        continue;
    }
}

This isn't the only right answer, but hopefully it'll get you where you want to go.

Related Topic