You need to sign in to do that
Don't have an account?
Using a Trigger to update the Lat and Lng of Account when Address is updated
So first off I noticed there are built in Lattitute and Longitude fields for Account objects. Do these already get updated when address is filled in? Executing in Query Editor does not seem to give me a value in the Developers Console.
Either way I started building a Geocoding class via google maps and I wanted it to automatically fire when the address of an Account is inserted or updated.
My Trigger was initially After Update, Insert but I got an error for read only values. I then tried Before Update, Insert which seemed anti intutive but I now get a null value for the ID I think.
My code is below but I essentially just want a way to fire a trigger to update a field in Accounts when the address field in Account is updated or created?
trigger AddLocation on Account (before insert, before update) {
for (Account updatedAccount : Trigger.new) {
// if( (Trigger.oldMap.get(updatedAccount.Id).BillingStreet !=
// Trigger.newMap.get(updatedAccount.Id).BillingStreet)||( Trigger.oldMap.get(updatedAccount.Id).BillingCity !=
// Trigger.newMap.get(updatedAccount.Id).BillingCity)||( Trigger.oldMap.get(updatedAccount.Id).BillingState !=
// Trigger.newMap.get(updatedAccount.Id).BillingState)||( Trigger.oldMap.get(updatedAccount.Id).BillingPostalCode !=
// Trigger.newMap.get(updatedAccount.Id).BillingPostalCode)){
Geocoding updater = new Geocoding(updatedAccount.Id);
updatedAccount.BillingLatitude = updater.getLat();
updatedAccount.BillingLongitude = updater.getLng();
//}
}
}
All Answers
Id will not be generated in before insert trigger. You may consider passing the entire instance of account. Like this,
Geocoding updater = new Geocoding(updatedAccount);
And modifying your code for Geocoding class accordingly.
--Akram
Would the ID for updatedAccount not still be null? As I need that to grab the address and generate the geocoding url.
public class Geocoding {
private static FINAL String GKEY = 'key';
private static SObject accountObj;
private static double lat;
private static double lng;
//Constructor, takes the account ID, calls URL Builder method, creates http connection
//and uses URL to get the Geocoding response
//Extracts the latitude and lngitude from response and sets to class variables
public Geocoding (SObject updatedAccount) {
accountObj = updatedAccount;
callOut();
}
@future
public static void callOut () {
Http gCall = new Http();
HttpRequest gReq = new HttpRequest();
gReq.setEndpoint(urlBuilder());
gReq.setMethod('GET');
HttpResponse gRes = gCall.send(gReq);
String response = gRes.getBody();
lat = double.valueOf(response.substringBetween('"location" : { "lat" : ', ','));
lng = double.valueOf(response.substringBetween('"lng : "', '},'));
accountObj.put('BillingLatitude', lat);
accountObj.put('BillingLongitude', lng);
}
//Takes accID of updating account and constructs the Google Geocoding URL
//from the address
public static String urlBuilder (){
//List<Account> accAddress = Database.query('SELECT BillingStreet, BillingCity, ' +
// 'BillingState, BillingPostalCode ' +
// 'FROM Account ');
String gAddress = '';
//for(Account addresses : accAddress) {
gAddress = String.valueOf(accountObj.get('BillingStreet'));
gAddress += '+';
gAddress += String.valueOf(accountObj.get('BillingCity'));
gAddress += '+';
gAddress += String.valueOf(accountObj.get('BillingState'));
gAddress += '+';
gAddress += String.valueOf(accountObj.get('BillingPostalCode'));
// }
String gUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address=' +
gAddress +
'&key=' +
GKEY;
System.debug(gAddress);
return gUrl;
}
public double getLat() {
return lat;
}
public double getLng() {
return lng;
}
}
I made some changes in your code. I don't have any gmap key. If you have one please incorporate it. Following code uses the free api and updates Lat and Lng values into the Account record. Seems like we have some limit on number of characters per post. I will split it into multiple message.
I think I finally have this working. Thanks so much for your help. For any future readers, I had issues with enabling the correct api in google, ha stupid one, and also allowing google maps as an endpoint in remote site settings under security controls for salesforce. Additionally I created a custom object for the Lat and Lng as the built in ones may be used by the system and I didn't have confidence in them not being altered.
I noticed you changed it to an after update Trigger, Akram. I initially tried that but found I couldn't make changes to other fields in the account being updated as they were locked. How was it you avoid that?
I also like how to manage the JSON reply and build the URL, much less awkward then mine.
Thanks again.
Ronan