function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Milan HrdlickaMilan Hrdlicka 

trigger generating an error using a web callout

Hi all,

I am trying to use this JSON parsing in a trigger.
The purpose of the trigger is to insert latitude and longtitude data to custom object "Branch__c" once data like address, city etc. are inserted so geolocation details are inserted automatically after the trigger is fired.
The point is to gather address details from Branch__c custom object and construct a String to be put in "endPointString" variable.
I am doing this by using a formula field where I want to concatenate all necessary details. 
In order to test whether the callout works in a trigger at all I chose to make an "in between steps trigger" just to test the functionality, therefore in all newly inserted rows would be put the same longtitude and latitude details as these the "endPointString" variable would have a fixed String value for the moment.
The thing is that when I use below trigger which uses above "parsing classes" and try to insert test data, I get a different error :)

Can you please help?
Appreciate your help,
Milan


The error: Line: 36, Column: 1
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updGPStest: execution of BeforeInsert caused by: System.CalloutException: Callout from triggers are currently not supported. Class.getGPS.getGPSdata: line 23, column 1 Trigger.updGPStest: line 11, column 1: []​

Data to insert:
-----------------------------
List<Branch__c> brList = new List<Branch__c> {
    new Branch__c(Account__c = '0010Y00000EhCbzQAF', City__c='Kladno', Name__c='Kladno_BULK_TEST1', Postal_Code__c='272 01', Street__c='Vrchlického', Street_No1__c='2409', Street_No2__c='9'),
    new Branch__c(Account__c = '0010Y00000EhCbzQAF', City__c='Kladno', Name__c='Kladno_BULK_TEST2', Postal_Code__c='272 01', Street__c='Vrchlického', Street_No1__c='2409', Street_No2__c='9'),
    new Branch__c(Account__c = '0010Y00000EhCbzQAF', City__c='Kladno', Name__c='Kladno_BULK_TEST3', Postal_Code__c='272 01', Street__c='Vrchlického', Street_No1__c='2409', Street_No2__c='9')
};
// Bulk insert all contacts with one DML call

insert brList;

My current trigger:
-------------------------------

 trigger updGPStest on Branch__c (before insert, before update) {
     
    List<Branch__c> addrString = new List<Branch__c>();
    getGPS gps = new getGPS();
    
    for(Branch__c br1 : Trigger.New) {
    

        addrString = [SELECT Concatenate_Address__c FROM Branch__c WHERE Id IN :Trigger.New];
        
        gps.getGPSdata();

        
        
        br1.Location_GPS__latitude__s = gps.getLat();
        br1.Location_GPS__longitude__s = gps.getLng();
        
        
         //gps.setEndPointStr('&addrString&');
        //gps.setEndPointStr('http://maps.googleapis.com/maps/api/geocode/json?address=Černokostelecká /, Říčany, 251 01');
        //br1.Test_Column__c = br1.Concatenate_Address__c;
        

    }
}


web callout classes used:

//class no.1
--------------------
public class getGPS {
    
    String endPointString = 'https://maps.googleapis.com/maps/api/geocode/json?address=Žerotínova 1664/57, Praha, 130 00&key=AIzaSyDpkHWwId9J1mMCqu9mirXPEwpM3XTs0GU';
    double lng;
    double lat;
    
    public double getLng() {
        return lng;
        }
    
    public double getLat() {
        return lat;
        }
    
  

      public void getGPSdata() {
          Http httpProtocol = new Http();
          HttpRequest request = new HttpRequest();
          String endpoint = endPointString;
          request.setEndPoint(endpoint);
          request.setMethod('GET');
          HttpResponse response = httpProtocol.send(request); 
          String jsonString = response.getBody();
          googleAddress addr = googleAddress.parse(jsonString);
          
googleAddress.Location loc = addr.firstLoc;
double lng = loc.lng;
double lat = loc.lat;
          
          this.lng=lng;
          this.lat=lat;

      }
    
                       
}

//class no.2
--------------------

public class googleAddress {

    public class Address_components {
        public String long_name;
        public String short_name;
        public List<String> types;
    }

    public class Geometry {
        public Location location;
        public String location_type;
        public Viewport viewport;
    }

    public List<Results> results;
    public String status;
    public Location firstLoc;

    public class Results {
        public List<Address_components> address_components;
        public String formatted_address;
        public Geometry geometry;
        public Boolean partial_match;
        public String place_id;
        public List<String> types;
    }

    public class Viewport {
        public Location northeast;
        public Location southwest;
    }

    public class Location {
        public Double lat;
        public Double lng;
    }

    
    public static googleAddress parse(String json) {
        
        googleAddress returnAddr;
        
        returnAddr = (googleAddress) System.JSON.deserialize(json, googleAddress.class);
        if (!returnAddr.results.isEmpty()){
            returnAddr.firstLoc = returnAddr.results[0].geometry.location;
        }
        return returnAddr; 
        
        
    }
}
 
Best Answer chosen by Milan Hrdlicka
Hemant_JainHemant_Jain
For calling static method you can use the below snippet:
 
getGPS.getGPSDate();

ClassName.MethodName.

If this resolves, kindly mark it as the best answer

All Answers

Hemant_JainHemant_Jain
Use @future(callout=true) for the methods which you are calling from the trigger.

So the callout class will have method like:
 
@future(callout=true)  
public void getGPSdata() {
 /*Your code here*/
}

 
Milan HrdlickaMilan Hrdlicka
Thanks for your advice.
The future annotation requires a static class getGPSdata() - dont know how to get "lat" and "lng" details from the code in case the class is static..
Any idea?

Thanks a lot. Milan.

public class getGPS {
    
    //String endPointString = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + EncodingUtil.urlEncode('Žerotínova 1664/57, Praha, 130 00','UTF-8') + '&key=AIzaSyDpkHWwId9J1mMCqu9mirXPEwpM3XTs0GU';
    double lng;
    double lat;
    
    public double getLng() {
        return lng;
        }
    
    public double getLat() {
        return lat;
        }
    
      @future(callout=true)
      public static void getGPSdata() {
          Http httpProtocol = new Http();
          HttpRequest request = new HttpRequest();
          
          
          String endPointString = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + EncodingUtil.urlEncode('Žerotínova 1664/57, Praha, 130 00','UTF-8');
          String endpoint = endPointString;
          request.setEndPoint(endpoint);
          request.setMethod('GET');
          HttpResponse response = httpProtocol.send(request); 
          String jsonString = response.getBody();
          googleAddress addr = googleAddress.parse(jsonString);
          
googleAddress.Location loc = addr.firstLoc;
double lng = loc.lng;
double lat = loc.lat;

System.debug('LONGITUDE IS: ' + lng);
System.debug('LATITUDE IS: ' + lat);
      
          
          //this.lng=lng;
          //this.lat=lat;

      }
    
                       
}
Hemant_JainHemant_Jain
For calling static method you can use the below snippet:
 
getGPS.getGPSDate();

ClassName.MethodName.

If this resolves, kindly mark it as the best answer
This was selected as the best answer
Milan HrdlickaMilan Hrdlicka
Thanks a lot.
Hemant_JainHemant_Jain
Cheers. Don't forget to mark it as the best answer :)