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
tarun jain 110tarun jain 110 

Future method cannot be called from a future

Hi,

I created a after insert and after update trigger. On after insert trigger i call the static methd with @ future(callout=true) and perform callout on completion or when we get success I update the same object. when on after update is fired I call same function then I go the error of " Future method cannot be called from a future " Error.

Basically, I want to call update trigger from after insert trigger and in both the cases callout function perform. Is this possible or not ?. If yes then please tell me how resolve this error.

Thanks
Varun SinghVarun Singh
Hi  Use  this  code

Step 1: Create Apex Class
First step is to create an apex class. After you login, click on Setup > Develop > Apex Classes > New. 
Step 2: Write future method
Write future method that calls external service.
 
public class AccountUpdater {

  //Future annotation to mark the method as async.
  @Future(callout=true)
  public static void updateAccount(String id, String name) {

    //construct an HTTP request
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://cheenath.com/tutorial/sfdc/sample1/data.txt');
    req.setMethod('GET');

    //send the request
    Http http = new Http();
    HttpResponse res = http.send(req);

    //check the response
    if (res.getStatusCode() == 200) {

      //update account
      Account acc = new Account(Id=id);
      acc.Description = res.getBody();
      update acc;
    } else {
      System.debug('Callout failed: ' + res);
    } 
  }
}

Step 3: Add external server to Remote Sites
Click Setup > Security Controls > Remote Site Settings > New Add external site name and endpoint URL
Site:cheenath endpoint url:http://cheenath.com/


Step 4: Create APEX trigger
Click Setup > Customize > Accounts > Triggers > New
And create the following trigger:
trigger descriptionUpdater on Account (after insert) {

  System.debug('Making future call to update account');
  for (Account acc : Trigger.New) {
    //Call future method to update account
    //with data from external server.
    //This is a async calls, it returns right away, after
    //enqueuing the request.

    AccountUpdater.updateAccount(acc.Id, acc.Name);
  }

}

 
tarun jain 110tarun jain 110
Hi,

Thanks for reply,

Yes I want to do same thing but in trigger I want to do like:

trigger descriptionUpdater on Account (after insert, after update) {
 System.debug('Making future call to update account');
 for (Account acc : Trigger.New) {
 //Call future method to update account //with data from external server.
//This is a async calls, it returns right away, after
 //enqueuing the request.
AccountUpdater.updateAccount(acc.Id, acc.Name);
}
 }

I have condition when if (res.getStatusCode() == 200) is false so Don't worry about infinite call from trigger. But i want to do same thing as mention above.
Amit Singh 1Amit Singh 1
Hi,

+1 to Varun. Guide me if I am wrong You want call same function from Trigger but in different Events Like Insert and Update. For update what you need to do is check of the previous value was different from the new one then call the function.

Sample like below:
trigger descriptionUpdater on Account (after insert, After Insert) {

  System.debug('Making future call to update account');
  If(Trigger.isAfter && Trigger.isInsert){
	for (Account acc : Trigger.New) {
		AccountUpdater.updateAccount(acc.Id, acc.Name);
	}
  }
  if(Trigger.isAfter && Trigger.isUpdate ){
	  for(Account acc : Trigger.New){
		  if(Trigger.oldMap.get(acc.id).YourField!=acc.YourField){
			 AccountUpdater.updateAccount(acc.Id, acc.Name);
		  }
	  }
  }

}
Hope this will help.

Thanks,