Understanding User-Defined Functions in Power Apps Canvas: Comprehensive Guide

I’ve been eagerly awaiting this feature for a long time – “User-Defined Functions” has finally been released (though in preview), so I decided to thoroughly explore how to use it.

*Note: The features discussed in this article are currently in “preview” and may be subject to changes.

User-Defined Functions (UDF)

User-Defined Functions are similar to function declarations that allow you to pre-define functions with specified parameters and return values.
While this is a standard feature in other programming languages (like JavaScript, Python, and C#), Power Apps hasn’t had this capability until now – and it’s been one of the most requested features.

I believe it’s easier to understand through practical examples, so let me walk you through some real-world applications.

Initial Setup

To use User-Defined Functions, you need to modify your settings.Go to [Settings] → [Upcoming features] → [Preview] → Enable “User-Defined Functions”.
*Note: After changing this setting, you’ll need to save and restart Power Apps Studio.

Basic Usage

User-Defined Functions can be defined within App.Formulas.

// Syntax 
FunctionName(param1:type1, param2:type2...):returnType = [Expression];
// Example: IsWeekEnd function (Input:Date, Return:Boolean) 
IsWeekEnd(d:Date):Boolean = Weekday(d) in [1,7];

Once you’ve defined a function like the example above that determines if a date falls on a weekend, you can use it for various purposes such as changing date colors,
displaying icons only on holidays,
and handling button click validations.

Previously, these validations had to be implemented separately for each control, but now the development process is significantly streamlined.

Let me share more examples below.

Example 1: Defining App-Wide Design Standards

User-Defined Functions can be effectively used to implement consistent design standards across your app.

For instance, consider a scenario where you’re building an app that requires postal code and mobile phone number inputs, and you want to display these values in a custom error color (red in this example) when they don’t match the specified format.

Previously, you would define colors in Formulas like this:
And then implement If statements for each text input to define colors:

While this method works for implementing color changes (requirement changes), copying and pasting If statements everywhere becomes tedious.

This is where User-Defined Functions come in handy.
You can define a function that takes a validation expression and returns the appropriate text color (normal or error):

ValidatedTextInputColor(validation:Boolean):Color = If(validation, TextColor.Normal, TextColor.Error);

Now, each control can simply call this function with its specific validation check as an argument, making the code much more concise:

 
// Postal code validation 
ValidatedTextInputColor(IsMatch(Self.Value, "^d{3}-?d{4}$")) 
// Mobile phone validation 
ValidatedTextInputColor(IsMatch(Self.Value, "^0d{2}-?d{4}-?d{4}$")) 


Example 2: Input Validation

Furthermore, we can define the input validation functionality itself as a function:

 // Format validation for postal code, mobile number, and email // *Note: These regular expressions are examples only and are not guaranteed to work in all cases. IsValidFormattedText(type:Text, inputText:Text):Boolean = Switch(type, "PostalCode", IsMatch(inputText, "^d{3}-?d{4}$"), "Mobile", IsMatch(inputText, "^0d{2}-?d{4}-?d{4}$"), "Mail", IsMatch(inputText, "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$"), false );

By defining the validation expressions this way, controls can simply specify the “format type” and “target value” to determine the color:
And naturally, this can also be used for input validation:

This approach is particularly useful because these “universally applicable functions” can be created once and shared with the entire team.

Support for Behavioral Functions like Set and Collect

Recently, behavioral functions like Set and Collect can also be declared by enclosing expressions in curly braces:

FunctionName(param1:type1, param2:type2...):returnType = {[Expression]};

This enhancement makes centralized app state management possible.

Example 3: Centralized App State Management

For applications that need to manage global state (like a shopping cart), you can define Reducer-style functions to centralize all state change logic within the Formulas section.
With this definition in place, the “Add to Cart” button implementation becomes straightforward:
As does the “Increase Quantity” icon:
The “Decrease Quantity” icon:
And the “Remove Item” icon:

By ensuring that all cart state updates go through this function, debugging becomes much more efficient as you can start your investigation from this single function when cart-related issues occur.

However, it’s debatable whether such comprehensive state management is necessary in Power Apps. Even implementing this approach just for global variables (like sidebar open/close states) can significantly improve state management in your application.

Product := Type({id:Text, name:Text, price:Number, quantity:Number});
Action := Type({type:Text, item:Product, quantity:Number});
cartReducer(action:Action):Void={
    Switch(action.type,
        "ADD_ITEM",
            If(!IsBlank(LookUp(cartItems, id = action.item.id)), // カート内の存在チェック
                // If item exists, increment quantity by 1
                UpdateIf(cartItems As i, i.id = action.item.id, {quantity:i.quantity + 1}),
                // If item doesn't exist, add it to cart
                Collect(cartItems, {id:action.item.id, name:action.item.name, price:action.item.price, quantity:action.quantity});
            ),
        "REMOVE_ITEM",
            RemoveIf(cartItems, id = action.item.id),
        "UPDATE_QUANTITY",
            UpdateIf(cartItems As item, item.id=action.item.id, {quantity:Max(item.quantity + action.quantity, 0)});
            // Remove item if quantity becomes 0
            RemoveIf(cartItems, quantity = 0);
    )
};

In conclusion, User-Defined Functions are incredibly powerful and will likely see increased adoption in future Power Apps development.

Related Resources and Official Documentation

Copied title and URL