As developers we are frequently capturing data from form input, validating and displaying errors back to the user when validation criteria are not met. Other times we have to create strings such as URL’s with dynamic parameter values or even queries with dynamic where clauses.

In this blog post I want to demonstrate a much better approach on how to create dynamic error messages or even other types of strings using the under used String.format method.

Getting started with a basic problem

Let’s start with a code example on not so good code on adding a custom validation message within a trigger:

opportunity.addError('When the stage is ' + opportunity.stageName + ' a close lost reason must be provided');

The code above is merely adding a custom validation error to an opportunity record being saved. It’s not a great approach for how we should be dealing with error messages as it contains a hard coded text which will not allow the business to modify the message without a developer.

Using custom labels

So the solution to allow the business to customise the error message is of course to use custom labels. The difficulty now is that we need to use a custom label and also include dynamic content within that message to the user.

opportunity.addError(Label.Opportunity_Close_Lost_Reason_Required + ': ' + opportunity.stageName);

This solution is now much better than the first example as it now allow the business to customise the error message and also translate it into other languages. But still it isn’t ideal. Some languages it may make sense to place the dynamic content at the end of the string, but for other languages it may not.

So how can we improve the previous example? Include markers within our custom labels and begin to use the String.format method.

Custom labels with markers

Update your custom label to appear as the following:

When the stage is {0} a close lost reason must be provided

Notice the {0} in the custom label above. This is a marker with a position index of 0. Later in this post it will become clearer why we need to include markers with position indexes.

Next we can update our code to use our custom label and merge in dynamic content into our custom label.

      new List<String>{

The String.format has the following method signature:

format(stringToFormat, formattingArguments)

The first argument is the string to be formatted, which is our custom label that also contains the marker which we need to replace. The second argument to be provided is a list of strings which contain the dynamic content which should replace the markers within the string we passed in the first argument.

What may not be apparent just yet is that the order of the strings within the list corresponds to the markers to be replaced within the string to be formatted. The following example demonstrates this:

String message = '{3}, {2}, {1} and {0}';
String output = String.format(message, new List<String>{
   'Four',  // {0}
   'Three', // {1}
   'Two',   // {2}
   'One'    // {3}
// Output = One, Two, Three and Four

Using this approach to build custom error messages is much better to use as it now enables the business to modify the custom label and adjust it to a more friendly format and is more suitable for other languages which follow other grammar rules.

You can also use this approach within Visualforce and Lightning Components.


The following example shows how to format strings in Visualforce using the same approach as shown above.

<apex:outputtext value="{3}, {2}, {1} and {0}">
   <apex:param value="Four" />
   <apex:param value="Three" />
   <apex:param value="Two" />
   <apex:param value="One" />

Lightning Components

You can also achieve the same now in Lightning Components. The following example shows how to do this in Lightning Components:

{!format('{3}, {2}, {1} and {0}', 'Four', 'Three', 'Two', 'One')}

To conclude

When working with custom labels or other types of strings which require dynamic content use the format methods either in Apex, Visualforce or Lightning Components to simply how your code appears and enable the business to easily change the labels for better ongoing maintenance.

You can find more information on Salesforce: