Im trying to make a callout when an opportunity reaches a stage and from this callout update a field. I created this apex class which is called from a flow. But I keep getting You have uncommitted work pending. Please commit or rollback before calling out
I found these answers already 1 , 2 but those don't require to return a value from the calllout.
I suspect that is the prolbem.
Here someone says its possible to first to the call out and then do the DML transaction. That is exactly what I am doing. I understand invocable methods are bulkified. Is this a problem?
Is there a way to achieve this?
code:
global class CreateProject {
@InvocableMethod
public static void run(List<List<String>> inputvar){
String projectName = '';
String accountName = '';
for(List<String> vars: inputvar){
projectName = vars.get(0);
accountName = vars.get(1);
}
String clientId = '';
if(getAllClients().containsKey(accountName)){
clientId = getAllClients().get(accountName);
}else{
clientId = insertClient(accountName);
}
insertProject(projectName, clientId, accountName);
}
public static map<String,String> getAllClients(){
String key = '';
String workspaceId = '';
String baseEndPoint = '';
HttpRequest req = new HttpRequest();
String endPoint = baseEndPoint+'/workspaces/' + workspaceId+'/clients?page-size=500';
req.setEndpoint(endPoint);
req.setMethod('GET');
req.setHeader('X-Api-Key', key);
Http http = new Http();
HTTPResponse res = http.send(req);
Map<String, String> clients = new Map<String, String>();
JSONParser parser = JSON.createParser(res.getBody());
while (parser.nextToken() != null) {
String ID = '';
String name ='';
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'name')) {
parser.nextToken();
ID = parser.getText();
}
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'id')) {
parser.nextToken();
name = parser.getText();
}
clients.put(name,ID);
}
return clients;
}
public static String insertClient(String name){
// post method returning id
return insertId;
}
@future(callout=true)
public static void insertProject(String projectName , String clientId, String accountName){
// post mthod using id and retrieving anther id which needds to be inserted.
try{
Opportunity oppty = [select id from opportunity where name=:accountName];
oppty.API__C = insertId;
update oppty;
}catch(QueryException e){
}
}
}
getAllClients
twice; does this mean it'll do two callouts, or are you caching the result? If it does two callouts, are you sure that method doesn't also do DML (like kurunve said, to log or update tokens)