-
Notifications
You must be signed in to change notification settings - Fork 109
Code File (Custom Classes) Docs #363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
a838d13
30c9540
1536c98
6520f26
d106a3e
02fbbbb
d161407
af033f0
49c9d8e
82a68fa
d056348
8340dd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
--- | ||
slug: /concepts/custom-code/code-file | ||
title: Code File | ||
description: Learn how to create and use custom classes and enums in FlutterFlow. | ||
tags: [Code File, Custom Code] | ||
sidebar_position: 5 | ||
keywords: [FlutterFlow, Custom Classes, Custom Enums, Customizations, Flutter, Dart, Pub.dev] | ||
--- | ||
|
||
# Code File | ||
|
||
FlutterFlow allows you to add your own custom Dart files with [classes](https://dart.dev/language/classes) and [enums](https://dart.dev/language/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`, or `Order`, 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. | ||
|
||
:::warning[Limitations] | ||
|
||
- **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. | ||
|
||
::: | ||
|
||
## Add 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: | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%'}}> | ||
<iframe | ||
src="https://demo.arcade.software/sX8BKGhdsUGj7IZJCSpN?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
<p></p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. admonition tip somewhere that we can add any imports in our custom classes and can refer to any generated classes too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||
|
||
## Create Class Instance | ||
pinkeshmars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mention how it is similar to datatype instance and point to that doc? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we don't have any docs in custom data type about creating a datatype instance? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we don't have it yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you create a linear ticket for the same and reference this PR comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
- 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: | ||
|
||
```jsx | ||
Review review1 = Review( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. THis may be incomplete if we don't show the code for the Review class first. I know its added to the Arcade but its not enough since the rest of the explanations is so tied to the Review class, but we dont show the class definition in code here. I'd suggest add the Review class snippet after the Create Custom Class Arcade There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree! added. |
||
'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` or `review1.comment`). | ||
- Call methods that do something with that data (e.g., `review1.markHelpful()` or `review1.shortComment()`). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another point where these methods are confusing because we dont have the code for Review class somewhere here where we can reference it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya, now worries. added the code snippet for the Review class. |
||
|
||
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. | ||
|
||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%'}}> | ||
<iframe | ||
src="https://demo.arcade.software/0CQju0ZUuhOEnkRhbxP4?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
<p></p> | ||
|
||
:::tip[When You Don't Need an Instance] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldnt call it a tip rather its a feature. Im afraid this entire section with the description (for e.g "skip instance creation" language) can make non coders feel like this is the easiest approach so lets go with it, and they will have static methods everywhere and more bugs because the logic will not work the way a non static class is expected to work. We should treat it as its own section and talk about when its useful with more examples There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, in that case, let's remove (comment out) this part and revisit with more detail! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because it will take more time to rewrite this part? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i see a bunch of new actions under custom class, see here: https://linear.app/flutterflow/issue/SUP-2529/custom-class-method-is-not-appearing-in-actions-list#comment-34cd1a72 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you say this 'should be covered in the v1 version of the docs' you mean in this PR only right? yes, we can do it. Could you please help with that ticket? it is is not opening for me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes in this PR, can you check the linear ticket again? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! Added a new 'Using Static Classes' section. |
||
|
||
You can skip instance creation when everything in the class is `static`, meaning it's shared across all uses (like a utility class). For example, look at the class below: | ||
|
||
```jsx | ||
class Utils { | ||
static int square(int x) => x * x; | ||
} | ||
``` | ||
|
||
In such cases, you can directly access the class data and methods via the **Set from Variable** menu. | ||
|
||
 | ||
::: | ||
|
||
## 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. | ||
|
||
### Data Types | ||
pinkeshmars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
You can select your custom class as a Type for variables, state, or parameters, just like a [Custom Data Type](../../resources/data-representation/custom-data-types.md). | ||
|
||
 | ||
|
||
### 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. | ||
|
||
 | ||
|
||
### Call In Action Flows | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this is more important to show with an Arcade. and if I remember correctly this is not the name of the action. we must have the action name the way we do it for other features. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, you're right. However, there's currently an issue where custom class methods aren't showing up in the actions list, so I’m unable to see any details or record the arcade. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added now! |
||
|
||
You can also add your custom class’s methods directly within an Action Flow. For example, you can trigger the `markHelpful()` method when a user taps a “Mark as Helpful” button to update a field or increment the helpful count of a review. | ||
|
||
## Enums | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its ###? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. definitely the name shouldnt be just Enums, same reason as Data Types comment. Custom Enums? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed the name to "Custom Enums" but kept the heading as ## only to avoid nesting it under "Using Custom Classes." Since enums are different from classes, I think they deserve their section. |
||
|
||
Similar to how you add a custom class, you can also add Custom Enums in your app. [Enums](../../resources/data-representation/enums.md) 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. | ||
|
||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%'}}> | ||
<iframe | ||
src="https://demo.arcade.software/wFd9NKYGdb2Jp7ZYkaR8?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
<p></p> | ||
|
||
## 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. | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- 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. |
Uh oh!
There was an error while loading. Please reload this page.