1

I have a future method called out from a trigger which passes the ifcondition to be evaluated to this method and if this evaluates to true I need to call some classes. The problem here is even if the ifcondition should be evaluated as true, it always ends up in else part i.e false.I am not sure where I am going wrong. Need urgent help on this.

 global  class TriggerClass
{

  public class IntentionalException extends Exception{}
  @future (callout=true)
  Public static void ifMethod(String postal,Decimal period,Decimal principal,String lname,Decimal sal,String panNo,String LoanType,Decimal Loan,Decimal cibilscore,String operations,String sessionId,String ifcondition)
 {
ToolingAPI.SforceService x = new ToolingAPI.SforceService();
x.SessionHeader = new ToolingAPI.SessionHeader_element();
x.SessionHeader.sessionId = UserInfo.getSessionId();
x.SessionHeader.sessionId = sessionId;
System.debug('inside myMethod...'); 

boolean result=false;

 try{
 //ToolingAPI.ExecuteAnonymousResult b = x.executeAnonymous(forLoopCode);
 ToolingAPI.ExecuteAnonymousResult b = x.executeAnonymous(ifcondition);
 //ToolingAPI.ExecuteAnonymousResult toolingResult =     x.executeAnonymousUnencoded(ifcondition);
 }
 catch(IntentionalException ie) {
        result = (ie.getMessage() == 'true') ? True : False;
    }

//System.debug( 'result---' + b);
System.debug('exiting myMethod...'); 
 System.debug('result is---------------------------------------'+result);
 if(result==true)
 {
  System.debug('-----------In if loop');
   //execute opearations belonging to the criteria Id
  }
  else{
   System.debug('-------------In else loop'); 
  //reject loan

}
 }
}

This is my trigger which is calling the above code:

        trigger appTrigger on Applicant__c (after insert,after update) {

       public CustBusinessPro__Criteria__c Criteria {get;set;}
  system.debug('---------- hello');
  public List < CustBusinessPro__Criteria__c > criteriaList {get;set;}

  ToolingAPI.SforceService x = new ToolingAPI.SforceService();
  x.SessionHeader = new ToolingAPI.SessionHeader_element();
   x.SessionHeader.sessionId = UserInfo.getSessionId();
  String sessionId = UserInfo.getSessionId();
 String test;
 criteriaList=new LIST<CustBusinessPro__Criteria__c>([SELECT Id,Name,CustBusinessPro__Operations__c,CustBusinessPro__Where_Clause__c FROM CustBusinessPro__Criteria__c] );
 for (CustBusinessPro__Criteria__c cd: criteriaList) {

     for(CustBusinessPro__Applicant__c app:Trigger.new)
 {

 // System.debug('>>>>>>>>>>>>>>>>>'+        cd.CustBusinessPro__Where_Clause__c);
  test=cd.CustBusinessPro__Where_Clause__c;
  test=test.replaceAll('AND','&&');
  test=test.replaceAll('OR','||');

   test=test.replaceAll('CustBusinessPro__Age__c',String.valueOf(app.CustBusinessPro__Age__c));
    test=test.replaceAll('CustBusinessPro__Gender__c ','\'' + app.CustBusinessPro__Gender__c  + '\'');
     test=test.replaceAll('CustBusinessPro__Country__c','\'' + app.CustBusinessPro__Country__c + '\'');
      test=test.replaceAll('CustBusinessPro__City__c','\'' + app.CustBusinessPro__City__c + '\'');
       test=test.replaceAll('CustBusinessPro__Salary__c','\'' + String.valueOf(app.CustBusinessPro__Salary__c) + '\'');
        test=test.replaceAll('CustBusinessPro__Marital_Status__c','\'' + app.CustBusinessPro__Marital_Status__c + '\'');

              System.debug('>>>>>>>>>>>>>>>>>'+ test);


      String ifcondition='if('+test+')';
      System.debug('---------------ifcondition'+ifcondition);






  TriggerClass.ifMethod(app.CustBusinessPro__Postal_Code__c,app.CustBusinessPro__Loan_Tenure__c,app.CustBusinessPro__Loan_Amount__c,app.CustBusinessPro__Last_Name__c,app.CustBusinessPro__Salary__c,app.CustBusinessPro__PAN__c,app.CustBusinessPro__Type_of_Loan__c,app.CustBusinessPro__Loan_Amount__c,app.CustBusinessPro__CIBIL_Score__c,cd.CustBusinessPro__Operations__c,sessionId,ifcondition);

  }

 }


  }
  • Have you considered writing a test class to use for this? You'll then be able to control and repeat the same test conditions to debug your code. – crmprogdev Apr 01 '16 at 12:59
  • I am a little bit new to this and I am afriad I dont understand what do you exactly mean. I just need your help in letting me know whether I am going on right track – Jyoti Zanwar Apr 01 '16 at 13:21
  • If you're new, then I suggest you visit Trailhead and go through the Test Class module. Before you can deploy a class to production it will need a test class. Test classes are also an excellent way to debug your code. It's called Test Driven Development. – crmprogdev Apr 01 '16 at 13:41

1 Answers1

0

I suggest you should only resort to this sort of code if you have a compelling reason: the API is not designed for this purpose and it is awkward to get the code right. See Deniel Ballinger's Adding Eval() support to Apex blog post for a discussion of the benefits and disadvantages.

I assume you are trying to use this pattern to obtain the return value:

public class Dynamic {
    public class IntentionalException extends Exception{}

    public static boolean eval(String toEval){
        boolean result = false;
        if(!toEval.startsWith('if')) {
            toEval = 'if(' + toEval + ') {throw new Dynamic.IntentionalException(\'true\');} else {throw new Dynamic.IntentionalException(\'false\');}';
        }
        ToolingAPI x = new ToolingAPI();
        try{
            ToolingAPI.ExecuteAnonymousResult toolingResult = x.executeAnonymousUnencoded(toEval);
        } catch (IntentionalException ie) {
            result = (ie.getMessage() == 'true') ? True : False;
        }
        return result;
    }
}

For that to work you must throw the exception from the code being evaluated i.e. end your code string with:

throw new TriggerClass.IntentionalException('result string');

You are limited to string values unless you add other types of fields to the IntentionalException.

Keith C
  • 135,775
  • 26
  • 201
  • 437
  • Yes I followed the same piece of code , but what should be the result string here? how do I know whether the ifcondition evaluated to true or false? – Jyoti Zanwar Apr 01 '16 at 13:51
  • I added the line, and this is what I have in my ifcondition string: if(24 == 24 && 'India' =='India') Still it evaluates to false – Jyoti Zanwar Apr 01 '16 at 13:57
  • @JyotiZanwar Well the exception throw is missing from what you posted. It is up to you to figure out how all the code you are executing translates to a single true or a false and then return that as a string. And by the way, I don;t see anything in the code you are executing that justifies the mechanism you are using: I suggest you try to re-write the code conventionally. Anyone maintaining this in the future would appreciate you being successful doing that. – Keith C Apr 01 '16 at 13:58
  • 1
    This should result in a true back in the calling code throw new TriggerClass.IntentionalException(String.valueOf(24 == 24 && 'India' =='India'));. – Keith C Apr 01 '16 at 14:00
  • I wanted to evaluate the ifcondition that forms dynamically from a trigger and what led me to this was absence of eval() in apex. That is why I used this future method and ToolingAPI. Can you suggest any other method I can do. – Jyoti Zanwar Apr 01 '16 at 14:01
  • @JyotiZanwar All code is "dynamic" in the sense that you can have various if/else choices and inject data that controls what needs to be done. Was there something you thought you could not do with conventional code? – Keith C Apr 01 '16 at 14:05
  • When I use this directly in triggers, it shows an error saying callouts from trigger are currently not supported. – Jyoti Zanwar Apr 01 '16 at 14:08
  • @JyotiZanwar Using the future annotation should address that. (The results will not be available until some time later though.) See e.g. http://salesforce.stackexchange.com/questions/5602/http-callout-from-triggers. – Keith C Apr 01 '16 at 14:15
  • Yes I knew about the future annotation and used it already in my code. The main question here is how do I evaluate the String variable "ifcondition" which contains something like (24 == 24 && 'India' =='India') and get back its result as true or false depending on the condition. – Jyoti Zanwar Apr 01 '16 at 14:34
  • @JyotiZanwar Is the expression some user input? For that case I would recommend writing an expression parser in Apex; that also allows you to limit what code is executing i.e. so someone can't execute delete [select Id from Account]. – Keith C Apr 01 '16 at 16:10