Evaluate Dynamic Formulas in Apex in Summer '25 : [email protected] (Bob Buzzard)

Evaluate Dynamic Formulas in Apex in Summer '25
by: [email protected] (Bob Buzzard)
blow post content copied from  Bob Buzzard Blog
click here to view original post



### Summary of Content The content discusses an enhancement in Salesforce's Apex programming language introduced in the Summer '25 release. This update allows developers to use a new "template mode" for dynamic formulas, making it easier to reference record fields. Instead of writing complex concatenation formulas, developers can now use a simpler merge syntax. For example, instead of writing: ``` name & " (" & website & ")" ``` Developers can write: ``` {!name} ({!website}) ``` This change simplifies the process of creating formulas that combine strings. The author, Bob Buzzard, has updated his formula tester page to incorporate this new feature, allowing users to specify whether the formula should be evaluated as a template. The page includes a checkbox for this purpose and has an onchange handler that automatically toggles the checkbox based on user input. Additionally, the author shares a revised Apex method that evaluates the formula, addressing some unexpected behavior encountered during testing. One issue was that the method's field name handling was case-sensitive, leading to duplicate entries in the query. The author resolved this by ensuring field names were converted to lowercase before processing. ### Key Details - **Feature**: Template mode for dynamic formulas in Apex. - **Release**: Summer '25 Salesforce release. - **Simplification**: Easier syntax for concatenating strings using merge syntax. - **Formula Tester**: Updated to include a checkbox for template evaluation. - **Apex Method**: Revised to handle case sensitivity in field names. - **Availability**: Requires a Salesforce instance on Summer '25, with sandboxes available on May 9th and scratch orgs on May 11th. ### Additional Context This enhancement is part of Salesforce's ongoing efforts to improve developer experience and streamline coding practices. The introduction of template mode is particularly beneficial for those who frequently work with dynamic formulas, as it reduces complexity and potential errors in formula creation. ### Hashtags for SEO #Salesforce #Apex #DynamicFormulas #TemplateMode #Summer25Release #BobBuzzard #SalesforceDevelopment #CodingSimplification #SalesforceUpdates #DeveloperExperience



Image generated by ChatGPT o3 in response to a prompt by Bob Buzzard
Proving yet again AI isn't good at putting text in images!

Introduction

The ability to evaluate dynamic formulas in Apex, which went GA in the Spring '25 Salesforce release, gets a minor but very useful improvement in the Summer '25 release - template mode. In this mode you can use merge syntax to refer to record fields, making formulas that concatenate strings much easier to specify.  Using the example from the release notes,  rather than writing the formula to combine an account name and website as a clunky concatenation :

    name & " (" & website & ")"

we can write:

    {!name} ({!website})

and tell the formula builder to evaluate it as a template. This felt like a good addition to my formula tester page, that I created to demonstrate the Spring '25 functionality, and it also uncovered some unexpected behaviour.

The Sample

My formula tester page is updated to allow the user to specify whether the formula should be evaluated as a template or not via a simple checkbox under the text area to input the formula:


I've also tried to make the page helpful and added an onchange handler to the text area that toggles the Formula is template checkbox based on whether the entered text contains the patter {! - note that the user can override this if they need that string literal for some other reason:



Note also that there's a timeout of 1 second in the onchange handler so it will only fire when the user has (hopefully) finished typing. 

There will be code


The revised Apex method to build and evaluate the formula is as follows:

@AuraEnabled
public static String CheckFormula(String formulaStr, String sobjectType, String returnTypeStr,
                                  Id recordId, Boolean formulaIsTemplate)
{
    FormulaEval.FormulaReturnType returnType = 
                   FormulaEval.FormulaReturnType.valueof(returnTypeStr);

    FormulaEval.FormulaInstance formulaInstance = Formula.builder()
                                    .withType(Type.forName(sobjectType))
                                    .withReturnType(returnType)
                                    .withFormula(formulaStr)
                                    .parseAsTemplate(formulaIsTemplate)
                                    .build();


    //Use the list of field names returned by the getReferenced method to generate dynamic soql
    Set<String> fieldNames = formulaInstance.getReferencedFields();
    Set<String> lcFieldNames=new Set<String>();
    for (String fieldName : fieldNames)
    {
        lcFieldNames.add(fieldName.toLowerCase());
    }
    if (lcFieldNames.isEmpty())
    {
        lcFieldNames.add('id');
    }

    String fieldNameList = String.join(lcFieldNames,',');
    String queryStr = 'select ' + fieldNameList + ' from ' + sobjectType + 
                      ' where id=:recordId LIMIT 1'; //select name, website from Account
    SObject s = Database.query(queryStr);
    Object formulaResult=formulaInstance.evaluate(s);
    system.debug(formulaResult);

    return formulaResult.toString();
}
The bit I expected to change was the additional formulaIsTemplate parameter and invoking parseAsTemplate on the builder. While testing however, I found that if I built a string literal without using any fields, my fieldNameList parameter was empty and I got an error running the SOQL query of select from Account where id='<blah>'.

My first attempt at a fix was to skip the query if the field list was empty, but the evaluate method errors when passed a null sObject parameter. No problem, I'll just add the Id field if the Set of field names is empty. 

Turns out there was a problem. I checked if the field named Id was in the Set, which it wasn't, then added it. Executing the query duly errored as I had a duplicate field in my query. It turns out that the getReferencedFields method isn't case agnostic and it considers Id as a different field to id and returns them both in the Set.

To confirm this I ran the following Apex:

FormulaEval.FormulaInstance formulaInstance = Formula.builder()
                .withType(Schema.Account.class)
                .withReturnType(FormulaEval.FormulaReturnType.STRING)
                .withFormula('{!name} {!Name} {!NaMe} {!NAME}')
                .parseAsTemplate(true)
                .build();
        
String fieldNameList = String.join(formulaInstance.getReferencedFields(),',');
System.debug('Field name list = ' + fieldNameList);
and got the output:

    09:55:32:043 USER_DEBUG [9]|DEBUG|Field name list = NAME,NaMe,Name,name

So I had to add some extra code to iterate the field names, lower case them and add them to a new Set to remove any duplicates. Then I could check if it was empty and if it was add the id field.

You can find the updated code in my Summer 25 samples repository - note that this needs a Salesforce instance on the Summer '25 which, at the time of writing (April 25th), is pre-release orgs. Sandboxes are available on May 9th and scratch orgs on May 11th, assuming Salesforce hit their dates.

More Information






April 25, 2025 at 07:56PM
Click here for more details...

=============================
The original post is available in Bob Buzzard Blog by [email protected] (Bob Buzzard)
this post has been published as it is through automation. Automation script brings all the top bloggers post under a single umbrella.
The purpose of this blog, Follow the top Salesforce bloggers and collect all blogs in a single place through automation.
============================

Salesforce