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
*Note: After changing this setting, you’ll need to save and restart Power Apps Studio.

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



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.



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);
// 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
// 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 );


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
FunctionName(param1:type1, param2:type2...):returnType = {[Expression]};
This enhancement makes centralized app state management possible.
Example 3: Centralized App State Management





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.