3
I have a requirement to populate the GeoCode whenever the Account records are inserted or updated. I have written after insert, after update trigger to fire a geolocation google API it works perfectly fine.

But, I encountered a problem whenever there is a bulk insertion of data as below:

1. Using data loader I try to insert 10 records out of which 8 are successful inserts and 2 failures. At this time trigger has to fire the future method and populate geocode for the 8 inserted records but the code inside the @future method is NOT EXECUTED.

Can anyone suggest a work around fix for this.

Trigger:

trigger SetGeolocation on Account (after insert, after update) {
if(!system.isFuture() && !system.isBatch())

{
    List<Id> calloutIds = new List<Id>();    
    for (Account a : trigger.new)
        {

            calloutIds.add(a.id);
        }
LocationCallouts.getLocation(calloutIds);
}

}

Future Method:

    public class LocationCallouts {

 @future (callout=true)  // future method needed to run callouts from Triggers
  static public void getLocation(List<id> accntIds){
    // gather account info
    List<Account> updateList = new List<Account>();
    for(Account t : [SELECT Street__c, City__c, County__c, Country__c, Postcode__c FROM Account WHERE id =: Id]){

    // create an address string
    String address = '';
    if (t.Street__c!= null)
        address += t.Street__c+', ';
    if (t.City__c!= null)
        address += t.City__c+', ';
    if (t.County__c!= null)
        address += t.County__c+', ';
    if (t.Postcode__c != null)
        address += t.Postcode__c +', ';
    if (t.Country__c!= null)
        address += t.Country__c;

    address = EncodingUtil.urlEncode(address, 'UTF-8');

    // build callout
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://maps.google.com/maps/api/geocode/json?address='+address+'&sensor=false');
    req.setMethod('GET');
    req.setTimeout(60000);

    try{
        // callout
        HttpResponse res = h.send(req);

        // parse coordinates from response
        JSONParser parser = JSON.createParser(res.getBody());
        double lat = null;
        double lon = null;
        while (parser.nextToken() != null) {
            if (parser.getText() == 'coordinates'){
                   parser.nextToken(); // object start
                       String txt = parser.getText();
                       parser.nextToken();
                       if (txt == 'lat')
                           lat = parser.getDoubleValue();
                       else if (txt == 'lng')
                           lon = parser.getDoubleValue();
            }
        }}


        // update coordinates if we get back
        if (lat!= null){
            t.Location__Latitude__s = lat;
            t.Location__Longitude__s = lon;
            updateList.add(t);;
        }

    } catch (Exception e) {
    }
    Database.saveresult[] updatedResults = database.update(updateList,false);
}
}
  • 4
    your callout is passing a list of Ids and your future method is looking for a single Id? – Jesse Milburn Aug 4 '16 at 12:17
  • 2
    Why are you using custom address fields ? Why not standard address field ? – Mohith Shrivastava Aug 4 '16 at 12:20
  • Sorry I have just updated the code. Please see the modified code. I have a requirement to use custom fields rather than standard. – konatham swathireddy Aug 4 '16 at 12:26
  • Try moving your dml out of the loop. Make it allOrNone = false. – Adrian Larson Aug 5 '16 at 20:04
  • Hi @AdrianLarson, I have modified the code to do DML out of For Loop. Please see edited code. but still it did not solve the issue Please suggest the details – konatham swathireddy Aug 12 '16 at 8:23
0

I have somewhat similar code that does the same thing. Below code works. I think your future actually runs but there is a problem with getting accounts back from database.

 List<Account> updateList = = [SELECT Street__c, City__c, County__c, Country__c, Postcode__c FROM Account WHERE Id IN :accntIds];
        for(Account t : updateList ){
 // create an address string
    String address = '';
    if (t.Street__c!= null)
        address += t.Street__c+', ';
    if (t.City__c!= null)
        address += t.City__c+', ';
    if (t.County__c!= null)
        address += t.County__c+', ';
    if (t.Postcode__c != null)
        address += t.Postcode__c +', ';
    if (t.Country__c!= null)
        address += t.Country__c;

    address = EncodingUtil.urlEncode(address, 'UTF-8');

    // build callout
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://maps.google.com/maps/api/geocode/json?address='+address+'&sensor=false');
    req.setMethod('GET');
    req.setTimeout(60000);

    try{
        // callout
        HttpResponse res = h.send(req);

        // parse coordinates from response
        JSONParser parser = JSON.createParser(res.getBody());
        double lat = null;
        double lon = null;
        while (parser.nextToken() != null) {
            if (parser.getText() == 'coordinates'){
                   parser.nextToken(); // object start
                       String txt = parser.getText();
                       parser.nextToken();
                       if (txt == 'lat')
                           lat = parser.getDoubleValue();
                       else if (txt == 'lng')
                           lon = parser.getDoubleValue();
            }
        }}


        // update coordinates if we get back
        if (lat!= null){
            t.Location__Latitude__s = lat;
            t.Location__Longitude__s = lon;
            updateList.add(t);;
        }

    } catch (Exception e) {
    }
    Database.saveresult[] updatedResults = database.update(updateList,false);
}
}

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.