|
| 1 | +--- |
| 2 | +slug: /concepts/custom-code/code-file |
| 3 | +title: Code File |
| 4 | +description: Learn how to create and use custom classes and enums in FlutterFlow. |
| 5 | +tags: [Code File, Custom Code] |
| 6 | +sidebar_position: 5 |
| 7 | +keywords: [FlutterFlow, Custom Classes, Custom Enums, Customizations, Flutter, Dart, Pub.dev] |
| 8 | +--- |
| 9 | + |
| 10 | +# Code File |
| 11 | + |
| 12 | +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. |
| 13 | + |
| 14 | +## Key Use Cases |
| 15 | + |
| 16 | +- **Custom Models**: Define your own data models, such as `UserProfile`, `Product`, or `Order`, and use them throughout your app. |
| 17 | +- **Business Logic**: Add reusable utility methods like tax calculations, formatting, or conditional evaluations. |
| 18 | +- **Reusable Enums**: Define enums and use them in UI conditions and dropdowns. |
| 19 | + |
| 20 | +:::warning[Limitations] |
| 21 | + |
| 22 | +- **No Generics:** Classes with generic types (e.g., `class ApiResponse<T> {}`) are currently not supported. |
| 23 | +- **No Function-Typed Parameters:** Methods or fields that have function types as parameters or fields are ignored (e.g., void Function(int) onTap). |
| 24 | +- **No Extensions:** Dart Extensions (e.g., `extension StringX on String { … }`) are not supported yet. |
| 25 | + |
| 26 | +::: |
| 27 | + |
| 28 | +## Add Custom Class |
| 29 | + |
| 30 | +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. |
| 31 | + |
| 32 | +Here’s an example of adding a Review custom class: |
| 33 | + |
| 34 | +<div style={{ |
| 35 | + position: 'relative', |
| 36 | + paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding |
| 37 | + height: 0, |
| 38 | + width: '100%'}}> |
| 39 | + <iframe |
| 40 | + src="https://demo.arcade.software/sX8BKGhdsUGj7IZJCSpN?embed&show_copy_link=true" |
| 41 | + title="" |
| 42 | + style={{ |
| 43 | + position: 'absolute', |
| 44 | + top: 0, |
| 45 | + left: 0, |
| 46 | + width: '100%', |
| 47 | + height: '100%', |
| 48 | + colorScheme: 'light' |
| 49 | + }} |
| 50 | + frameborder="0" |
| 51 | + loading="lazy" |
| 52 | + webkitAllowFullScreen |
| 53 | + mozAllowFullScreen |
| 54 | + allowFullScreen |
| 55 | + allow="clipboard-write"> |
| 56 | + </iframe> |
| 57 | +</div> |
| 58 | +<p></p> |
| 59 | + |
| 60 | +## Create Class Instance |
| 61 | + |
| 62 | +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: |
| 63 | + |
| 64 | +- 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. |
| 65 | +- An **instance** (or “object”) is a real, usable item made from that blueprint. See the code snippet below: |
| 66 | + |
| 67 | + ```jsx |
| 68 | + Review review1 = Review( |
| 69 | + 'r001', |
| 70 | + 'p123', |
| 71 | + 'u456', |
| 72 | + 'Alex Morgan', |
| 73 | + 'Great quality T-shirt!', |
| 74 | + 4.5, |
| 75 | + DateTime(2025, 5, 22), |
| 76 | + 3, |
| 77 | + ReviewStatus.approved, |
| 78 | + ); |
| 79 | + ``` |
| 80 | + |
| 81 | +- You can reuse the same class structure multiple times with different review data. |
| 82 | + |
| 83 | +When you create an instance of a class, you can: |
| 84 | + |
| 85 | +- Store actual review details. |
| 86 | +- Access and update the fields (e.g., `review1.rating` or `review1.comment`). |
| 87 | +- Call methods that do something with that data (e.g., `review1.markHelpful()` or `review1.shortComment()`). |
| 88 | + |
| 89 | +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. |
| 90 | + |
| 91 | + |
| 92 | +<div style={{ |
| 93 | + position: 'relative', |
| 94 | + paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding |
| 95 | + height: 0, |
| 96 | + width: '100%'}}> |
| 97 | + <iframe |
| 98 | + src="https://demo.arcade.software/0CQju0ZUuhOEnkRhbxP4?embed&show_copy_link=true" |
| 99 | + title="" |
| 100 | + style={{ |
| 101 | + position: 'absolute', |
| 102 | + top: 0, |
| 103 | + left: 0, |
| 104 | + width: '100%', |
| 105 | + height: '100%', |
| 106 | + colorScheme: 'light' |
| 107 | + }} |
| 108 | + frameborder="0" |
| 109 | + loading="lazy" |
| 110 | + webkitAllowFullScreen |
| 111 | + mozAllowFullScreen |
| 112 | + allowFullScreen |
| 113 | + allow="clipboard-write"> |
| 114 | + </iframe> |
| 115 | +</div> |
| 116 | +<p></p> |
| 117 | + |
| 118 | +:::tip[When You Don't Need an Instance] |
| 119 | +
|
| 120 | +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: |
| 121 | + |
| 122 | +```jsx |
| 123 | +class Utils { |
| 124 | + static int square(int x) => x * x; |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +In such cases, you can directly access the class data and methods via the **Set from Variable** menu. |
| 129 | + |
| 130 | + |
| 131 | +::: |
| 132 | + |
| 133 | +## Using Custom Class |
| 134 | + |
| 135 | +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. |
| 136 | + |
| 137 | +### Data Types |
| 138 | + |
| 139 | +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). |
| 140 | + |
| 141 | + |
| 142 | + |
| 143 | +### Access Fields and Methods |
| 144 | + |
| 145 | +You can use custom class fields to display values directly in the UI, and call its methods in variable dialogs to return a result. |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | +### Call In Action Flows |
| 150 | + |
| 151 | +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. |
| 152 | + |
| 153 | +## Enums |
| 154 | + |
| 155 | +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. |
| 156 | + |
| 157 | +For example, you could define an enum called `ReviewStatus` with values like `pending`, `approved`, and `rejected`. |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | +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. |
| 162 | + |
| 163 | + |
| 164 | +<div style={{ |
| 165 | + position: 'relative', |
| 166 | + paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding |
| 167 | + height: 0, |
| 168 | + width: '100%'}}> |
| 169 | + <iframe |
| 170 | + src="https://demo.arcade.software/wFd9NKYGdb2Jp7ZYkaR8?embed&show_copy_link=true" |
| 171 | + title="" |
| 172 | + style={{ |
| 173 | + position: 'absolute', |
| 174 | + top: 0, |
| 175 | + left: 0, |
| 176 | + width: '100%', |
| 177 | + height: '100%', |
| 178 | + colorScheme: 'light' |
| 179 | + }} |
| 180 | + frameborder="0" |
| 181 | + loading="lazy" |
| 182 | + webkitAllowFullScreen |
| 183 | + mozAllowFullScreen |
| 184 | + allowFullScreen |
| 185 | + allow="clipboard-write"> |
| 186 | + </iframe> |
| 187 | +</div> |
| 188 | +<p></p> |
| 189 | + |
| 190 | +## Tips & Best Practices |
| 191 | + |
| 192 | +- Keep your custom class files modular and focused; ideally one class per file for better organization and reusability. |
| 193 | +- Avoid advanced Dart features that are not supported by FlutterFlow’s parser, such as generics or function-typed fields. |
| 194 | +- Re-parse your code after making changes to ensure FlutterFlow updates the parsed structure correctly. |
| 195 | +- Document your code with comments to make your custom classes easier to understand and maintain over time. |
0 commit comments