Tuesday, 2 January 2024

Evaluate Dynamic Formulas in Apex (Spring 24 Developer Preview)

 The Dynamic Formula brings enhanced capabilities for evaluating user-defined formulas for Apex objects and sObjects.


With the new ‘FormulaEval’ namespace, you can now optimise database CPU demands and avoid static expressions when evaluating formula expressions.


Note : To leverage this feature, ensure that the FormulaEvalInApex feature is enabled in your scratch orgs.Without the feature enabled, Apex code utilising this feature can be compiled but not executed.


Creating a formula instance is made easy with the FormulaBuilder class.


Simply call the static method builder() with the formula text, return type, and context object.


Validate the formula instance by using the build() method, which may trigger the FormulaValidationException exception if the validation fails.


Once your formula instance is validated, you can calculate the formula expression and retrieve the result using the evaluate() method in the FormulaInstance class.


If an error occurs during evaluation, the method will trigger the FormulaEvaluationException exception.


Ex : The usage of the build() and evaluate() methods


global class MotorYacht {

  global Integer lengthInYards;

  global Integer numOfGuestCabins;

  global String name;

  global Account owner;

}


MotorYacht aBoat = new MotorYacht();

aBoat.lengthInYards = 52;

aBoat.numOfGuestCabins = 4;

aBoat.name = 'Go Boat';


// Example 1: Evaluate 'isItSuper' formula instance


FormulaEval.FormulaInstance isItSuper = FormulaEval.FormulaBuilder.builder()

.withReturnType(FormulaEval.FormulaReturnType.STRING)

.withType(MotorYacht.class)

.withFormula('IF(lengthInYards < 100, "Not Super", "Super")')

.build();


isItSuper.evaluate(aBoat); //=> "Not Super"


// Example 2: Evaluate 'ownerDetails' formula instance


aBoat.owner = new Account(Name='Acme Watercraft', Site='New York');

FormulaEval.FormulaInstance ownerDetails = FormulaEval.FormulaBuilder.builder()

.withReturnType(FormulaEval.FormulaReturnType.STRING)

.withType(MotorYacht.class)

.withFormula(‘owner.Name & " (" & owner.Site & ")"')

.build();


ownerDetails.evaluate(aBoat); //=> "Acme Watercraft (New York)"


Monday, 1 January 2024

Make Callout After DML Rollback and Releasing Savepoint (Spring 24 apex)

 Roll back all uncommitted DML by using a savepoint. Then use the new Database.releaseSavepoint method to explicitly release savepoints before making a desired callout.Previously, callouts after creating savepoints resulted in a CalloutException regardless of whether there was uncommitted DML or the changes were rolled back to a savepoint.


To execute callouts post-rollback, adhere to these steps:


  1. Revert all uncommitted changes using a savepoint.
  2. Please make sure to explicitly release the savepoint via the Database.releaseSavepoint method.
  3. Now, perform your intended callout without encountering any hindrances.


Ex :

Savepoint mySavepoint = Database.setSavepoint();


try {

    // Attempt a database operation

    insert new Account(name='Foo');

    Integer divisor = 1 / 0;

} catch (Exception e) {

    // Roll back to the savepoint in case of an exception

    Database.rollback(mySavepoint);

    Database.releaseSavepoint(mySavepoint); // Release any savepoints created after 'mySavepoint'

    

    // Perform a callout as uncommitted work is rolled back and savepoints are released

    initiateCallout();

}

Null Coalescing Operator (Spring 24 Apex)

The ?? Operator returns the left-hand argument if the left-hand argument isn't null. Otherwise, it returns the right-hand argument.

 

// Left operand SOQL is empty, return defaultAccount from right operand:

Ex :

Account defaultAccount = new Account(name = 'Acme');

Account a = [SELECT Id FROM Account WHERE Id = '001000000FAKEID'] ?? defaultAccount;

Assert.areEqual(defaultAccount, a);