<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Follone</title>
    <description>The latest articles on DEV Community by Gabriel Follone (@_follone).</description>
    <link>https://dev.to/_follone</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3051645%2F3e0da67c-0cdc-4591-9153-ac4e13b2893a.jpg</url>
      <title>DEV Community: Gabriel Follone</title>
      <link>https://dev.to/_follone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_follone"/>
    <language>en</language>
    <item>
      <title>Power Apps - Canvas - Onstart How to avoid ruining your application</title>
      <dc:creator>Gabriel Follone</dc:creator>
      <pubDate>Tue, 13 Jan 2026 22:26:18 +0000</pubDate>
      <link>https://dev.to/_follone/power-apps-canvas-onstart-how-to-avoid-ruining-your-application-d5</link>
      <guid>https://dev.to/_follone/power-apps-canvas-onstart-how-to-avoid-ruining-your-application-d5</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1. Introduction&lt;/li&gt;
&lt;li&gt;2. The OnStart Trap&lt;/li&gt;
&lt;li&gt;3. Principles That Keep OnStart Healthy&lt;/li&gt;
&lt;li&gt;4. Suggested Structure&lt;/li&gt;
&lt;li&gt;5. Practical Tips&lt;/li&gt;
&lt;li&gt;6. Final Checklist&lt;/li&gt;
&lt;li&gt;7. Conclusion&lt;/li&gt;
&lt;li&gt;8. References&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;OnStart runs once when the app loads. It is tempting to treat it like a main() function, but that is where performance and maintainability regress. The goal is to keep OnStart as a thin orchestration layer and push real logic into the formula bar (named formulas, UDFs, tables, and styles).&lt;/p&gt;

&lt;p&gt;Microsoft guidance for large canvas apps explicitly recommends using &lt;code&gt;App.Formulas&lt;/code&gt; instead of &lt;code&gt;App.OnStart&lt;/code&gt; and splitting long formulas into reusable parts. That direction is exactly what this article reinforces (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The OnStart Trap
&lt;/h2&gt;

&lt;p&gt;When OnStart becomes a dumping ground, apps slow down and become fragile. Avoid these patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do not place core business logic in OnStart.&lt;/strong&gt; Define UDFs and named formulas and call them from screens or controls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not load large datasets at startup.&lt;/strong&gt; Load only what the first screen needs and defer the rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not build long, monolithic formulas in OnStart.&lt;/strong&gt; Split logic into named formulas and UDFs (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not call connectors inside loops.&lt;/strong&gt; This multiplies network calls and kills load time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not mix unrelated responsibilities.&lt;/strong&gt; Separate parameters, caching, user context, and UI defaults.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not use OnStart as a hidden workflow engine.&lt;/strong&gt; This breaks reusability and makes testing harder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not rely on screen state.&lt;/strong&gt; Screen-specific setup belongs in Screen.OnVisible or screen-level UDFs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Principles That Keep OnStart Healthy
&lt;/h2&gt;

&lt;p&gt;Use these principles to keep OnStart small and safe:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Thin Orchestration Only&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OnStart should call setup steps, not implement them.&lt;/li&gt;
&lt;li&gt;Keep reusable logic in &lt;code&gt;App.Formulas&lt;/code&gt; and UDFs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deterministic and Idempotent&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running OnStart twice should not corrupt state or create duplicates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fast First Screen&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load only what is required for the first screen to render (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/create-performant-apps-overview" rel="noopener noreferrer"&gt;Overview of creating performant apps&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Separation of Concerns&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep environment/params, collections, user context, and theme settings in distinct blocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Concurrent Only For Independent Tasks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Concurrent only when operations are truly independent (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/efficient-calculations" rel="noopener noreferrer"&gt;Efficient calculations&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Suggested Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------OnStart-----------------------------------------------*/
// Flow response and parameters
With(
    { coFlow: 'SomeFlow'.Run() },
    Set(vsFlowValue, coFlow.result)
);

// Deeplink routing (task focus)
If(
    !IsBlank(Param("Source")),
    Switch(
        Param("SomeParameter"),
        "TaskA",
        /* setup for TaskA */,
        "TaskB",
        /* setup for TaskB */,
        Blank()
    )
);

// Global defaults and parameters
Concurrent(
    Set(vsParamScreen, Param("Screen")),
    Set(viParamItemId, Value(Param("ItemID")))
);

// Build month/period lists
ClearCollect(
    colPeriodList,
    /* data builder logic */
);

// Optional data enrichment (only if needed)
If(
    RoundUp(Month(Now()) / 3, 0) = 1,
    Collect(colPeriodList, /* additional rows */)
);

// Collections cache (first screen only)
ClearCollect(
    colCache,
    ShowColumns(SomeDataSource, /* required columns */)
);

/*-----------------------------------------------End OnStart-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Practical Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;App.Formulas&lt;/code&gt; to split logic&lt;/strong&gt; and keep OnStart readable (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer named formulas for read-only values&lt;/strong&gt; like constants, configuration, and lookups (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-formulas" rel="noopener noreferrer"&gt;Get started with formulas in canvas apps&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use explicit column selection&lt;/strong&gt; like &lt;code&gt;ShowColumns&lt;/code&gt; when caching collections to reduce payload (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/efficient-calculations" rel="noopener noreferrer"&gt;Efficient calculations&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer delegable query patterns&lt;/strong&gt; such as server-side views and &lt;code&gt;StartsWith&lt;/code&gt;/&lt;code&gt;Filter&lt;/code&gt; to avoid local loops (see &lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/optimized-query-data-patterns" rel="noopener noreferrer"&gt;Optimized query data patterns&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache only what is reused on multiple screens.&lt;/strong&gt; If a collection is used on a single screen, load it there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Patch/SubmitForm in OnStart.&lt;/strong&gt; Side effects at startup are hard to debug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document the intent&lt;/strong&gt; of each block with short comments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Final Checklist
&lt;/h2&gt;

&lt;p&gt;Before shipping, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OnStart runs fast and does not load unnecessary data.&lt;/li&gt;
&lt;li&gt;Logic is grouped into clear sections with comments.&lt;/li&gt;
&lt;li&gt;Business rules live in the formula bar (UDFs, named formulas).&lt;/li&gt;
&lt;li&gt;Screen-specific init is in Screen.OnVisible, not OnStart.&lt;/li&gt;
&lt;li&gt;Concurrent is used only for independent work.&lt;/li&gt;
&lt;li&gt;There are no hidden side effects or data writes on startup.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Conclusion
&lt;/h2&gt;

&lt;p&gt;Keeping OnStart lean makes your app faster, easier to maintain, and easier to scale. Treat it as a launcher, not as the place where the app truly lives. The formula bar is where the app logic should grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Official Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-formulas" rel="noopener noreferrer"&gt;Get started with formulas in canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance and Optimization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/efficient-calculations" rel="noopener noreferrer"&gt;Efficient calculations in Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/optimized-query-data-patterns" rel="noopener noreferrer"&gt;Optimized query data patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/create-performant-apps-overview" rel="noopener noreferrer"&gt;Overview on how to create performant Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/app-performance-considerations" rel="noopener noreferrer"&gt;Performance considerations for Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Power Apps - Canvas - Code Reusability How to Do It</title>
      <dc:creator>Gabriel Follone</dc:creator>
      <pubDate>Sat, 05 Jul 2025 02:18:28 +0000</pubDate>
      <link>https://dev.to/_follone/power-apps-canvas-code-reusability-how-to-do-it-3jhc</link>
      <guid>https://dev.to/_follone/power-apps-canvas-code-reusability-how-to-do-it-3jhc</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1. Introduction&lt;/li&gt;
&lt;li&gt;2. Challenge&lt;/li&gt;
&lt;li&gt;
3. How to Solve It?

&lt;ul&gt;
&lt;li&gt;Buttons&lt;/li&gt;
&lt;li&gt;Custom Components and Enhanced Component Properties&lt;/li&gt;
&lt;li&gt;User Defined Functions&lt;/li&gt;
&lt;li&gt;Safely Manipulating Items&lt;/li&gt;
&lt;li&gt;Software Development Principles&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4. Conclusion&lt;/li&gt;

&lt;li&gt;5. Recommendations by Scenario&lt;/li&gt;

&lt;li&gt;6. Important Notes&lt;/li&gt;

&lt;li&gt;7. References&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;As an application grows, it's natural to look for ways to optimize development. Code reusability has always been an applicable concept in Power Apps, although on smaller scales and with greater complexity in the past. Currently, it's more accessible and effective. This article will present several examples of how to reuse logic in your Canvas application, as well as discuss when it's appropriate to apply these techniques.&lt;/p&gt;

&lt;p&gt;For this, let's start with a simple and very common scenario in the daily life of those who create apps with this technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Challenge
&lt;/h2&gt;

&lt;p&gt;Let's say someone asked for a screen to register new people on the team and the screen needs to have a form with 3 text fields, a reset button, a save button, and a table on the side where it's possible to view all team members. Every time the user enters the screen, it needs to reload the users table and reset the input controls, the reset button whenever clicked needs to reload the table and reset the input controls, and the save button needs to update the team members table, simple right?!&lt;/p&gt;

&lt;p&gt;So let's go to the screen without logic and we should have something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl900jjdzsfr08inctyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl900jjdzsfr08inctyv.png" alt="The image displays a two-panel user interface. The left panel is a form with three input fields labeled " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's create the logic to reset the input controls and we should have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Reset Fields
Reset(tiExample1Field_1);
Reset(tiExample1Field_2);
Reset(tiExample1Field_3);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating the logic to reload the table we have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Reload Collection
ClearCollect(colTeam, tbTeam)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we don't follow best practices, we'll end up adding this logic repeatedly in different controls, meaning we'll have the same logic in the screen's &lt;code&gt;OnVisible&lt;/code&gt; and in the reset button's &lt;code&gt;OnSelect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*==============OnVisible==============*/
//Reload Collection
ClearCollect(colTeam, tbTeam);
//Reset Fields
Reset(tiExample1Field_1);
Reset(tiExample1Field_2);
Reset(tiExample1Field_3);

/*==============OnSelect==============*/
//Reload Collection
ClearCollect(colTeam, tbTeam);
//Reset Fields
Reset(tiExample1Field_1);
Reset(tiExample1Field_2);
Reset(tiExample1Field_3);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. How to Solve It?
&lt;/h2&gt;

&lt;p&gt;Now the discussion starts to get serious, after all, currently the best way to do this is still in preview and the others we have available are workarounds, and what are they?&lt;/p&gt;

&lt;h3&gt;
  
  
  Buttons
&lt;/h3&gt;

&lt;p&gt;We have the option to add all of this to an invisible button on the screen and make the screen's &lt;code&gt;OnVisible&lt;/code&gt; properties and the reset button's &lt;code&gt;OnSelect&lt;/code&gt; be a &lt;code&gt;Select()&lt;/code&gt; to this invisible button. This way we ensure maintenance in a single place, but what are the limitations of this approach? The &lt;code&gt;Select()&lt;/code&gt; doesn't work with controls from other screens and doesn't have native support for parameters, meaning if we have logic that is used several times by different controls and events on the same screen and we don't need to pass dynamic values to this logic, this option becomes very interesting and doesn't require activating any preview features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gzit1jpn0vni3m6my53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gzit1jpn0vni3m6my53.png" alt="The image displays a series of screenshots from what appears to be a Power Apps development environment, highlighting various configurations and interactions. The primary focus is on the " width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Components and Enhanced Component Properties
&lt;/h3&gt;

&lt;p&gt;The most viable option currently that doesn't need to activate preview features (yes, enhanced component properties are GA), what are the pros and cons? It brings the same gains as reusability with buttons and still supports parameters (and even allows optional parameters), we can call properties of type event, action, and function from different screens. The downside is just that it's not so easy to use and especially for those who aren't used to real development might not understand very well how to use or where to apply it, but here's an example:&lt;/p&gt;

&lt;p&gt;In this example we don't need to pass any parameters, but we need to change the state of items that are on the screen so we need to activate the component's &lt;code&gt;Access app scope&lt;/code&gt; and with that our property needs to be of type action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb27rkxsgth4iakjy13n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb27rkxsgth4iakjy13n.png" alt="The image displays a screenshot of a Power Apps development interface, focusing on the configuration of a custom component. On the left, within the " width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then copy and paste the logic from the invisible button's &lt;code&gt;OnSelect&lt;/code&gt; from the previous step into the property we just created, add this custom component in a way that's not visible to the user on the team form screen and replace the &lt;code&gt;Select(buExample1Invisible)&lt;/code&gt; with &lt;code&gt;ccFunctionsTeam_1.fxReloadAndResetTeam()&lt;/code&gt; and voilà!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzbf3v47i9sn02ew26gu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzbf3v47i9sn02ew26gu.png" alt="The image displays a series of screenshots from a Power Apps development environment, illustrating how a custom function is triggered by an event and impacts the user interface. The main focus is on the " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  User Defined Functions
&lt;/h3&gt;

&lt;p&gt;The best option, but still not in GA are definitely the UDFs (even though they still don't support optional parameters, they now support behavior functions), and why? Simplicity! It's better than working with Enhanced Component Properties because we can declare it directly in the formula bar, meaning we don't need to create components and add them to the screen, which makes the solution much simpler, elegant, and easy to understand. And how would this look in practice?&lt;/p&gt;

&lt;p&gt;First, copy and paste to the formula bar in the UDFs section the code snippet below (if you don't know what the UDF section is, read my other article about &lt;a href="https://dev.to/_follone/power-apps-canvas-formula-bar-anatomy-1h0n"&gt;Power Apps - Canvas - Formula Bar Anatomy - DEV Community&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udfReloadAndResetTeam() = {
    //Reload Collection
    ClearCollect(colTeam, tbTeam);
    //Reset Fields
    Reset(tiExample1Field_1);
    Reset(tiExample1Field_2);
    Reset(tiExample1Field_3);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the solution would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3r5ec847lg8cgabulgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3r5ec847lg8cgabulgi.png" alt="The image displays a series of screenshots from a Power Apps development environment, illustrating how a user-defined function (UDF) named udfReloadAndResetTeam() is integrated into an application. Red boxes and arrows highlight that this UDF is assigned to both the OnSelect property of a component and the OnVisible property of the " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, from here I assume I no longer need to explain the benefit of all this and the examples will now always start from using UDFs to make this article a bit more practical.&lt;/p&gt;

&lt;p&gt;In our challenge so far we've only solved the request regarding the reset button's &lt;code&gt;OnSelect&lt;/code&gt; and the Team form screen's &lt;code&gt;OnVisible&lt;/code&gt;, but we still need the Save control and how can we do this following all these best practices I'm talking about?&lt;/p&gt;

&lt;h3&gt;
  
  
  Safely Manipulating Items
&lt;/h3&gt;

&lt;p&gt;So far the expression we were reusing was very simple, it had no parameters or anything dynamic. Now let's create a UDF that accepts parameters, but not only that, let's declare types to make our application resistant to unexpected bugs. And in this example we'll create a static named formula with a default value for our team collection just to make it easy to explain.&lt;/p&gt;

&lt;p&gt;Copy and paste in your formula bar in the table section the named formula below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tbTeam = [
    {ItemId: 1, ItemPersonName: "John Doe", ItemPersonMail: "jdoe@contoso.com", ItemPersonRegion: "NA"},
    {ItemId: 2, ItemPersonName: "Gabriel Follone", ItemPersonMail: "gfollone@contoso.com", ItemPersonRegion: "SA"}
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now copy and paste in the UDTs section the type below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tpTeamMember := Type({
    ItemId: Number,
    ItemPersonName: Text,
    ItemPersonMail: Text,
    ItemPersonRegion: Text
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally paste in the UDF section our expression that will insert the values into the collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udfPostMember(ParamMember: tpTeamMember) = {
    Patch(colTeam, 
        Coalesce(LookUp(colTeam, ItemId = ParamMember.ItemId), {}),
        {
            ItemId: (Last(colTeam).ItemId + 1),
            ItemPersonName: ParamMember.ItemPersonName,
            ItemPersonMail: ParamMember.ItemPersonMail,
            ItemPersonRegion: ParamMember.ItemPersonRegion
        }
    )
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the implementation of this becomes quite simple, just add to the save button's &lt;code&gt;OnSelect&lt;/code&gt; the following expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udfPostMember(
    {
        ItemPersonName: tiExample1Field_1.Value,
        ItemPersonMail: tiExample1Field_2.Value,
        ItemPersonRegion: tiExample1Field_3.Value
    }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Software Development Principles
&lt;/h3&gt;

&lt;p&gt;And now let's say a new request comes up: after saving, the input controls need to be reset. But we have a problem now, because our UDF that controls the reset of the form controls also resets the collection! And here comes the SRP (Single Responsibility Principle) from SOLID. This principle makes it clear that a function should be responsible for only one thing within our system, meaning, let's create a UDF for resetting the controls, another for resetting the collection, resulting in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udfReloadTeamData() = {
    //Reload Collection
    ClearCollect(colTeam, tbTeam);
};

udfResetTeamForm() = {
    //Reset Fields
    Reset(tiExample1Field_1);
    Reset(tiExample1Field_2);
    Reset(tiExample1Field_3);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now how does the implementation look? In the save button's &lt;code&gt;OnSelect&lt;/code&gt; right below the &lt;code&gt;udfPostMember&lt;/code&gt; do I call &lt;code&gt;udfResetTeamForm&lt;/code&gt; or add &lt;code&gt;udfResetTeamForm&lt;/code&gt; inside &lt;code&gt;udfPostMember&lt;/code&gt;? If you thought neither, congratulations! Why are neither options good options?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1: Add the call to both UDFs directly in &lt;code&gt;OnSelect&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, this option is much better than the second, but here we're learning about reusability and best practices for all of this, meaning, leaving all the logic in a single control having the option to leave it encapsulated in the formula bar is not the best decision. This reduces the reusability options of the logic, after all, even though it's possible to use &lt;code&gt;Select()&lt;/code&gt; on this button, if I need to use this outside this screen it would no longer be possible.&lt;/p&gt;

&lt;p&gt;Second, it decreases testability, after all it's much easier to test encapsulated logic.&lt;/p&gt;

&lt;p&gt;Third, clarity and maintainability: having this directly in the button's &lt;code&gt;OnSelect&lt;/code&gt; is harder to find and if I have this same logic calling 2 UDFs in different places and the execution order is changed, I would have to change it in all places where this logic is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2: Add the call to &lt;code&gt;udfResetTeamForm&lt;/code&gt; inside &lt;code&gt;udfPostMember&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you understood the explanation about SRP you must have already realized that opting for this scenario makes us go against this principle, after all by doing this we are increasing the coupling between the UDFs, this means that one will depend on the other. If the way to reset the form changes, or if you want to use &lt;code&gt;udfPostMember&lt;/code&gt; in a context where the reset is not necessary, you'll have to modify the insert function. And obviously when coupling increases, flexibility decreases and you lose the option to decide when and how the form should be reset. The reset becomes a &lt;em&gt;mandatory&lt;/em&gt; consequence of the insert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Scenario - Scenario 3: Create a UDF that orchestrates the other two&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With this you maintain the SRP principle, keep coupling low, increase reusability within the app and make the application's operation more readable and easier to understand. Win-win-win!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udfSaveAndResetForm(ParamMember: tpTeamMember) = {
    udfPostMember(ParamMember);
    udfResetTeamForm();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Conclusion
&lt;/h2&gt;

&lt;p&gt;Once again showing that principles long disseminated in software development can be easily applied to low-code tools. Even though we are limited to what the tool's controls offer us (if we don't use PCFs), it's easy to apply everything I explained - it just requires discipline and minimal planning before implementation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invisible Buttons&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Doesn't require preview features&lt;br&gt;• Simple to implement&lt;br&gt;• Works immediately&lt;br&gt;• Familiar to beginners&lt;br&gt;• Doesn't affect performance&lt;/td&gt;
&lt;td&gt;• &lt;code&gt;Select()&lt;/code&gt; doesn't work between screens&lt;br&gt;• Doesn't support parameters natively&lt;br&gt;• Can pollute the screen with invisible controls&lt;br&gt;• Considered a "workaround"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Components&lt;br&gt;(Enhanced Component Properties)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• &lt;strong&gt;Is in GA&lt;/strong&gt;&lt;br&gt;• Supports parameters (including optional)&lt;br&gt;• Works between different screens&lt;br&gt;• Shareable via component library&lt;br&gt;• Typed properties (Action, Event, Function)&lt;br&gt;• Reusable between apps&lt;br&gt;• Professional solution&lt;/td&gt;
&lt;td&gt;• Requires more technical knowledge&lt;br&gt;• More complex initial setup&lt;br&gt;• Steeper learning curve&lt;br&gt;• Can increase app size&lt;br&gt;• Harder to debug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User Defined Functions (UDFs)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Direct declaration in formula bar&lt;br&gt;• Cleaner and more intuitive syntax&lt;br&gt;• Supports behavior functions (Set, Collect, Reset)&lt;br&gt;• No need to add extra controls&lt;br&gt;• Facilitates unit testing&lt;br&gt;• Better code organization&lt;br&gt;• Optimized performance&lt;/td&gt;
&lt;td&gt;• &lt;strong&gt;Still in Preview (not GA)&lt;/strong&gt;&lt;br&gt;• Doesn't support optional parameters&lt;br&gt;• Can't create local variables&lt;br&gt;• Some technical limitations&lt;br&gt;• May change before GA&lt;br&gt;• Requires manual activation&lt;br&gt;• Not shareable between apps (yet)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Recommendations by Scenario
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple app, single screen logic&lt;/td&gt;
&lt;td&gt;Invisible Buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise app, multiple screens&lt;/td&gt;
&lt;td&gt;Custom Components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App in development, technical team&lt;/td&gt;
&lt;td&gt;UDFs (with caution)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared library between apps&lt;/td&gt;
&lt;td&gt;Custom Components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rapid prototyping&lt;/td&gt;
&lt;td&gt;Invisible Buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production with long-term support&lt;/td&gt;
&lt;td&gt;Custom Components&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  6. Important Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UDFs&lt;/strong&gt;: Still in preview, not in GA (Generally Available)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Component Properties&lt;/strong&gt;: Are in GA and ready for production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDFs syntax with behavior functions&lt;/strong&gt;: Use braces &lt;code&gt;{}&lt;/code&gt; for functions with behavior functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDFs have limitations&lt;/strong&gt;: Don't support optional parameters and have some technical restrictions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UDTs are still an Experimental feature&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Official Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-formulas" rel="noopener noreferrer"&gt;Get started with formulas in canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/component-properties" rel="noopener noreferrer"&gt;Canvas component properties&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Blogs and Articles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.microsoft.com/en-us/power-platform/blog/power-apps/user-defined-functions-user-defined-types-and-enhanced-component-properties-move-forward/" rel="noopener noreferrer"&gt;User defined functions, user defined types, and enhanced component properties move forward&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.microsoft.com/en-us/power-platform/blog/power-apps/enhanced-component-properties-user-defined-functions-and-untypedobjects-on-the-move/" rel="noopener noreferrer"&gt;Enhanced Component Properties, User Defined Functions, and UntypedObjects on the move&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_follone/power-apps-canvas-formula-bar-anatomy-1h0n"&gt;Power Apps - Canvas - Formula Bar Anatomy - DEV Community&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance and Optimization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/efficient-calculations" rel="noopener noreferrer"&gt;Efficient calculations in Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/optimized-query-data-patterns" rel="noopener noreferrer"&gt;Optimized query data patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/app-performance-considerations" rel="noopener noreferrer"&gt;Performance considerations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
    </item>
    <item>
      <title>Power Apps - Canvas - Formula Bar Anatomy</title>
      <dc:creator>Gabriel Follone</dc:creator>
      <pubDate>Wed, 16 Apr 2025 13:05:21 +0000</pubDate>
      <link>https://dev.to/_follone/power-apps-canvas-formula-bar-anatomy-1h0n</link>
      <guid>https://dev.to/_follone/power-apps-canvas-formula-bar-anatomy-1h0n</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1. Introduction&lt;/li&gt;
&lt;li&gt;
2. Basic Structure

&lt;ul&gt;
&lt;li&gt;App Values&lt;/li&gt;
&lt;li&gt;UDTs (User Defined Types)&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;UDFs (User-Defined Functions)&lt;/li&gt;
&lt;li&gt;Assets&lt;/li&gt;
&lt;li&gt;Styles&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;7. Conclusion&lt;/li&gt;

&lt;li&gt;8. References&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Code reusability is relatively simple in traditional programming. Concepts like DRY (Don't Repeat Yourself) have existed for a long time, but in Power Platform, this was only possible with considerable effort. Now, this reality has changed with improvements in the formula bar, and that's what we'll explore.&lt;br&gt;
As we add more elements to the formula bar, it becomes increasingly difficult to maintain consistency. That's why I've been organizing it in a specific way that I'd like to share with you.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Basic Structure
&lt;/h2&gt;
&lt;h3&gt;
  
  
  App Values
&lt;/h3&gt;

&lt;p&gt;This section contains basic information about the application and global variables that will be used throughout the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------App Values-----------------------------------------------*/
AppName = "Power Track";
AppVersion = "1.0.0.0";
AppUser = udfGetUserDetails(User().Email);

// Environment Variables
evjsTheme = LookUp('Environment Variable Values', 'Environment Variable Definition'.'Display Name' = "evjsTheme").Value;
/*-----------------------------------------------App Values-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UDTs
&lt;/h3&gt;

&lt;p&gt;User Defined Types (UDTs) help structure complex data and improve typing in the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------UDTs-----------------------------------------------*/
// Custom types to structure Office 365 user data
tpUser := Type(
    {
        AccountEnabled: Boolean,
        BusinessPhones: [{Value: Text}],
        City: Text,
        CompanyName: Text,
        Country: Text,
        Department: Text,
        DisplayName: Text,
        GivenName: Text,
        Id: Text,
        JobTitle: Text,
        Mail: Text,
        MailNickname: Text,
        OfficeLocation: Text,
        PostalCode: Text,
        Surname: Text,
        TelephoneNumber: Text,
        UserPrincipalName: Text,
        mobilePhone: Text
    }
);

// Custom type to structure the color theme
tpThemePalette := Type(
        {
            palette: {
                themePrimary: Text,
                themeLighterAlt: Text,
                themeLighter: Text,
                themeLight: Text,
                themeTertiary: Text,
                themeSecondary: Text,
                themeDarkAlt: Text,
                themeDark: Text,
                themeDarker: Text,
                neutralLighterAlt: Text,
                neutralLighter: Text,
                neutralLight: Text,
                neutralQuaternaryAlt: Text,
                neutralQuaternary: Text,
                neutralTertiaryAlt: Text,
                neutralTertiary: Text,
                neutralSecondary: Text,
                neutralPrimaryAlt: Text,
                neutralPrimary: Text,
                neutralDark: Text,
                black: Text,
                white: Text
            }
        }
    )
;
/*-----------------------------------------------UDTs-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tables
&lt;/h3&gt;

&lt;p&gt;This section contains static table definitions and logic for data manipulation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------Tables-----------------------------------------------*/
// Definition of static tables and data manipulation

// Screen inventory and access control based on named formulas
tbScreens = [
    {ItemId: 1, ItemDisplayName: "Home", ItemScreen: Home}
];

// Table used for navigation components such as a tablist for example
tbNavigation = [
    {ItemId: 1, ItemDisplayName: "Home", Visible: true, ItemTargetScreen: LookUp(tbScreens, ItemId = 1).ItemScreen }
];

// Example of defining a table for use within the app
/*
tbFeedBack = ShowColumns([Table],
        'Created By', //Person Standard
        Rating, //Number
        Message //Multiple Line of Text
    )
;
*/
/*-----------------------------------------------Tables-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UDFs
&lt;/h3&gt;

&lt;p&gt;User-Defined Functions (UDFs) allow encapsulating reusable logic, making the code cleaner and easier to maintain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------UDFs-----------------------------------------------*/
// Reusable functions that simplify logic
udfGetUserDetails(ParamSearch:Text):tpUser =
    If(!IsBlank(ParamSearch),
        First(Office365Users.SearchUserV2({searchTerm: ParamSearch}).value)
    )
;

udfConvertSvg(ParamSvgValue:Text):Text = "data:image/svg+xml;utf8, "&amp;amp;EncodeUrl(ParamSvgValue);
/*-----------------------------------------------UDFs-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Assets
&lt;/h3&gt;

&lt;p&gt;In this section, icons and other visual elements used in the application are defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------Assets-----------------------------------------------*/
// Definition of icons and visual elements

svgHomeIcon = $"&amp;lt;svg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 -960 960 960' width='24px' fill='000000'&amp;gt;&amp;lt;path d='M240-200h147.69v-235.38h184.62V-200H720v-360L480-741.54 240-560v360Zm-40 40v-420l280-211.54L760-580v420H532.31v-235.38H427.69V-160H200Zm280-310.77Z'/&amp;gt;&amp;lt;/svg&amp;gt;";

// Another option here is to make the svg colors dynamic

svgHomeIconDynamic(ParamColor:Text):Text = $"&amp;lt;svg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 -960 960 960' width='24px' fill='{ParamColor}'&amp;gt;&amp;lt;path d='M240-200h147.69v-235.38h184.62V-200H720v-360L480-741.54 240-560v360Zm-40 40v-420l280-211.54L760-580v420H532.31v-235.38H427.69V-160H200Zm280-310.77Z'/&amp;gt;&amp;lt;/svg&amp;gt;";

//To use it is simple, in the image value of an image control you pass the following function udfConvertSvg(svgHomeIconDynamic("#000000"))
/*-----------------------------------------------Assets-----------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Styles
&lt;/h3&gt;

&lt;p&gt;Here, visual definitions such as colors, fonts, and component styles are centralized.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*-----------------------------------------------Style------------------------------------------------*/
// Standardized colors, fonts, and visual elements

// Application theme based on environment variable
Theme = AsType(ParseJSON(evjsTheme), tpThemePalette);

// Fonts
Fonts = {
    Bold        : "Sans Black",
    Semibold    : "Sans Medium",
    Normal      : "Sans",
    Lighter     : "Sans Light"
};

// Text colors
FontColors = {
    Active      : ColorValue("#000000"),  // Active, selected states - using neutralPrimary
    Primary     : ColorValue("#32ba23"),  // Titles, headers - using themePrimary
    Secondary   : ColorValue("#373737"),  // Secondary text, subtitles - using neutralSecondary
    Disabled    : ColorValue("#595959"),  // Disabled text - using neutralTertiary
    WarnLight   : ColorValue("#D11F1F")   // Error text - kept as is because there's no equivalent in the palette
};

//FontSettings
FontSettings = {
    H1: {
        Bold:    { Font: Fonts.Bold,   Size: 24, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Normal:  { Font: Fonts.Normal, Size: 24, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Lighter: { Font: Fonts.Normal, Size: 24, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Secondary  }
    },
    H2: {
        Bold:    { Font: Fonts.Bold,   Size: 18, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Normal:  { Font: Fonts.Normal, Size: 18, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Lighter: { Font: Fonts.Normal, Size: 18, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Secondary  }
    },
    H3: {
        Bold:    { Font: Fonts.Bold,   Size: 16, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Normal:  { Font: Fonts.Normal, Size: 16, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Primary    },
        Lighter: { Font: Fonts.Normal, Size: 16, Lineheight: 1.3, Fontweight: FontWeight.Normal, Color: FontColors.Secondary  }
    }
    ...
};

// Component definition example
Components = {
    Button: {
        Primary: {
            AutoDisableOnSelect: false,
            BorderColor: RGBA(0,0,0,0),
            BorderThickness: 0,
            Color: ColorValue(Theme.palette.white),
            DisabledBorderColor: ColorValue(Theme.palette.neutralLighterAlt),
            DisabledColor: FontColors.Disabled,
            DisabledFill: ColorValue(Theme.palette.neutralLight),
            Fill: ColorValue(Theme.palette.themePrimary),
            FocusedBorderColor: RGBA(0,0,0,0),
            FocusedBorderThickness: 3,
            Font: FontSettings.P.Bold.Font,
            FontWeight: FontSettings.P.Bold.Fontweight,
            HoverBorderColor: RGBA(0,0,0,0),
            HoverColor: ColorValue(Theme.palette.white),
            HoverFill: ColorValue(Theme.palette.themeDark),
            PressedBorderColor: ColorValue(Theme.palette.neutralPrimary),
            PressedColor: ColorValue(Theme.palette.white),
            PressedFill: ColorValue(Theme.palette.themeDarker),
            RadiusBottomLeft: 5,
            RadiusBottomRight: 5,
            RadiusTopLeft: 5,
            RadiusTopRight: 5,
            Size: FontSettings.P.Bold.Size
        }
        //...
    }
};
/*-----------------------------------------------Style------------------------------------------------*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary, the concepts applied here are old; there's nothing about reinventing the wheel, but for Power Apps, they are relatively new. In other words, we just need to apply what already works here too.&lt;/p&gt;

&lt;p&gt;Note: The structure above is just how I organize my formula bar. You are free to organize it as you wish, but just a tip: if you want to create a UDF that uses a table, the UDF must be below the table, which is why I organize UDT &amp;gt; Table &amp;gt; UDF.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-formulas" rel="noopener noreferrer"&gt;Get started with formulas in canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/working-with-large-apps" rel="noopener noreferrer"&gt;Build large and complex canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/efficient-calculations" rel="noopener noreferrer"&gt;Efficient calculations in Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/optimized-query-data-patterns" rel="noopener noreferrer"&gt;Optimized query data patterns in Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/create-performant-apps-overview" rel="noopener noreferrer"&gt;Overview on how to create performant Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/canvas-apps/app-performance-considerations" rel="noopener noreferrer"&gt;Performance considerations for Power Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/power-platform/guidance/creator-kit/theme" rel="noopener noreferrer"&gt;Theming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
    </item>
  </channel>
</rss>
