I have a process builder executing the following Apex class when the criteria is met. Everything runs nicely until the last line, where the API method is called and a map is passed.
public class Cls_Location {
@InvocableMethod(label='Get Device Id')
public static void getCoordinates(List<Id> dList) {
List<Id> ids = new List<Id>();
for(Id i : dList) {
ids.add(i);
system.debug(i);
}
//sensor coordinates map and respective list
Map<Id, List<Double>> sCoord = new Map<Id, List<Double>>();
List<Double> sCoordList = new List<Double>();
//device coordinates map and respective list
Map<Id, List<Double>> dCoord = new Map<Id, List<Double>>();
List<Double> dCoordList = new List<Double>();
for(Device__c qDevice : [SELECT Id, Name,
Geo_Ip_Location__c, Geo_Ip_Location__Latitude__s, Geo_Ip_Location__Longitude__s
FROM Device__c
WHERE Id IN :ids]) {
system.debug('Query: ' + qDevice);
Double dLat = qDevice.Geo_Ip_Location__Latitude__s;
Double dLgtd = qDevice.Geo_Ip_Location__Longitude__s;
system.debug('dLat: ' + dLat);
system.debug('dLgtd: ' + dLgtd);
dCoordList.add(dLat);
dCoordList.add(dLgtd);
dCoord.put(qDevice.Id, dCoordList);
system.debug('dCoord: ' + dCoord);
}
if (dCoord.size() > 0) {
for (Id c : dCoord.keySet()) {
system.debug('Device Lat: ' + dCoord.get(c)[0]);
system.debug('Device Longtd: '+ dCoord.get(c)[1]);
}
Cls_GoogleMapsCalloutService.runCallout(dCoord);
}
}
}
Here's a snippet of the API callout class and method:
public class Cls_GoogleMapsCalloutService {
public static HttpResponse runCallout(Map<Id, List<Double>> m1) {
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint(MAPS_URL);
request.setMethod('GET');
HttpResponse response = http.send(request);
if (response.getStatusCode() == 200) {
//JSON PARSING is done here
Is there any way around this?
Grateful for your time.
Best Answer
So the error you would get in your debug logs is Uncommited Work Pending:.
There is a limitation in SF, if you do a dml, you cannot do a callout in same transaction. This is just the way SF works.
So if your process builder is running, that means you already did a DML. Now from Process Builder you calling an Invocable method, which does callout.
Thus it will fail. Is there a workaround for this?
ofc. You have to use future method.
Calling from your invocable method like
As future method can only accept primitive datatype, I have to convert your Map of
(Map<Id, List<Double>>)
to JSON string and then deserialize and use it.Edit : If you want to use queuable Apex then Main class will be
And then you would call your queuable like :
Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm
Source: http://cloudyworlds.blogspot.com/2015/03/invoking-apex-callout-from-process.html