Code File
FlutterFlow allows you to add your own custom Dart files with classes and enums. This means you can create reusable building blocks to manage your app’s data and logic more easily. Using custom classes, you can create custom data types, use their properties in the UI, call methods in action flows, and much more.
Key Use Cases
- Custom Models: Define your own data models, such as
UserProfile
,Product
, orOrder
, and use them throughout your app. - Business Logic: Add reusable utility methods like tax calculations, formatting, or conditional evaluations.
- Reusable Enums: Define enums and use them in UI conditions and dropdowns.
- No Generics: Classes with generic types (e.g.,
class ApiResponse<T> {}
) are currently not supported. - No Function-Typed Parameters: Methods or fields that have function types as parameters or fields are ignored (e.g., void Function(int) onTap).
- No Extensions: Dart Extensions (e.g.,
extension StringX on String { … }
) are not supported yet.
Create Custom Class
To add a custom class, go to the Custom Code from the left navigation menu, click plus (+) button, and select Code File. Set the name of the file, add your code, and hit the Save button. Now, you must validate your code in the editor to catch basic syntax errors. If there are no errors, click the Parse button. FlutterFlow will scan your code and automatically detect supported classes and enums.
Here’s an example of adding a Review
custom class:
Here's the code snippet of the Review
custom class:
class Review {
String id;
String productId;
String userId;
String userName;
String comment;
double rating; // out of 5
ReviewStatus reviewStatus;
DateTime date;
int helpfulCount = 0;
Review(
this.id,
this.productId,
this.userId,
this.userName,
this.comment,
this.rating,
this.reviewStatus,
this.date,
);
// Method: Get a short version of the comment
String shortComment() {
if (comment.length <= 50) return comment;
return comment.substring(0, 47) + "...";
}
// Method: Get formatted date as string (e.g., "2024-05-22")
String formattedDate() {
return "${date.year}-${_twoDigits(date.month)}-${_twoDigits(date.day)}";
}
String _twoDigits(int n) {
return n >= 10 ? "$n" : "0$n";
}
// Method: Check if review is positive (4 stars or more)
bool isPositive() {
return rating >= 4.0;
}
// Method: Check if review is recent (within last 30 days)
bool isRecent() {
final now = DateTime.now();
return now.difference(date).inDays <= 30;
}
// Method: Mark this review as helpful
void markHelpful() {
helpfulCount += 1;
}
}
You can also include import statements and access generated classes within your custom class files. For more details, see the examples on how to access generated classes.
Create Custom Class Instance
You need to create an instance of a class so you can work with actual data and use the class’s properties and methods in your app. Here’s a simple explanation:
-
A class is like a blueprint or template. For example, the
Review
class describes what a review is, but doesn’t hold any real review information itself. -
An instance (or “object”) is a real, usable item made from that blueprint. See the code snippet below:
Review review1 = Review(
'r001',
'p123',
'u456',
'Alex Morgan',
'Great quality T-shirt!',
4.5,
DateTime(2025, 5, 22),
3,
ReviewStatus.approved,
); -
You can reuse the same class structure multiple times with different review data.
When you create an instance of a class, you can:
- Store actual review details.
- Access and update the fields (e.g.,
review1.rating
orreview1.comment
). - Call methods that do something with that data (e.g.,
review1.markHelpful()
orreview1.shortComment()
).
To create an instance of a custom class, open the Set from Variable dialog and select Create Custom Class Instance. Choose the class you want to use, then select the class name from the Constructor dropdown. After that, set values for each of the required fields.
Using Custom Class
Once the custom class is added successfully, you can access its fields and methods in the Variable Dialog, call its methods in the Action Flow Editor, assign instances to state variables, pass them to page or component parameters, and use enum values in dropdowns or conditionals.
Custom Class as Data Type
You can select your custom class as a Type for variables, state, or parameters, just like a Custom Data Type.
Access Fields and Methods
You can use custom class fields to display values directly in the UI, and call its methods in variable dialogs to return a result.
Set Field [Action]
Use the Set Field action to update a specific property of a custom class instance. For example, you can set review.comment = 'Great fit and quality!'
when a user updates the review, allowing the UI to reflect the new comment instantly.
Call Method [Action]
Use the Call Method action to invoke a method defined in your custom class. For instance, if your Comment
class has a markHelpful()
method, you can trigger it when a user taps a “Helpful” button to record the interaction.
Using Static Members
Sometimes, you may want to define fields and methods that are shared across your app. In such cases, static
fields and methods are ideal. Because they're tied to the class rather than an instance, static members are accessible globally, for example, utilities for formatting, calculations, or global configuration.
This approach is typically used for stateless utility classes where shared functionality is needed across the app. For example, look at the class below:
class Utils {
static int square(int x) => x * x;
}
The Utils
class contains a static method square
that returns the square of a number without needing to create an object of the class.
Here are couple more examples to understand it better:
-
This
StringFormatter
class below provides reusable static methods to capitalize text, convert it to lowercase, or format it in snake_case.class StringFormatter {
static String lastFormatted = '';
static int formatCount = 0;
static String capitalize(String input) =>
input[0].toUpperCase() + input.substring(1);
static String toLowerCase(String input) => input.toLowerCase();
static String toSnakeCase(String input) =>
input.replaceAll(' ', '_').toLowerCase();
} -
The
MathHelper
class offers handy static methods to calculate tax, apply discounts, find percentages, and round off numbers.class MathHelper {
static double calculateTax(double amount) => amount * 0.18;
static double applyDiscount(double amount, double discountPercent) =>
amount - (amount * discountPercent / 100);
static double calculatePercentage(double part, double total) =>
(part / total) * 100;
static int roundOff(double value) => value.round();
}
You can mix both static and instance members in a single class. Static members are shared across all instances, while instance members hold data specific to each object. For example, look at the class below:
class Review {
static List<String> flaggedWords = ['bad', 'spam', 'fake'];
String id;
String userId;
String comment;
int helpfulCount = 0;
Review(
this.id,
this.userId,
this.comment
);
static bool isCommentAppropriate(String input) {
return !flaggedWords.any((word) => input.toLowerCase().contains(word));
}
void markHelpful() {
helpfulCount += 1;
}
}
flaggedWords
is a static list used across all reviews.isCommentAppropriate()
is a static method that can be used without creating aReview
instance, useful for validating comments before saving them.
Using static members are powerful, but they should be used carefully. Overusing static methods can lead to less flexible code and potential issues, especially when the logic requires access to state or needs to evolve over time. Stick to static methods only when the logic is truly independent and doesn’t rely on instance-specific data.
Access Static Fields and Methods
You can access the static class data and methods directly via the Set from Variable menu.
Set Static Field [Action]
Use the Set Static Field action to update a static field on a custom class. For example, if you have a class MathHelper
with a static field amount
, you can set it using an input value when a user enters a price. This allows you to store that value globally and use it across different calculations.
Call Static Method [Action]
Use the Call Static Method action to run a static method of your class. For instance, you can call MathHelper.calculateTax(amount)
to compute tax on a given amount during a checkout action, without needing to create an instance of the class.
Custom Enums
Similar to how you add a custom class, you can also add Custom Enums in your app. Enums are a great way to define a fixed set of values, such as user roles, order statuses, or content types. Once parsed, these enums become available throughout your app and can be used in dropdowns, conditionals, and UI bindings.
For example, you could define an enum called ReviewStatus
with values like pending
, approved
, and rejected
.
You can access the custom enums from Set from Variable menu > Custom Enum section. You’ll see your Dart file listed by name. Select the enum you want to use, such as ReviewStatus
, and then choose the specific value you want to assign.
Tips & Best Practices
- Keep your custom class files modular and focused; ideally one class per file for better organization and reusability.
- Avoid advanced Dart features that are not supported by FlutterFlow’s parser, such as generics or function-typed fields.
- Re-parse your code after making changes to ensure FlutterFlow updates the parsed structure correctly.
- Document your code with comments to make your custom classes easier to understand and maintain over time.