<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Brandon Wozniewicz - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Brandon Wozniewicz - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 19:47:59 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/scriptedBytes/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Stop Chasing Productivity and Start Moving with Purpose ]]>
                </title>
                <description>
                    <![CDATA[ Most people know how to set goals. And many understand that developing good habits is key to reaching those goals. Yet, despite this knowledge, it's still easy to feel stuck – or worse, in motion with ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-goals-using-the-path-framework/</link>
                <guid isPermaLink="false">68654987cd4d0c286c5cc497</guid>
                
                    <category>
                        <![CDATA[ goals ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ habits ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career development  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Wed, 02 Jul 2025 15:00:23 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750868906416/7cba189f-0c53-4beb-a0d6-cbb034fc73bb.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Most people know how to set goals. And many understand that developing good habits is key to reaching those goals. Yet, despite this knowledge, it's still easy to feel stuck – or worse, in motion without direction.</p>
<p>We chase productivity without asking a deeper question: <em>Are my actions actually moving me toward who I want to become?</em> Being busy feels good. It's a quick hit of dopamine every time we check something off our to-do list – even if that list has nothing to do with our actual goals.</p>
<p>In my own pursuit of reaching my goals, I began developing a simple framework to help me align my daily actions with the person I wanted to be. This isn't a radically new concept here. It is more like a refined mental model that’s built from things you've probably heard and read before. But it’s designed to fit together in a clear, usable way.</p>
<p>The goal is to help bridge the gap between big-picture intentions and everyday behavior. I call it <strong>PATH</strong>.</p>
<p>It stands for:</p>
<ul>
<li><p><strong>Purpose</strong> – your <em>why</em></p>
</li>
<li><p><strong>Aspirations</strong> – the vision of who you want to become</p>
</li>
<li><p><strong>Targets</strong> – clear, measurable goals</p>
</li>
<li><p><strong>Habits</strong> – the consistent actions that support those goals</p>
</li>
</ul>
<p>This is the framework I use to stay oriented. Not just to be productive, but to be <em>intentional</em>. I still get off track, but I find my way back a bit quicker.</p>
<p>In this article, you’ll learn how to apply the PATH framework to clarify your direction, set meaningful goals, and build habits that stick.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a href="#heading-busy-doesnt-mean-effective">Busy Doesn't Mean Effective</a></p>
</li>
<li><p><a href="#heading-the-power-of-frameworks">The Power of Frameworks</a></p>
</li>
<li><p><a href="#heading-a-framework-for-reaching-your-goals">A Framework For Reaching Your Goals</a></p>
</li>
<li><p><a href="#heading-complexity-and-difficulty-are-not-synonyms">Complexity and Difficulty Are Not Synonyms</a></p>
</li>
<li><p><a href="#heading-summary">Summary</a></p>
</li>
</ol>
<h2 id="heading-busy-doesnt-mean-effective">Busy Doesn't Mean Effective</h2>
<p>Being busy can feel like progress. Sometimes it is – you're moving toward your goals, checking boxes, staying active. But other times, it's just noise. A way to avoid sitting still. A way to avoid asking the harder question: <em>Is this making a meaningful difference?</em></p>
<p>Sometimes, we chase productivity not because we're clear, but because, in fact, we're <em>uncertain</em>. And doing something – anything – feels better than acknowledging we might be lost.</p>
<p>On the other hand, you can have clear goals and develop effective habits. But if someone asked you why you picked those goals, would you have an answer? Why do you want to lose ten pounds? Why do you want to start that company? What are you really aiming for?</p>
<p>Here's a thought experiment: Imagine your funeral. You get to pick one person to give your eulogy – and they can only say one sentence about you. What do you hope they'll say?</p>
<p>This is a personal question. And I know my answer very clearly. Do you know yours?</p>
<h2 id="heading-the-power-of-frameworks">The Power of Frameworks</h2>
<blockquote>
<p>You do not rise to the level of your goals. You fall to the level of your systems.</p>
<p>— James Clear</p>
</blockquote>
<p>In programming, a framework is predefined code that helps developers build software more efficiently and effectively. It abstracts away the implementation details of common problems – things you <em>could</em> handle yourself, but probably don't need to. The tradeoff? You give up some flexibility in exchange for speed. In other words, frameworks help you solve your problem faster by <em>deciding a few things for you</em>.</p>
<p>Developers lean on frameworks like React or .NET because they help us focus on solving meaningful problems, rather than wrestling with boilerplate code. PATH works the same way: it abstracts the structure so you can spend more time executing on what matters.</p>
<p>When it comes to setting goals, it's no different. It's easy to get lost in these implementation details and end up overcomplicating the process. We want the perfect strategy or the ideal plan. But in reality, progress almost always beats perfection. Initially, we don't need the most elegant system – we need one that we can follow.</p>
<p>That's where frameworks shine. They reduce friction and help you stop tinkering with the <em>how</em> and start taking action on the <em>what</em>. They free up mental energy, allowing you to focus on actually solving the problem.</p>
<p>This isn't new. Every great tool – whether it's a budgeting app, a productivity system, or a JavaScript library – obscures just enough complexity to help you move towards a solution faster.</p>
<h2 id="heading-a-framework-for-reaching-your-goals">A Framework For Reaching Your Goals</h2>
<p>PATH is a framework I've used for years to align my actions with my desired future self. Most goal-setting systems start with habits or outcomes, but PATH begins a bit further back: your purpose.</p>
<h3 id="heading-p-is-for-purpose"><strong>P is for Purpose</strong></h3>
<p>Purpose is the core of who you are and what matters most. It is your mission statement, no more than a sentence or two. It should be <em>you.</em> A strong purpose will help you get back on track when you veer off course.</p>
<h3 id="heading-a-is-for-aspirations"><strong>A is for Aspirations</strong></h3>
<p>Once you've decided on your purpose, the next step is to dream a little. This is the fun part.</p>
<p>Where do you want to be in the next 5 to 10 years? Try to picture a typical day of your ideal future – not necessarily what you own, but what you experience and do.</p>
<ul>
<li><p>Where do you live?</p>
</li>
<li><p>What time do you wake up?</p>
</li>
<li><p>What do you do during the day?</p>
</li>
<li><p>Who are you with?</p>
</li>
</ul>
<p>Here is an example:</p>
<p><em>I live by a beautiful lake in the mountains. I get up around 7 am, go for a long run, and then eat a healthy breakfast. I spend my day writing. Evenings are slow, spent laughing on the porch with friends and family.</em></p>
<p>Now, let's break that down into aspirations – broad themes that define the kind of life you're building. From that vision, here are three I see:</p>
<ul>
<li><p>Be in good shape</p>
</li>
<li><p>Be a writer</p>
</li>
<li><p>Spend quality time with friends and family</p>
</li>
</ul>
<p>These are your <strong>aspirations</strong> – the "A" in PATH. And they're <em>not</em> meant to be specific or time-bound. Think of them as a compass, not a destination. Their job is to give you something to aim at over and over again.</p>
<h3 id="heading-t-is-for-targets"><strong>T is for Targets</strong></h3>
<p>Targets are the specific goals we aim to achieve.</p>
<p>Each aspiration should have one or more targets – clear, time-bound goals that move you in the direction of your aspiration.</p>
<p>These targets should follow the SMART framework:</p>
<ul>
<li><p>Specific</p>
</li>
<li><p>Measurable</p>
</li>
<li><p>Attainable</p>
</li>
<li><p>Realistic</p>
</li>
<li><p>Time-bound</p>
</li>
</ul>
<p>For example, if you aspire to become a software developer, a target might be:</p>
<p><em>Contribute one fix or update to an open-source project by the end of the month.</em></p>
<p>If aspirations are our compass, targets are the destination. They let you measure progress and know when you've arrived.</p>
<h3 id="heading-h-is-for-habits"><strong>H is for Habits</strong></h3>
<p>Habits are where the rubber meets the road.</p>
<p>Every target should have one or more supporting habits – things you do consistently that move you towards your goal. While they will generally be daily or weekly routines, one-off tasks are also acceptable. The idea is these are things that <strong>move the needle.</strong></p>
<p>For example, if your target is to run a 5k event, a habit might be:</p>
<p><em>Run 3 miles every other day.</em></p>
<p>Or, if you're just starting, you may want to create a one-off task such as:</p>
<p><em>Map out a running route.</em></p>
<p>Again, these habits (or tasks) are <strong>needle-movers</strong>. Following them – <em>actually</em> following them – should almost guarantee that you reach your targets.</p>
<p>When it comes to building a habit, the key is to start small, sometimes <em>really</em> small. In the beginning, the goal isn’t performance, it’s momentum. And while momentum can be hard to start, once it’s moving, it’s even harder to stop.</p>
<p>If you’re trying to build a writing habit, begin with two sentences. If you want to exercise more, start by putting on your workout clothes. Or just drive to the gym. The point is to make starting frictionless.</p>
<p>Consistency also depends on cues. Every habit needs a reliable trigger – something that prompts you to take action. It might be a specific time of day, walking in the door after work, or finishing your morning coffee. Over time, that cue becomes automatic, and so does the habit.</p>
<h2 id="heading-complexity-and-difficulty-are-not-synonyms">Complexity and Difficulty Are Not Synonyms</h2>
<p>There's a moment in the boxing film <em>Bleed for This</em> where the main character is asked, "What's the biggest lie you've ever been told?" He answers:</p>
<p><em>"It's not that simple."</em></p>
<p>The interviewer tries to clarify – as if she believes the main character doesn't understand the question – but he cuts her off and essentially says:</p>
<p><em>"No, that's the lie. It</em> <em><strong>is</strong></em> <em>that simple."</em></p>
<p>That line stuck with me, because we often treat life like it requires a perfect plan before we can begin. However, sometimes the hardest part is simply deciding.</p>
<p>Don't confuse something <em>hard</em> with something that's <em>complex</em>. In my experience, the most meaningful things in life are often simple yet challenging.</p>
<p>Knowing what to do isn't the challenge. It's doing it – over and over again, especially when it's boring, inconvenient, or the outcome is uncertain. That's why clarity matters, and frameworks can help.</p>
<p>There's the person who spends their entire life looking for an elevator. And then there's the person who starts climbing the stairs.</p>
<p>Figure out who you want to be, and filter your goals and actions through that lens.</p>
<p>I'd bet almost anyone reading this could name a few things that would take less than an hour a day that would completely change their life over time. The difference – the <em>only</em> difference –&nbsp;is that the person who gets clear on what they want and then actually does those things every day...gets there.</p>
<p>At the end of the day, the goal isn't to be productive. It's to be <em>intentional</em>. To align your daily actions with your goals and ensure those goals are pushing you toward the person you want to become. That's the idea behind PATH – a framework for being intentional.</p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>If you remember nothing else, here’s the heart of PATH:</p>
<ul>
<li><p><strong>Purpose</strong> – Define your <em>why</em>. A short, personal mission statement that keeps you grounded.</p>
</li>
<li><p><strong>Aspirations</strong> – Paint a picture of who you want to become. Think 5–10 years out, focused on experience, not possessions.</p>
</li>
<li><p><strong>Targets</strong> – Turn aspirations into SMART goals with clear deadlines. These give your vision structure.</p>
</li>
<li><p><strong>Habits</strong> – Identify consistent, meaningful actions that drive progress toward your targets – daily, weekly, or even one-off tasks.</p>
</li>
</ul>
<p>I’ve created a free Notion template to help you get started with the PATH framework.<br>→ <a href="https://www.notion.com/templates/path-goal-tracker-essentials">PATH Goal Tracker Essentials</a></p>
<p>There’s also an upgraded version available for those who want habit tracking, progress calculations, and more.<br>→ <a href="https://www.notion.com/templates/path-goal-tracker-plus">PATH Goal Tracker Plus</a></p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Assign Dataverse Security Roles at Scale ]]>
                </title>
                <description>
                    <![CDATA[ Assigning Dataverse security roles manually works pretty well – until it doesn't. Whether you are onboarding 50 new hires or rolling out access to a new app, managing roles by hand can be tedious and  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-assign-dataverse-security-roles-at-scale/</link>
                <guid isPermaLink="false">68557b4d4b011b57124c6b6b</guid>
                
                    <category>
                        <![CDATA[ Power Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dataverse ]]>
                    </category>
                
                    <category>
                        <![CDATA[ power-automate ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 20 Jun 2025 15:16:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750432574148/b3cfaebe-7566-4795-b00e-5da9d65dd8f4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Assigning Dataverse security roles manually works pretty well – until it doesn't.</p>
<p>Whether you are onboarding 50 new hires or rolling out access to a new app, managing roles by hand can be tedious and error-prone.</p>
<p>In this article, you will learn about three scalable ways to assign security roles across multiple users or teams, with low-code and pro-code options.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a href="#heading-aside-teams">Aside: Teams</a></p>
</li>
<li><p><a href="#heading-canvas-apps-relate-unrelate-functions">Canvas Apps Relate / Unrelate Functions</a></p>
</li>
<li><p><a href="#heading-power-automate-with-the-relate-rows-in-dataverse-action">Power Automate with the Relate Rows in Dataverse Action</a></p>
</li>
<li><p><a href="#heading-c-console-app-using-the-dataverse-sdk">C# Console App: Using the Dataverse SDK</a></p>
</li>
<li><p><a href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ol>
<h2 id="heading-aside-teams">Aside: Teams</h2>
<p>Teams are the simplest way to assign roles to multiple users.</p>
<p>Dataverse admins and team owners can add users to one or more teams. Rather than assigning roles to individual users, the security role is assigned to the team.</p>
<p>But there are caveats: record ownership and team management can introduce their own complexity. In environments with many teams, updating security roles can become just as tedious as assigning them individually.</p>
<p>This article focuses on <strong>programmatic individual assignments</strong>, but keep in mind that all three methods described below can be adapted to work with teams as well.</p>
<h2 id="heading-canvas-apps-relate-unrelate-functions">Canvas Apps Relate / Unrelate Functions</h2>
<p>Canvas app developers can use Power FX to assign security roles across users or teams. Minimal code is required, and the result can serve as a lightweight security role management portal.</p>
<p>While not ideal for massive batches, this approach is suitable for assigning roles to a few hundred users.</p>
<pre><code class="language-plaintext">ForAll(
    colSelectedUsers As User,
    Relate(
        User.'Security Roles (systemuserroles_association)',
        cbx_securityRoles.Selected
    )
)
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>colSelectedUsers</code> is a collection of users.</p>
</li>
<li><p><code>cbx_securityRoles</code> is a Combobox control holding the security role to assign.</p>
</li>
</ul>
<p>The <code>Relate</code> function connects each user with the selected security role. The first parameter is the many-to-many relationship (<code>systemuserroles_association</code>) between <code>systemuser</code> and <code>role</code>.</p>
<p>To find relationship names, open the User table &gt; <strong>Relationships</strong>. Then, look for many-to-many connections to the role table.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/Snag_1e2ee592.png" alt="Image of user table relationships highlighting the system user roles association relationship" width="600" height="400" loading="lazy">

<p>The security role/user relationship is a many-to-many relationship.</p>
<h2 id="heading-power-automate-with-the-relate-rows-in-dataverse-action">Power Automate with the Relate Rows in Dataverse Action</h2>
<p>The <strong>Relate Rows in Dataverse</strong> action allows you to assign roles dynamically in cloud flows.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/power-automate.jpg" alt="Image of cloud flow assigning security roles" width="600" height="400" loading="lazy">

<h3 id="heading-how-it-works">How it works:</h3>
<ul>
<li><p>Trigger a flow (for example, manually or via Dataverse trigger).</p>
</li>
<li><p>Fetch a list of users based on a condition.</p>
</li>
<li><p>Loop through each user with <strong>Apply to Each</strong>.</p>
</li>
<li><p>Assign a static or dynamic security role.</p>
</li>
</ul>
<h2 id="heading-c-console-app-using-the-dataverse-sdk">C# Console App: Using the Dataverse SDK</h2>
<p>This method offers maximum control and supports complex, high-scale role assignments – but it requires pro-code skills.</p>
<p><strong>Example:</strong></p>
<p>This console app:</p>
<ol>
<li><p>Connects to the environment via client credentials.</p>
</li>
<li><p>Retrieves all users with the title "Salesperson"</p>
</li>
<li><p>Builds a batch of associate requests.</p>
</li>
<li><p>Executes the batch transactionally – if one fails, all fail.</p>
</li>
</ol>
<pre><code class="language-csharp">using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

class Program
{
    static void Main(string[] args)
    {
        string dataverseUrl = "https://your-org.crm.dynamics.com";
        string clientId     = "client-id-here";
        string clientSecret = "client-secret-here";
        string tenantId     = "tenant-id-here";

        string connectionString = $@"
            AuthType=ClientSecret;
            Url={dataverseUrl};
            ClientId={clientId};
            ClientSecret={clientSecret};
            TenantId={tenantId};
        ";
        // Connect to our environment
        using var serviceClient = new ServiceClient(connectionString);

        if (!serviceClient.IsReady)
        {
            Console.WriteLine("Failed to connect.");
            return;
        }

        // Fetch a list of users that we intend to associate a role with
        var query = new QueryExpression("systemuser")
        {
            ColumnSet = new ColumnSet("systemuserid"),
            Criteria = new FilterExpression
            {
                Conditions =
                {
                     new ConditionExpression(
                        "title",
                        ConditionOperator.Equal,
                        "Salesperson"
                     ),
                }
            }
        };

        var users = serviceClient.RetrieveMultiple(query);

        // Role to assign (pretend guid for demo purposes)
        var securityRoleId = new Guid(
            "00000000-0000-0000-0000-000000000ABC"
        );

        // Prepare our transaction
        var transaction = new ExecuteTransactionRequest
        {
            ReturnResponses = true,
            Requests = new OrganizationRequestCollection()
        };

        // For each user we fetched above, we add an associate request 
        // to the transaction
        foreach (var user in users.Entities)
        {
            var userId = (Guid)user["systemuserid"];

            var relationship = new Relationship(
                "systemuserroles_association"
            );

            var relatedReferences = new EntityReferenceCollection
            {
                new EntityReference(
                    "role",
                    securityRoleId
                )
            };
            // build the associate request
            var request = new AssociateRequest
            {
                Target = new EntityReference(
                    "systemuser",
                    userId
                ),
                RelatedEntities = relatedReferences,
                Relationship = relationship
            };
            // add the request to the transaction
            transaction.Requests.Add(request);
        }

        // Finally, execute the batch as a transaction
        serviceClient.Execute(transaction);
    }
}
</code></pre>
<p>You can even utilize this logic within a Custom API, allowing Power Automate or Canvas Apps to call it, blending low-code and pro-code capabilities.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>If your teams are already well-structured and manageable in number, <strong>teams remain the easiest way</strong> to assign roles at scale.</p>
<p>But when teams aren't feasible –&nbsp;or when assigning directly to users is required – each method we discussed here offers a viable alternative:</p>
<ul>
<li><p>Use <strong>Canvas Apps</strong> for lightweight, user-facing management portals</p>
</li>
<li><p>Use <strong>Power Automate</strong> when complexity is low and there is a need to trigger it in a variety of ways.</p>
</li>
<li><p>Use <strong>C# and the Dataverse SDK</strong> for full control and batch efficiency.</p>
</li>
</ul>
<p>Ready to automate your role assignments? Start small –&nbsp;build a simple Power App or Flow – and scale your approach from there.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Reduce Technical Debt in the Power Platform ]]>
                </title>
                <description>
                    <![CDATA[ Technical debt refers to the future cost – measured in terms of time, money, effort, or opportunity – of choosing expedient solutions today instead of more deliberate and scalable ones. And it's not j ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-reduce-technical-debt-in-the-power-platform/</link>
                <guid isPermaLink="false">6842c4f3e7fdc9878ba5dadd</guid>
                
                    <category>
                        <![CDATA[ Power Platform ]]>
                    </category>
                
                    <category>
                        <![CDATA[ powerapps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 06 Jun 2025 10:37:39 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748957101508/ffb9fc9d-3d35-477b-841f-280d8c6a6793.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Technical debt</strong> refers to the future cost – measured in terms of time, money, effort, or opportunity – of choosing expedient solutions today instead of more deliberate and scalable ones. And it's not just a pro-code concept.</p>
<p>It might be easier to understand if we compare it to financial debt.</p>
<p>Howard G. Cunningham – the creator of the first wiki – described technical debt this way:</p>
<blockquote>
<p><em>Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable.</em></p>
<p><em>The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.</em></p>
</blockquote>
<p>In this article, you'll learn why technical debt is just as much a concern in low-code projects as in traditional development – and why, in some ways, it can be even more prominent. We'll walk through eight common contributors to technical debt in Power Platform projects that, if left unchecked, can lead to future headaches.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a href="#heading-why-technical-debt-is-also-a-low-code-problem">Why Technical Debt Is Also a Low-Code Problem</a></p>
</li>
<li><p><a href="#heading-eight-examples-of-technical-debt-in-a-low-code-project">Eight Examples of Technical Debt in a Low-Code Project</a></p>
<ul>
<li><p><a href="#heading-hard-coded-or-static-values-in-your-code">Hard-Coded or Static Values in Your Code</a></p>
</li>
<li><p><a href="#heading-duplicated-code">Duplicated Code</a></p>
</li>
<li><p><a href="#heading-poor-naming-of-controls-and-variables">Poor Naming of Controls and Variables</a></p>
</li>
<li><p><a href="#heading-overloaded-screens-and-applications">Overloaded Screens and Applications</a></p>
</li>
<li><p><a href="#heading-no-version-notes">No Version Notes</a></p>
</li>
<li><p><a href="#heading-invisible-logic">Invisible Logic</a></p>
</li>
<li><p><a href="#heading-denormalized-data-models">Denormalized Data Models</a></p>
</li>
<li><p><a href="#heading-leading-with-layout-before-logic">Leading with Layout Before Logic</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ol>
<h2 id="heading-why-technical-debt-is-also-a-low-code-problem">Why Technical Debt Is Also a Low-Code Problem</h2>
<p>Technical debt builds when short-term decisions ignore long-term consequences. While it exists in any development, low-code platforms increase the risk for a simple reason: they remove much of the traditional friction that forces teams to slow down.</p>
<p>With fewer barriers to entry, it's easier for citizen developers – and even professional developers new to the platform – to start building without considering maintainability, scalability, and security.</p>
<p>Low-code platforms enable speed – but if you aren't intentional, the speed can create an environment that fosters the growth of technical debt.</p>
<h2 id="heading-eight-examples-of-technical-debt-in-a-low-code-project">Eight Examples of Technical Debt in a Low-Code Project</h2>
<h3 id="heading-hard-coded-or-static-values-in-your-code">Hard-Coded or Static Values in Your Code</h3>
<p>We've all seen code like this:</p>
<pre><code class="language-plaintext">Office365Outlook.SendEmailV2(
  gblAuthenticatedUser.Email, 
  "Sign-Up Request Received!", 
  "A team member will reach out shortly with more information."
)
</code></pre>
<p>At first glance, this appears to be fine. But what happens if the subject or body of the email needs to change?</p>
<p>Hard-coded values are fragile. A better approach is to store your email templates in a data source, even if it only contains one record.</p>
<pre><code class="language-plaintext">With({
  wthEmailTemplate: LookUp(EmailTemplates, TemplateType="new_signup")},
  Office365Outlook.SendEmailV2(
    gblAuthenticatedUser, 
    wthEmailTemplate.Subject, 
    wthEmailTemplate.Message
  )
)
</code></pre>
<p>Now, if the email needs to be changed, you update the data source, not the application logic.</p>
<h3 id="heading-duplicated-code">Duplicated Code</h3>
<p>While it can be trickier to avoid than in traditional code, duplicate logic is a future maintenance headache.</p>
<p>Imagine two different ways to create comments in an application:</p>
<pre><code class="language-plaintext">//Main dialog in a stream of comments
With(
    {
        wthNewlyCreatedComment: Patch(
            Comments,
            Defaults(Comments),
            {Comment: txt_hs_comment.Value}
        )
    },
    Collect(
        colComments,
        wthNewlyCreatedComment
    );
    Set(
        gblCommentCount,
        CountRows(colComments)
    )
)

//A different dialog when replying to another's comment
With(
    {
        wthNewlyCreatedComment: Patch(
            Comments,
            Defaults(Comments),
            {Comment: txt_hs_dialogComment.Value}
        )
    },
    Collect(
        colComments,
        wthNewlyCreatedComment
    );
    Set(
        gblCommentCount,
        CountRows(colComments)
    )
)
</code></pre>
<p>These two blocks do the same thing. If the logic ever changes, you must remember to update it in both places.</p>
<p>A cleaner approach is to use a <strong>user-defined function (UDF)</strong> to encapsulate logic that gets reused across your app.</p>
<pre><code class="language-plaintext">// App.Formulas
UpdateComments(comment: Text):Void = 
{
	With(
        {
            wthNewlyCreatedComment: Patch(
                Comments,
                Defaults(Comments),
                {Comment: comment}
            )
        },
        Collect(
            colComments,
            wthNewlyCreatedComment
        );
        Set(
            gblCommentCount,
            CountRows(colComments)
        )
    )
};
</code></pre>
<p>And then in each of the locations that need this formula:</p>
<pre><code class="language-plaintext">//Main dialog in a stream of comments
UpdateComments(txt_hs_comment.Value)

//A different dialog when replying to another's comment
UpdateComments(txt_hs_dialogComment.Value)
</code></pre>
<p>As of this writing, <strong>user-defined functions in Canvas apps support side effects</strong> (such as modifying collections or setting variables), but the overall feature is still <strong>in preview</strong>.</p>
<p>If UDFs aren't an option for your current use case, a common workaround is to use a hidden button that encapsulates the logic and call it with <code>Select(ButtonName)</code>. Just keep in mind: the control must be on the same screen where it's being invoked.</p>
<h3 id="heading-poor-naming-of-controls-and-variables">Poor Naming of Controls and Variables</h3>
<pre><code class="language-plaintext">Home Screen
  ButtonCanvas4
  TextCanvas2
  ButtonCanvas1
</code></pre>
<p>What's wrong with the scenario above? It is impossible to know what each control is responsible for.</p>
<p>Good naming isn't just a nice-to-have – it's one of the best ways to reduce confusion and improve maintainability, especially in collaborative environments.</p>
<p>Here is an improved version that allows any developer to understand what these controls do:</p>
<pre><code class="language-plaintext">Home Screen
  txt_hs_userName
  btn_hs_submitForm
  btn_hs_cancelSubmission
</code></pre>
<p>In this example, we follow the pattern of:</p>
<p><code>[control_type]_[screen]_[control responsibility]</code></p>
<p>This helps make it easy to search for items quickly as well as identify what they do.</p>
<p>Another aspect that naturally lends itself to naming conventions is the use of variables. Canvas apps have various methods for storing data locally. They include:</p>
<ol>
<li><p>Collections (ClearCollect/Collect)</p>
</li>
<li><p>Global Variables (Set)</p>
</li>
<li><p>Local Variables (UpdateContext)</p>
</li>
<li><p>Contextual Variables (With functions)</p>
</li>
</ol>
<p>Each type of variable has a different scoping associated with it. Collections are tables and available throughout your entire application. Global variables are also available throughout the entire application. Variables set using <code>UpdateContext</code> are scoped to the screen on which they are declared. And variables contained within a <code>With</code> function are available only within that function.</p>
<p>It is a good idea to ensure that the variable name accurately reflects the type of variable it represents. For example:</p>
<pre><code class="language-plaintext">// prefixed with "wth" for a with-function scoped variable
With({wthNewlyCreatedUser: Patch(AppUsers,...)},...)

// prefixed with "ctx" for a screen-scoped contextual variable
UpdateContext({ctxCurrentPostVotes: LookUp(colPostVotes, ....)})

// prefixed with "gbl" for global
Set(gblAuthenticatedUser, LookUp(AppUsers,....))

// prefixed with "col" for a collection
ClearCollect(colUserRoles, LookUp(AppRoles, ...))
</code></pre>
<p>Each data storage type is designated by a prefix that indicates its kind, which makes debugging an application easier.</p>
<h3 id="heading-overloaded-screens-and-applications">Overloaded Screens and Applications</h3>
<p>It can be tempting to keep everything on one screen for simple applications. But canvas apps can quickly become non-performant if too many controls or too much logic is on a single screen. The recommended limit is no more than 500 controls per app and 300 controls per screen. Using and editing the application can slow down significantly if these limits are exceeded.</p>
<p>One way to prevent this issue is to think more modularly. For example, you may have both administrative and non-administrative tasks within a single application. Instead, you can make two applications, one for admin users and the other for general users.</p>
<p>Another way to avoid these issues in the same application is to build using components. The controls that make up a component don't count individually towards the screen limits and are also a natural way to reduce duplication within and across your applications. Components can be created within an application or as a component library (if your component needs to be used in multiple applications – for example, loaders/spinners and confirmation dialogs).</p>
<p>For more information on components, refer to <a href="https://www.scriptedbytes.com/posts/power-apps-reusable-components">this article I wrote about building reusable components.</a></p>
<h3 id="heading-no-version-notes">No Version Notes</h3>
<p>As the Power Platform ecosystem grows, advanced versioning techniques are being introduced, including the integration of solutions with Git. But even if you don't have that git integration, there is something simple you can do.</p>
<p>When you save an application after any non-trivial change, use the built-in version notes.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/Snag_29bdb959.png" alt="Image of how to save with version notes in a canvas app" width="600" height="400" loading="lazy">

<p>This simple habit will make two things much easier:</p>
<ol>
<li><p>If you ever need to roll back changes, it becomes much easier to identify the correct version to roll back to.</p>
</li>
<li><p>When using multiple environments (for example, Dev, Test, and Prod), this can help you identify which version is currently in each environment, as the built-in version numbers may not necessarily match.</p>
</li>
</ol>
<p>To view version notes for a canvas app, select 'View Details' for the app and then select the versions tab.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/Snag_29bde376.png" alt="Image of canvas app versions and version notes" width="600" height="400" loading="lazy">

<h3 id="heading-invisible-logic">Invisible Logic</h3>
<p>Invisible logic is logic that supports a product, but it is not immediately recognizable. For example, custom APIs and cloud flows can quickly become forgotten if there is no documentation reminding developers that these critical components exist – and what they actually do.</p>
<p>One of the best ways to document a project is by using solutions. Solutions will typically include the majority of a project's assets – often more than 90% – but there are notable exceptions, such as SharePoint lists, Power BI reports, and certain external integrations.</p>
<p>Some things a solution often won't or can't include are assets that belong to core or base solutions – for example, generic cloud flows that serve multiple projects or products. Depending on your solution strategy, you may not want to add these to each solution, and they will only exist in a core or base solution.</p>
<p>Other things that fall under the umbrella of invisible logic include Power BI assets and Dataflows, along with their respective automation architectures (for example, how and when a Dataflow gets triggered).</p>
<p>As a best practice, utilize the self-documenting nature of solutions to provide references to all assets, logic, and dependencies that a project uses. Also, consider adopting a feature-based documentation practice, where each feature or user story implemented includes basic documentation, including high-level implementation details and any underlying logic. This could be a wiki-like document that allows developers, who may be troubleshooting or extending a feature, a simple way to get oriented before diving into an unfamiliar project.</p>
<h3 id="heading-denormalized-data-models">Denormalized Data Models</h3>
<p>Data normalization is a topic of its own, but you don't need to be an expert to get started building robust and <em>scalable</em> data models. In simple terms, data normalization involves grouping similar data elements and eliminating duplication.</p>
<p>Take a look at the following example of the employee table.</p>
<pre><code class="language-plaintext">Employees Table (Denormalized)

| Employee ID | Name   | Department Name | Department Location |
|-------------|--------|------------------|----------------------|
| 1           | Alice  | HR               | Building A           |
| 2           | Bob    | IT               | Building B           |
| 3           | Carol  | HR               | Building A           |
| 4           | Dan    | IT               | Building B           |
| 5           | Eve    | Finance          | Building C           |
</code></pre>
<p>In the above table, we can see the EMPLOYEE table records contain information about the department. Conceptually, this is fine, but the main issue is that the attributes of each record not only describe the employee but also provide details about the department.</p>
<p>This type of data is referred to as denormalized data. Denormalized data makes the data model harder to scale and maintain. For example, if the <code>Department Name</code> changes, we must locate every record with that department name and update it accordingly.</p>
<p>Instead, let's examine a more normalized data model that consists of two tables now.</p>
<pre><code class="language-plaintext">Employees Table (Normalized)

| Employee ID | Name   | Department ID |
|-------------|--------|----------------|
| 1           | Alice  | 1              |
| 2           | Bob    | 2              |
| 3           | Carol  | 1              |
| 4           | Dan    | 2              |
| 5           | Eve    | 3              |


Departments Table

| Department ID | Department Name | Department Location |
|---------------|------------------|----------------------|
| 1             | HR               | Building A           |
| 2             | IT               | Building B           |
| 3             | Finance          | Building C           |
</code></pre>
<p>This data model eliminates duplication and simplifies attribute updates for the department, requiring only a single record update to be made. And because each attribute of the EMPLOYEES and DEPARTMENTS tables only describes the primary key of the respective table, this is a normalized data model.</p>
<p>One common misconception among new developers is that more tables are a bad thing. Many believe that fewer data sources are easier to maintain, but that’s not always true.</p>
<p>In development, what makes things easier to maintain isn't less of something, but rather how atomic, modular, and dependent-free it is. For example, a few small, pure functions that do just one thing will be easier to maintain than a single side-effect-producing function that does many things.</p>
<p>Don't shy away from normalized data just because it creates more tables. Shy away from data models that won't scale.</p>
<p><strong>One final note:</strong> Denormalized data has its place, too, and it's not a bad thing. For example, reporting data is often denormalized and is much more preferred as it makes reporting logic much easier.</p>
<h3 id="heading-leading-with-layout-before-logic">Leading with Layout Before Logic</h3>
<p>Low code makes it easy to jump in and start building, which is a significant benefit. But this model can also make it very easy to skip important aspects of development, such as requirement gathering, user interface design, and data modeling.</p>
<p>It's perfectly fine to prototype ideas. This is great for quickly determining if something may or may not be feasible. But you must have the discipline to stop before getting too far along, and take time to plan properly.</p>
<p>For example, consider employing a business logic-first approach. This means that the requirements and core business logic are decided on (and often implemented) before you even start building the user interface.</p>
<p>The core principle of this type of development is that, regardless of the interface a user chooses to interact with our data – and remember, a web application is nothing more than an interface to your data – the core business logic should function properly. In this light, a Canvas app becomes just an aesthetic wrapper that complements what is hopefully well-designed business logic.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Technical debt exists in both traditional and low-code development. Recognizing this debt early, before it begins to accumulate, is critical. Some tips that can reduce and keep technical debt at manageable levels are:</p>
<ol>
<li><p>Avoid hard-coded or static data in your app logic</p>
</li>
<li><p>Eliminate duplicated logic with user-defined functions (UDFs)</p>
</li>
<li><p>Use consistent naming conventions for controls and variables</p>
</li>
<li><p>Break overloaded apps into multiple screens or multiple apps</p>
</li>
<li><p>Add version notes to track meaningful changes</p>
</li>
<li><p>Document invisible logic such as flows and APIs</p>
</li>
<li><p>Normalize your data to reduce duplication</p>
</li>
<li><p>Start with business logic—not layout or visuals</p>
</li>
</ol>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Sort Dates Efficiently in JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Recently, I was working on a PowerApps Component Framework (PCF) project that required sorting an array of objects by date. The dates were in ISO 8601 format but without a time zone – for example, "20 ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-sort-dates-efficiently-in-javascript/</link>
                <guid isPermaLink="false">6839b592f8650e337982bcba</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ datetime ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 30 May 2025 13:41:38 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748612402734/7124a95d-0a33-4ab6-93d2-d94fc354ae12.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Recently, I was working on a PowerApps Component Framework (PCF) project that required sorting an array of objects by date. The dates were in ISO 8601 format but without a time zone – for example, <code>"2025-05-01T15:00:00.00"</code>.</p>
<p>Without much thought, I wrote something similar to:</p>
<pre><code class="language-JavaScript">const sorted = data.sort((a, b) =&gt; {
  return new Date(a.date) - new Date(b.date);
})
</code></pre>
<p>This worked fine on small datasets. But the array I was sorting had nearly <strong>30,000 objects</strong>. On a fast development machine, the performance hit was around <strong>100–150ms</strong> – already noticeable when combined with other UI work. When I tested with <strong>4× CPU throttling</strong> in the browser, the delay increased to nearly <strong>400ms</strong>, which more accurately simulates a lower-end device. That's a reasonable approach to ensure your app still performs well for users on slower machines.</p>
<p>Results in browser:</p>
<pre><code class="language-Bash">sort_with_date_conversion: 397.955078125 ms
</code></pre>
<p>Output with performance throttled by 4x slowdown</p>
<p>In this article, you will learn how to sort dates efficiently in JavaScript. We'll walk through what makes the method above inefficient, as well as a better pattern–especially when dealing with large amounts of data.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a href="#heading-why-400ms-feels-slow">Why 400ms Feels Slow</a></p>
</li>
<li><p><a href="#heading-setting-up-our-experiment">Setting Up Our Experiment</a></p>
</li>
<li><p><a href="#heading-the-cost-of-date-conversion">The Cost of Date Conversion</a></p>
</li>
<li><p><a href="#heading-the-lexicographical-superpower-of-iso-8601">The Lexicographical Superpower of ISO 8601</a></p>
</li>
<li><p><a href="#heading-what-if-your-dates-arent-iso-format">What If Your Dates Aren't ISO Format?</a></p>
</li>
<li><p><a href="#heading-key-takeaways">Key Takeaways</a></p>
</li>
</ol>
<h2 id="heading-why-400ms-feels-slow">Why 400ms <em>Feels</em> Slow</h2>
<p>According to Jakob Nielsen's classic <em>"Usability Engineering</em>" (1993), delays under 100 milliseconds are perceived as instantaneous. Between 100ms and 1,000ms, users start to notice lag – even if it doesn't require UI feedback. In my case, 400ms felt <strong>choppy</strong>, especially since the PCF component was already handling other tasks. It wasn't going to cut it.</p>
<h2 id="heading-setting-up-our-experiment">Setting Up Our Experiment</h2>
<p>Let's simulate this with a simple experiment that stress tests our sorting. We'll create an array of 100,000 ISO-formatted dates, and <strong>we will simulate a 4x performance slowdown in the browser for all scenarios:</strong></p>
<pre><code class="language-JavaScript">// Create an array of 100,000 ISO-format dates
const isoArray = [];
let currentDate = new Date(2023, 9, 1); // October 1, 2023

for (let i = 0; i &lt; 100000; i++) {
  const year = currentDate.getFullYear();
  const month = String(currentDate.getMonth() + 1).padStart(2, '0');
  const day = String(currentDate.getDate()).padStart(2, '0');

  isoArray.push({ date: `\({year}-\){month}-${day}`, value: i });
  currentDate.setDate(currentDate.getDate() + 1); // advance by one day
}

// Shuffle the array to simulate unsorted input
function shuffle(array) {
  for (let i = array.length - 1; i &gt; 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

shuffle(isoArray);
</code></pre>
<h2 id="heading-the-cost-of-date-conversion">The Cost of Date Conversion</h2>
<p>Now, let's sort using the <code>new Date()</code> method, where each new date is instantiated directly inside the sort method.</p>
<pre><code class="language-JavaScript">console.time('sort_with_date_conversion');

// Sorting by converting each string to a Date object on every comparison
const sortedByDate = isoArray.sort((a, b) =&gt; {
  return new Date(a.date) - new Date(b.date);
});

console.timeEnd('sort_with_date_conversion');
</code></pre>
<p>Result in browser:</p>
<pre><code class="language-Bash">sort_with_date_conversion: 1629.466796875 ms
</code></pre>
<p>Sorting 100,000 dates took almost 2 seconds.</p>
<p>Almost 2 seconds. Ouch.</p>
<h2 id="heading-the-lexicographical-superpower-of-iso-8601">The Lexicographical Superpower of ISO 8601</h2>
<p>Here’s the critical realization: <strong>ISO 8601 date strings are already lexicographically sortable</strong>. That means we can skip the <code>Date</code> object entirely:</p>
<pre><code class="language-JavaScript">console.time('sort_by_iso_string');

// Compare strings directly — thanks to ISO 8601 format
const sorted = isoArray.sort((a, b) =&gt; 
  a.date &gt; b.date ? 1 : -1
);

console.timeEnd('sort_by_iso_string');
console.log(sorted.slice(0, 10));
</code></pre>
<p>Output in the console:</p>
<pre><code class="language-Bash">sort_by_iso_string: 10.549072265625 ms
[
  { date: '2023-10-01', value: 0 },
  { date: '2023-10-02', value: 1 },
  { date: '2023-10-03', value: 2 },
  { date: '2023-10-04', value: 3 },
  { date: '2023-10-05', value: 4 },
  { date: '2023-10-06', value: 5 },
  { date: '2023-10-07', value: 6 },
  { date: '2023-10-08', value: 7 },
  { date: '2023-10-09', value: 8 },
  { date: '2023-10-10', value: 9 }
]
</code></pre>
<p>From 1600ms down to ~10ms. That's a 160x speedup.</p>
<p>Why is this faster? Because using new Date() inside .sort() results in creating two new Date objects <strong>per comparison</strong>. With 100,000 items and how sort works internally, that's <strong>millions</strong> of object instantiations. On the other hand, when we sort lexicographically, we are simply sorting strings, which is far less expensive.</p>
<h2 id="heading-what-if-your-dates-arent-iso-format">What If Your Dates <em>Aren't</em> ISO Format?</h2>
<p>Let's say your dates are in <code>MM/DD/YYYY</code> format. Those strings aren't lexicographically sortable, so you'll need to transform them first.</p>
<h3 id="heading-transform-then-sort">Transform <em>then</em> Sort</h3>
<pre><code class="language-JavaScript">console.time('sort_with_iso_conversion_first');

const sortedByISO = mdyArray
  .map((item) =&gt; { // First convert to ISO format
    const [month, day, year] = item.date.split('/');
    return { date: `\({year}-\){month}-${day}`, value: item.value };
  })
  .sort((a, b) =&gt; (a.date &gt; b.date ? 1 : -1)); // then sort

console.timeEnd('sort_with_iso_conversion_first');
</code></pre>
<p>Output:</p>
<pre><code class="language-Bash">sort_with_iso_conversion_first: 58.8779296875 ms
</code></pre>
<p>Still perceived as instantaneous.</p>
<h3 id="heading-retaining-original-objects">Retaining Original Objects</h3>
<p>If you want to keep your original objects (with non-ISO dates), you can use tuples:</p>
<pre><code class="language-JavaScript">console.time('sort_and_preserve_original');

// Create tuples: [sortableDate, originalObject]
const sortedWithOriginal = mdyArray
  .map((item) =&gt; {
    const [month, day, year] = item.date.split('/');
    return [`\({year}-\){month}-${day}`, item]; // return the tuple items
  })
  .sort((a, b) =&gt; a[0] &gt; b[0] ? 1 : -1) // sort based on the first item
  .map(([, item]) =&gt; item); // Return the original object

console.timeEnd('sort_and_preserve_original');
</code></pre>
<p>Output:</p>
<pre><code class="language-Bash">sort_and_preserve_original: 73.733154296875 ms
</code></pre>
<p>Still within the boundaries of being perceived as instantaneous.</p>
<p>The original data is preserved and the performance falls well within what is perceived as instantaneous.</p>
<h2 id="heading-key-takeaways">Key Takeaways</h2>
<ul>
<li><p><strong>Avoid object creation inside .sort()</strong>, especially for large arrays.</p>
</li>
<li><p><strong>ISO 8601 strings are lexicographically sortable.</strong> Use string comparison when you can.</p>
</li>
<li><p>If your date strings aren't sortable, <strong>map them to a sortable form first</strong>, sort, and optionally map them back.</p>
</li>
<li><p>Minor tweaks in sorting can yield <strong>massive performance gains</strong> – especially in UI components or real-time visualizations.</p>
</li>
</ul>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use React 19 in Power Apps PCF Components ]]>
                </title>
                <description>
                    <![CDATA[ The Power Apps Component Framework – PCF for short – lets you create complex custom components using traditional web development tools like HTML, CSS, and JavaScript. When creating a new PCF project,  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-react-19-in-pcf-components/</link>
                <guid isPermaLink="false">6830767c62d9a28c0de11007</guid>
                
                    <category>
                        <![CDATA[ powerapps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pcf ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 23 May 2025 13:22:04 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747861011004/173ecdcd-7bca-4c4f-967b-47616bd79a06.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Power Apps Component Framework – PCF for short – lets you create complex custom components using traditional web development tools like HTML, CSS, and JavaScript.</p>
<p>When creating a new PCF project, you can choose from two types of controls: <strong>standard controls</strong> and <strong>React virtual controls</strong>. For non-trivial components, React is often a good choice because it abstracts away much of the heavy DOM manipulation. But, when you’re using React with PCF, you’re currently limited to React 16 in Canvas apps and React 17 in Model-Driven apps.</p>
<p>That doesn’t mean you <em>can’t</em> use a newer version – but doing so means opting out of virtualization support. For many PCF components, that trade-off is usually acceptable.</p>
<p>In this article, I’ll show you how to integrate the latest version of React (v19) with your PCF component. We’ll install the necessary dependencies and configure the component to take full advantage of the latest version of React.</p>
<h3 id="heading-this-article-assumes-that-you">This article assumes that you:</h3>
<ul>
<li><p>Understand how to use the PAC CLI to create PCF projects.</p>
</li>
<li><p>Are comfortable using the command line and a code editor (for example, VS Code)</p>
</li>
<li><p>Know the basics of React</p>
</li>
<li><p>Have some experience with PCF development</p>
</li>
</ul>
<p>Note: You don’t need access to a Power Platform environment unless you want to deploy the component. The built-in test harness will be sufficient to follow along with this article.</p>
<h3 id="heading-in-this-tutorial-you-will">In this tutorial, you will:</h3>
<ul>
<li><p><a href="#heading-create-a-pcf-project">Create a PCF Project</a></p>
</li>
<li><p><a href="#heading-install-the-react-dependencies">Install the React Dependencies</a></p>
</li>
<li><p><a href="#heading-create-a-non-react-button">Create a Non-React Button</a></p>
</li>
<li><p><a href="#heading-create-a-react-button">Create a React Button</a></p>
</li>
<li><p><a href="#heading-add-the-react-button-to-the-pcf-component">Add the React Button to the PCF Component</a></p>
</li>
<li><p><a href="#heading-render-the-react-button-when-the-pcf-component-updates">Render the React Button When the PCF Component Updates</a></p>
</li>
</ul>
<h2 id="heading-create-a-pcf-project">Create a PCF Project</h2>
<p>To create a PCF project, you’ll use the <strong>PAC CLI</strong>. If you haven’t installed it yet, follow the instructions <a href="https://learn.microsoft.com/en-us/power-platform/developer/cli/introduction?tabs=windows">here</a>.</p>
<p>From the directory of your choice, create a new folder for this project, and then open your terminal and run:</p>
<pre><code class="language-bash">pac pcf init -ns SampleNameSpace -n SampleComponent --template field
</code></pre>
<p>Once it finishes, run:</p>
<pre><code class="language-bash">npm install
</code></pre>
<p>This installs the default project dependencies.</p>
<p>So why didn’t we use the <code>--framework</code> flag to specify React during project creation? Because that flag sets up a React virtual control, which only supports React 16/17. Instead, we’re creating a standard control and installing React ourselves.</p>
<h2 id="heading-install-the-react-dependencies">Install the React Dependencies</h2>
<p>To use React 19, you’ll need four dependencies:</p>
<ul>
<li><p><code>react</code></p>
</li>
<li><p><code>react-dom</code></p>
</li>
<li><p><code>@types/react</code></p>
</li>
<li><p><code>@types/react-dom</code></p>
</li>
</ul>
<p>These last two provide TypeScript typings for React. Install the above dependencies with:</p>
<pre><code class="language-bash">npm install -D react react-dom @types/react @types/react-dom
</code></pre>
<p>You can verify the installation by looking at the <code>package.json</code> file in the project.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747410603816/a7eeeb60-dcbe-49c9-9913-6319cd246333.png" alt="The package.json file showing the react dependencies installed." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>While not necessary for what we will be doing, in order to use some newer React features, you may need to tweak the <code>compilerOptions</code> in the <code>tsconfig.json</code> file to include the line below:</p>
<pre><code class="language-json">"jsx": "react-jsx"
</code></pre>
<p>Here is what the <code>tsconfig.json</code> file should look like with the added <code>jsx</code> line:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747410782472/524ac9a6-3898-4427-8bab-090fe0a3f718.png" alt="524ac9a6-3898-4427-8bab-090fe0a3f718" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-create-a-non-react-button">Create a Non-React Button</h2>
<p>Let’s verify that everything works before we introduce React.</p>
<p>From the command line, run:</p>
<pre><code class="language-bash">npm run start:watch
</code></pre>
<p>This may take a moment. It will open a browser showing your PCF test harness. You’ll likely see an empty screen. That’s expected – we haven’t rendered anything yet.</p>
<p>Open <code>index.ts</code> in the <code>SampleComponent</code> folder. This file contains a class that implements the PCF standard control interface. Let’s create a basic non-React button.</p>
<p>Update the <code>init</code> method in the <code>index.ts</code> file like this:</p>
<pre><code class="language-typescript">public init(
    context: ComponentFramework.Context&lt;IInputs&gt;,
    notifyOutputChanged: () =&gt; void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
): void {
    // A basic button with vanilla JS and the DOM
    const btn = document.createElement('button');
    btn.textContent = 'Click me!';
    container.appendChild(btn);

    // A simple event lister for button clicks
    btn.addEventListener('click', () =&gt; {
        alert('Button clicked!');
    });
}
</code></pre>
<p>Now, head back to your test harness. You should see a button. Clicking it should display an alert.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747411524929/36d26f79-1d48-403c-9005-56655a16ed04.png" alt="PCF test harness with clickable button." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747411544199/85aab788-1a02-439c-8597-d74d6fa3a39c.png" alt="PCF test harness with alert displayed after button was clicked." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-create-a-react-button">Create a React Button</h2>
<p>Next, let’s replace our plain DOM code with React.</p>
<p>Delete the button code from <code>init()</code>, leaving the <code>init</code> method empty.</p>
<p>Then, create a new file: <code>Button.tsx</code>. Inside <code>Button.tsx</code>, add the code below. This component will accept a label prop and emit an <code>onClick</code> event. Make sure to export the function.</p>
<pre><code class="language-typescript">export default function Button(props: { label: string; onClick: () =&gt; void }) {
    return &lt;button onClick={props.onClick}&gt;{props.label}&lt;/button&gt;;
}
</code></pre>
<h2 id="heading-add-the-react-button-to-the-pcf-component">Add the React Button to the PCF Component</h2>
<p>In <code>index.ts</code>, update the file to:</p>
<ol>
<li><p>Import <code>createRoot</code> from <code>react-dom/client</code></p>
</li>
<li><p>Import the <code>Button</code> component</p>
</li>
<li><p>Render the <code>Button</code> component</p>
</li>
</ol>
<p>Here is the minimal example:</p>
<pre><code class="language-typescript">import { createRoot } from 'react-dom/client'; // import the createRoot method
import Button from './Button'; //import the button.tsx component we just created

export class SampleComponent
    implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt;
{
    constructor() {
        // Empty
    }
    public init(
        context: ComponentFramework.Context&lt;IInputs&gt;,
        notifyOutputChanged: () =&gt; void,
        state: ComponentFramework.Dictionary,
        container: HTMLDivElement
    ): void {
        // Add the code below to create a React root that allows us to render our button component.
        const root = createRoot(container);
        root.render(
            Button({ label: 'React Button', onClick: () =&gt; alert('React Button Clicked!') })
        );
    }
    // Other methods here...
}
</code></pre>
<p>You should now see “React Button” in the browser. Clicking it will trigger the alert.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747412200377/ef496e75-de8f-4abe-8371-25dd295ee057.png" alt="PCF test harness with the React button" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747412239139/d4c73764-667f-445c-9366-aa270e456d13.png" alt="PCF test harness with alert displayed after the React buttons was clicked." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-render-the-react-button-when-the-pcf-component-updates">Render the React Button When the PCF Component Updates</h2>
<p>Many PCF components receive dynamic input values. If the inputs change, we want the React component to re-render. This is where <code>updateView()</code> comes in. <code>updateView()</code> is triggered when the PCF property bag changes.</p>
<p>Let’s move the rendering logic from <code>init()</code> to <code>updateView()</code>.</p>
<p>First, import <code>Root</code> from <code>react-dom/client</code>, and initialize <code>root</code> as a property of the class.</p>
<pre><code class="language-typescript">import { createRoot, Root } from 'react-dom/client'; //add Root as an import

export class SampleComponent implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt; {
    root: Root; // initialize the root property on the SampleComponent class
    constructor() {
        // Empty
    }
    // other methods here...
}
</code></pre>
<p>Then, modify <code>init()</code> to set <code>this.root</code> to the root created by React’s <code>createRoot</code> method. Move the rendering logic from the <code>init</code> method to <code>updateView()</code>, replacing <code>root</code> with <code>this.root</code>.</p>
<pre><code class="language-typescript">public init(
    context: ComponentFramework.Context&lt;IInputs&gt;,
    notifyOutputChanged: () =&gt; void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
    ): void {
        this.root = createRoot(container); // assign the root React creates to this.root
    }

public updateView(context: ComponentFramework.Context&lt;IInputs&gt;): void {
    // render the React button component, by referencing this.root
    this.root.render(
        Button({ label: 'React Button', onClick: () =&gt; alert('Button Clicked!') })
    );
}
</code></pre>
<p>With the above setup, React will now re-render your button when the property bag of a PCF component changes.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You’ve now created a PCF component that uses the latest version of React! By installing and configuring React manually, you avoid the version limitations of Microsoft’s built-in React controls – unlocking the power of modern React features.</p>
<p>While this setup doesn’t support virtualization, for many components that’s a fair trade-off for modern tooling and maintainability.</p>
<p>If you’re building PCF components beyond simple DOM manipulation, React can be a powerful way to improve your development workflow and UI flexibility.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Extend Power Apps with Reusable Components ]]>
                </title>
                <description>
                    <![CDATA[ If you have experience in traditional software development, low-code tools may feel a bit sparse at first. But to many people’s surprise, traditional techniques often translate quite well to low-code  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/powerapps-component-crash-course/</link>
                <guid isPermaLink="false">682779afad5694b25984f6b1</guid>
                
                    <category>
                        <![CDATA[ Canvas PowerApps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Low Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 16 May 2025 17:45:19 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747410099474/8471a651-503f-4ced-a172-7dadac930039.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you have experience in traditional software development, low-code tools may feel a bit sparse at first. But to many people’s surprise, traditional techniques often translate quite well to low-code development. Not always one-for-one – but usually close enough.</p>
<p>One of the most fundamental tasks when building an application is breaking it down into its core parts, or components. Websites are constructed from smaller building blocks. Just how small? Well, that’s up to you, the developer.</p>
<p>In the example below, we can spot some obvious elements: a header, a search box, perhaps a sidebar for navigation, and a main content area. Applications emerge from many smaller parts coming together.</p>
<img src="https://www.scriptedbytes.com/content/images/2025/05/components.png" alt="Image of components of a website" width="600" height="400" loading="lazy">

<p>Components allow us to isolate responsibility and manage complexity for specific parts of an application. In both traditional and low-code development, they play a vital role in creating maintainable, reusable, and testable products.</p>
<p>In this article, you’ll learn what a component is. Then we’ll build a custom text field component inside a Canvas app.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>This tutorial assumes a basic understanding of Microsoft Power Apps. While not required to understand the article, to actively follow along, you’ll need access to a Power Platform environment with the App Maker security role.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a href="#heading-the-concept-of-a-component">The Concept of a Component</a></p>
</li>
<li><p><a href="#heading-how-to-build-your-own-component">How to Build Your Own Component</a></p>
</li>
<li><p><a href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-the-concept-of-a-component">The Concept of a Component</h2>
<p>The idea of components isn’t new – and it’s not exclusive to software.</p>
<p>Let’s think about a car for a moment. A car is made up of many smaller parts: wheels, an engine, seats, a steering wheel, and so on. But it’s the concept of the car – and specifically its ability to transport us – that provides value. That concept emerges from the way the individual parts work together.</p>
<p>Now imagine you get a flat tire. Not a good day. But thanks to how cars are designed, you don’t need a whole new car – maybe not even a new tire. You fix the issue and you’re back on the road within a few hours. Breaking things into smaller parts helps make the whole system more resilient. Applying this same principle to application development is a smart, future-proof approach.</p>
<h3 id="heading-two-broad-types-of-components">Two Broad Types of Components</h3>
<p>Within an application, components can vary in complexity and responsibility. Some are simple, like a text label. Others are more complex, like a pop-up dialog. Regardless of their complexity (again, your design choice), components typically fall into one of two categories:</p>
<ul>
<li><p><strong>Presentational ("Dumb") Components</strong></p>
</li>
<li><p><strong>Container ("Smart") Components</strong></p>
</li>
</ul>
<p>The difference comes down to purpose. A container component may interact with external sources and usually mutates state. A presentational component, on the other hand, is generally only responsible for how things look and light communication with the application.</p>
<p>Container components are often more complex and harder to test. Presentational components are typically simpler and more predictable.</p>
<p>This isn’t to say you should avoid container components. That’s not realistic. At some point, your app will need to talk to the outside world.</p>
<h3 id="heading-aside-pure-functions">Aside: Pure Functions</h3>
<p>The concept of <strong>pure functions</strong> is useful here.</p>
<p>A function is considered <em>pure</em> if it always returns the same output for the same input and doesn’t interact with any external state.</p>
<pre><code class="language-JavaScript">// Example 1 (pure)
function add(x, y) {
  return x + y;
}

console.log(add(2, 3)); // Always 5

// Example 2 (not pure)
function subtract(x) {
  const y = Math.floor(Math.random() * 100) + 1; // Random number between 1 - 100
  console.log(y);
  return x + y;
}

console.log(subtract(5)); // Unpredictable
</code></pre>
<p>Just like <code>add()</code> is pure and <code>subtract()</code> is not, a presentational component behaves like a pure function: same input, same output. The output might be how the UI appears or an event with associated data.</p>
<h3 id="heading-more-about-inputs-and-outputs">More About Inputs and Outputs</h3>
<p>If you’ve built a Canvas App before, you’ve already used components – even if you didn’t realize it. Most controls in a Canvas App are presentational components.</p>
<p>Take the <strong>Label</strong> control. It receives an input (<code>Text</code>) and renders output (the text on screen).</p>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_37f5d6fa.png" alt="Image of Canvas App label" width="600" height="400" loading="lazy">

<p>Events are another kind of output. For example, the <strong>Button</strong> control emits an event when clicked – handled through the <code>OnSelect</code> property. That property allows the app to respond to the click and perform some logic.</p>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_37fa1150.png" alt="Image of Canvas app button" width="600" height="400" loading="lazy">

<p>💡 When a component sends a message back to the application the component is said to have <em>emitted an event.</em></p>
<p>Now let’s look at the <strong>Text Input</strong> control.</p>
<p>Like the others, it has inputs (like <code>Placeholder</code>). But it also emits a <code>Change</code> event via <code>OnChange</code>. Even better, it passes data back to the application through its <code>Value</code> property. As the user types, the value updates. That value is how we access what they typed.</p>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_38070a2d.png" alt="Image of Canvas app text input" width="600" height="400" loading="lazy">

<h2 id="heading-how-to-build-your-own-component">How to Build Your Own Component</h2>
<p>Let’s build a simple, customized input component. It will include:</p>
<ul>
<li><p>A label above the input</p>
</li>
<li><p>Optional “required” validation</p>
</li>
<li><p>Change detection and data output</p>
</li>
</ul>
<p>Here is what it will look like:</p>
<img src="https://www.scriptedbytes.com/content/images/2025/05/image.png" alt="Image of custom text field to be built" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h3 id="heading-part-1-create-the-component">Part 1: Create the Component</h3>
<ol>
<li><p>Navigate to the <strong>Components</strong> section of your Canvas App.</p>
</li>
<li><p>Add a new component and name it <code>cmp_baseInput</code>.</p>
</li>
<li><p>Resize it to 340 (w) x 100 (h).</p>
</li>
</ol>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_3819d94d.png" alt="Image of how to create a component" width="600" height="400" loading="lazy">

<h3 id="heading-part-2-add-controls">Part 2: Add Controls</h3>
<ol>
<li><p>Add a <strong>Text Input</strong> control, centered.</p>
</li>
<li><p>Add two <strong>Labels</strong>—one above, one below the input.</p>
</li>
<li><p>Rename them:</p>
<ul>
<li><p><code>lbl_label</code></p>
</li>
<li><p><code>lbl_hint</code></p>
</li>
<li><p><code>txt_textField</code></p>
</li>
</ul>
</li>
</ol>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_381d4ce8.png" alt="Image of the appropriate controls added to the component" width="600" height="400" loading="lazy">

<h3 id="heading-part-3-add-custom-properties">Part 3: Add Custom Properties</h3>
<p>Add four properties to the component. We're primarily concerned with the Property Type, Property Definition, and Data Type properties.</p>
<ul>
<li><p><code>IsRequired</code> (Data, Input, Boolean)</p>
</li>
<li><p><code>Label</code> (Data, Input, Text)</p>
</li>
<li><p><code>Value</code> (Data, Output, Text)</p>
</li>
<li><p><code>OnChange</code> (Event)</p>
</li>
</ul>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_38262956.png" alt="Image of custom properties added to the component" width="600" height="400" loading="lazy">

<h3 id="heading-part-4-connect-the-properties">Part 4: Connect the Properties</h3>
<p>Set the control's properties as follows.</p>
<pre><code class="language-plaintext">lbl_label.Text = cmp_baseInput.Label

lbl_hint.Text = "This field is required."
lbl_hint.Visible = cmp_baseInput.IsRequired And Len(txt_textField.Value) &lt; 1

txt_textField.OnChange = cmp_baseInput.OnChange()

cmp_baseInput.Value = txt_textField.Value
cmp_baseInput.Label = "Placeholder Label"
</code></pre>
<h3 id="heading-part-5-style-it">Part 5: Style It</h3>
<pre><code class="language-plaintext">lbl_label.Size = 12
lbl_label.Height = 24
lbl_label.FontColor = RGBA(122, 138, 143, 1)

lbl_hint.Size = 10
lbl_hint.Height = 24
lbl_hint.FontColor = RGBA(215, 58, 60, 1)
lbl_hint.FontWeight = 'TextCanvas.Weight'.Semibold
</code></pre>
<h3 id="heading-part-6-add-it-to-the-app">Part 6: Add It to the App</h3>
<ol>
<li><p>Go back to the application screen.</p>
</li>
<li><p>Insert the component and name it <code>cmp_userName</code>.</p>
</li>
<li><p>Add a label nearby and set its text to:<br><code>"The user name is: " &amp; cmp_userName.Value</code></p>
</li>
</ol>
<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_3835242d.png" alt="Image of inserting the component in the application" width="600" height="400" loading="lazy">

<img src="https://www.scriptedbytes.com/content/images/2025/05/Snag_383a4039.png" alt="Image of the component inserted into the application" width="600" height="400" loading="lazy">

<h3 id="heading-part-7-test-it">Part 7: Test It</h3>
<ul>
<li><p>Type in the component and click outside of it → label near the component updates and the hint disappears.</p>
</li>
<li><p>Clear the text → hint reappears</p>
</li>
<li><p>Set <code>IsRequired</code> to false → hint disappears</p>
</li>
<li><p>Set <code>OnChange</code> to <code>Notify("A change occurred!")</code> and type in the input→ a toast message appears with you notification.</p>
</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You’ve just created a functional, presentational component. It handles labels, validation, value output, and even events – all in one package.</p>
<p>This is the real power of components: abstraction, clarity, and reusability. Whether you're in a traditional or low-code environment, thinking in components helps you break complexity into manageable parts.</p>
<p>As your apps grow, this mindset will pay off. You'll spend less time rewriting logic and more time building value – one well-defined part at a time.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
<p><em>Stay curious and keep building.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Successful Low-Code Apps: The Power of Knowledge Transfer in Development Teams ]]>
                </title>
                <description>
                    <![CDATA[ Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to ge ]]>
                </description>
                <link>https://www.freecodecamp.org/news/low-code-knowledge-transfer/</link>
                <guid isPermaLink="false">66d87a73191c724ea0c7ef03</guid>
                
                    <category>
                        <![CDATA[ Low Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Wed, 04 Sep 2024 15:19:15 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724883531478/4fa7979a-e61a-4268-94dc-a48dfcf17b4b.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to get started. Developers can also quickly release new applications into the wild.</p>
<p>But as this happens, questions arise, such as who supports these applications? And who will make the updates if there is a feature request or bug?</p>
<p>Many low-code applications are often created by a single developer, inherently leading to a single point of failure.</p>
<p>And don't let the advertised simplicity of low-code trick you into thinking anyone can edit the app, fix any issues, and add new features. Low code can still contain complexity, and complex solutions can quickly become a problem for organizations and teams that leverage dozens, if not hundreds, of other low- or non-low-code dependencies.</p>
<p>This doesn't mean that organizations should strictly restrict who can create these applications. Doing so would contradict the very purpose of low code. It's a model that empowers stakeholders themselves to rapidly prototype ideas and develop low-cost solutions to problems that, in traditional development, might cost millions of dollars.</p>
<p>In this low-code world, both organizations and developers need a plan. Developers, specifically, should have a plan to transfer knowledge of their products, whether working in a team or independently.</p>
<h2 id="heading-how-to-simplify-complexity">How to Simplify Complexity</h2>
<p>Our relatively small team has created numerous low-code solutions, primarily leveraging Microsoft's suite of products. Some of these solutions are simple low-code canvas apps, while others contain hundreds of dependencies that are anything but low-code.</p>
<p>We've learned, sometimes the hard way, the importance of ensuring maintainability in our development. This means supporting the applications we build and enabling existing and new team members to support them in the future.</p>
<p>Initially, we found ourselves drawn to the premise of being able to create products that solve problems quickly. Before we knew it, we had our own problem: how do we support the array of these products, ensuring that not just us but new team members could do so as well?</p>
<h3 id="heading-slow-down-to-speed-up">Slow Down to Speed Up</h3>
<p>This might sound contrary to the low-code paradigm, but taking frequent pauses to consider the long-term impacts of your decisions is critical to ensuring the tools you build today can be supported tomorrow.</p>
<p>This does not mean reverting back to the speeds of traditional software development, but you should not consider building low-code products as a race to the finish line.</p>
<h3 id="heading-pair-programming">Pair Programming</h3>
<p>Incorporating traditional software development practices can significantly benefit the low-code movement. Even if your applications involve little to no conventional code, concepts like pair programming can be effectively applied when building low-code products.</p>
<p>Take, for example, the process of building a Power App. Traditionally, only one person could edit an app at a time. Although that limitation has changed—multiple people can now edit an app simultaneously—defining a collaborative process remains crucial.</p>
<p>Our team often employs a primary "driver" approach, where one member leads the development while another observes, providing real-time feedback and suggestions.</p>
<p>This method keeps everyone engaged and helps mitigate the effects of tunnel vision on the product. And this collaborative approach is especially valuable for more complex aspects of the application.</p>
<p>For more straightforward tasks, we often work in parallel but stay closely connected via Teams or Zoom, ready to coordinate and ensure each different component is part of a cohesive whole.</p>
<h3 id="heading-applicationcode-reviews">Application/Code Reviews</h3>
<p>Low code doesn't mean no code. It is challenging to create robust applications with drag-and-drop alone. Even something like Power Apps has its own language called Power FX.</p>
<p>Schedule time each week to walk through or review others' applications to become familiar with their creations. Look for places where things can be improved, and be ready to accept feedback on your creations, too.</p>
<p>If you're using traditional code in your project, some of this can be accomplished with PRs. For purely low-code implementations, keep a document of changes and have a sign-off process to ensure other team members can access new changes.</p>
<p>For example, imagine adding a new screen to a Canvas app, allowing users to update personal settings. That change should be documented as unreviewed until at least one other team member has reviewed and signed off on this new feature.</p>
<h3 id="heading-get-other-team-members-involved">Get Other Team Members Involved</h3>
<p>If you're on a team, each product should involve at least two people to avoid single points of failure. Ensure each product has a primary and secondary developer or product owner. For larger teams, allow that secondary role to rotate, ensuring each member is more intimately involved with the team's products.</p>
<p>One way to get others involved and up to speed is to have other team members add new features or fix bugs in existing products under the guidance of the primary or lead developer. This knowledge transfer will help cultivate ownership in the various products your team supports, leading to higher engagement and motivation.</p>
<p>Additionally, as the workload is distributed more evenly across the team, bottlenecks are reduced, allowing for more expeditious handling of fixing bugs and enhancing products.</p>
<h2 id="heading-when-a-hands-on-approach-isnt-possible">When a Hands-On-Approach isn't Possible...</h2>
<p>Much of what I describe above is an attempt to get others involved with projects. The more we touch these things, the better we will understand them.</p>
<p>Inevitably, however, when this hands-on experience isn't possible, it is essential to have practices that can mitigate the effects of isolated development—that is, a development done by one or just a few people.</p>
<p>The two most important things we can do are create and maintain comprehensive documentation about our products and use standard practices as much as possible. We'll talk about documentation first.</p>
<h3 id="heading-document-document-document">Document, Document, Document</h3>
<p>As you've probably experienced, the low-code movement allows applications to be created quickly. The more applications exist, the fewer touchpoints we have with older ones. While those touchpoints are critical to the knowledge transfer process, relying on them alone isn't enough.</p>
<p>Whether you're on a team or a solo developer, creating documentation that describes each aspect of your products is critical. For small projects, this may be a simple text document. For larger projects, you could utilize a SharePoint site. Of course, as products become even more complex, the various dependencies will likely have their own documentation (for example, Git repositories).</p>
<p>Here is an example of how you might document a product you are building:</p>
<p>Let's say you have an application that allows users to reserve a conference room for meetings. That application consists of a user interface (such as a Canvas app) and custom code that creates a follow-up reminder for the person who reserved the meeting a day before. This reminder could send an email to remind the user about the meeting, and if the meeting is no longer occurring, encourage them to cancel the reservation. Finally, this product could also have a reporting element, where administrators can see conference room utilization over time to better understand demand.</p>
<p>Here is how you might document this project:</p>
<ol>
<li><p>Establish a single source of truth about this project, such as a SharePoint page.</p>
</li>
<li><p>This page briefly describes the project, the product owners, and the lead developers.</p>
</li>
<li><p>The page would also briefly describe this project's components (Canvas app, custom code, and reporting dashboard).</p>
</li>
<li><p>Finally, you would include documentation on any easy-to-overlook aspects or non-standard project implementations (more on standardization later).</p>
</li>
</ol>
<p>The SharePoint page handles the high-level overview of the project and gets you pointed in the right direction. Regarding the individual components, the Canvas app will include comments and notes in the version history, and your custom code will leverage Git and often include a detailed readme.</p>
<p>Documentation can be challenging, but it is critical. While documentation should be comprehensive, it should complement the hands-on knowledge transfer techniques described above.</p>
<h3 id="heading-standardize-as-much-as-possible">Standardize as Much as Possible</h3>
<p>Whether it is low-code or traditional development, it is important to have standard practices. This is even more important when talking about low code because of the speed at which things can be developed and potentially get out of control.</p>
<p>From project planning, design, development, and testing to cross training team members, make time to create standard practices for each phase.</p>
<p>Standardization shouldn't be considered a way to eliminate the need for cross-training and documentation but rather a way to complement those stages and reduce the time needed in those areas.</p>
<p>If you can approach a problem the same way every time, you can spend time discussing those non-standard and easy-to-forget parts of what you're building.</p>
<p>Here are some questions to get you started:</p>
<ol>
<li><p>What big-picture steps will each application require? Who will be involved in those steps?</p>
</li>
<li><p>What tools will you use? (for example, Power Apps, Appian, Pega)</p>
</li>
<li><p>Can you support traditional development? If so, how will that look?</p>
</li>
<li><p>What is your philosophical approach to development? For example, should you design the user interface or business logic first? What database will you use? (for example, SharePoint or Dataverse)</p>
</li>
<li><p>What conventions will you use in your code? (for example, naming conventions for screens and variables)</p>
</li>
<li><p>What does this knowledge transfer or cross-training process look like? Do you have dedicated times each week to review each other's work?</p>
</li>
</ol>
<p>Of course, this list goes on. The more you learn, the more you'll realize what needs to be discussed. Get started by creating a Standard Operating Procedure (SOP), and be prepared to edit it early and often.</p>
<h2 id="heading-what-if-i-am-a-solo-developer">What if I am a Solo Developer?</h2>
<p>If you're a solo developer, it may be easy to think that the recommendations above don't apply. But this couldn't be further from the truth. Creating and maintaining a knowledge-transfer framework is even more critical as a solo developer. While co-developing and pair programming are not directly applicable, the concepts still apply.</p>
<p>For example, take time to meet other developers and ask for feedback. At a minimum, it will be an excellent way to meet other people doing the same thing. And, of course, with AI taking a front row in programming, you can always leverage AI to help you learn new techniques and optimize the things you are building.</p>
<p>Finally, documentation and standard practices are just as necessary for the individual developer. First, if you ever work with others, you'll have a reference for your work. Second, these things will act as an external reminder of how you intend to solve development-related problems in the future.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>While low-code platforms offer incredible speed and flexibility, they can also introduce challenges when it comes to maintenance. Rapid development, if not managed carefully, can lead to issues that undermine the long-term success of your applications.</p>
<p>But by intentionally slowing down and establishing a clear plan for knowledge transfer, you can safeguard the future of your critical products. This approach ensures that applications remain supported and sustainable, both now and for years to come.</p>
<p>Stay curious.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is NodeJS? The JavaScript Engine and Runtime Explained for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Every year another something JS enters the development sphere. With names such as VueJS, NextJS, and AngularJS, you may be under the impression that NodeJS is a JavaScript framework. Or you've heard t ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-node-js-explained/</link>
                <guid isPermaLink="false">66d461823dce891ac3a96844</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Mon, 17 Jul 2023 14:46:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-sevenstorm-juhaszimrus-443383--2-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every year another <em>something JS</em> enters the development sphere. With names such as VueJS, NextJS, and AngularJS, you may be under the impression that NodeJS is a JavaScript framework. Or you've heard that NodeJS is a language. But neither of those statements is accurate.</p>
<p>To define NodeJS, we will take a step back and look at how JavaScript works and discuss three components that play a significant role in JavaScript:</p>
<ol>
<li><p>The language itself</p>
</li>
<li><p>The JavaScript engine</p>
</li>
<li><p>The JavaScript runtime</p>
</li>
</ol>
<h2 id="heading-the-javascript-language-itself">The JavaScript Language Itself</h2>
<p>JavaScript is a programming language based on ECMAScript. You may also hear it referred to as a dialect or implementation of the ECMAScript language standard.</p>
<p>A language standard contains a set of rules for how a language should behave. Dialects, on the other hand, are implementations of a language standard. Much like there are regional dialects of the English language, JavaScript is a dialect—the most popular dialect—of ECMAScript.</p>
<p>Before 2008, developers only used JavaScript to manipulate web pages. But the inability to use JavaScript outside the browser was not a limitation of JavaScript, the language, but a constraint of where this JavaScript code was being executed.</p>
<h2 id="heading-what-is-the-javascript-engine">What is the JavaScript Engine?</h2>
<p>Before we touch on where JavaScript is executed, we will briefly touch on how.</p>
<p>There are compiled languages and interpreted languages. A compiled language is like a prepared meal. All the ingredients have been mixed, organized, and arranged into something that only needs to be cooked. They've been checked beforehand to ensure they meet the standard for that meal.</p>
<p>An interpreted language, on the other hand, is like a hibachi chef performing their artistry on the grill as you watch. They prepare your meal in real-time, make adjustments on the fly, and incorporate their unique skills and techniques to create the final dish.</p>
<p>In the realm of JavaScript interpretation, a JavaScript engine takes on the role of the hibachi chef, executing the code and bringing it to life on the digital grill.</p>
<p>As much as it may seem like an improvisational act, the JavaScript engine still implements specific rules, ensuring consistency when executing your code. (Recall many of these rules come from the ECMAScript language standard).</p>
<p>But it may surprise you that much of what is written by a web developer will be found nowhere in the ECMAScript standard.</p>
<p>You see, the DOM, for example, is part of an "outside world." And ECMAScript has no specifications about how JavaScript should interact with this outside world. These rules come from somewhere else—the JavaScript runtime.</p>
<h2 id="heading-what-is-a-javascript-runtime">What is a JavaScript Runtime?</h2>
<p>A runtime is a place or environment where your code executes. It is <em>not</em> the thing running the code itself (this is the engine) but rather an environment that provides access to certain parts of the outside world.</p>
<p>Imagine your code is a person inside of a house. Different rooms will have different windows which allow this person to see different parts of what is outside. The outside doesn't change, but the room that the person is in will determine what they can see. This is the essence of what a JavaScript runtime is. It is like a room that you can place your code within. And just like the person inside of the house, the room your code is in will determine which parts of the outside world it has access to.</p>
<p>The most common JavaScript runtime is the browser. And for the browser, the parts of the outside world it allows you to see (interact with) with are the Window object and, subsequently, the document object, or DOM.</p>
<p>These objects are critical for web developers because they provide the necessary APIs that allow your JavaScript to interact with web pages. Adding a</p>
<p>, updating some inner HTML text, or listening to window-based events are all thanks to the Web API provided by the browser runtime.</p>
<h2 id="heading-so-what-is-nodejs">So What is NodeJS?</h2>
<p>By now, you may have an idea of what NodeJS is. Node is a JavaScript runtime. It's not a language or a framework. It's simply an environment that allows you to write JavaScript that interacts with different parts of the outside world other than the browser.</p>
<p>Instead of providing things like the Web API, it provides APIs to interact with components such as the file system, HTTP, and the operating system.</p>
<h2 id="heading-how-node-works">How Node Works</h2>
<p>Let's look at an example of what Node can do. You may need to install Node first. The easiest way to install it is to visit NodeJS.org and download the LTS (Long-Term Support) version.</p>
<p><em>Node JS org home screen displaying download options</em></p>
<p>We can check to ensure that it is installed correctly by opening a command line or terminal prompt and typing <code>node -v</code>.</p>
<pre><code class="language-js">node -v
&gt; v18.16.0
</code></pre>
<p>Let's run our first command in Node. In a terminal window, start the Node REPL by typing in <code>node</code> and pressing enter.</p>
<p>Once the REPL has started, we can run our first JavaScript commands within the Node runtime. Let's type <code>console.log(1 + 1)</code>:</p>
<pre><code class="language-js">console.log(1+1)
&gt; 2
</code></pre>
<p>Running commands in the REPL is great for demo purposes, but Node wouldn't be beneficial if that were the only place you could interact with the Node runtime. Fortunately, we can also create JavaScript files and run them with Node.</p>
<p>Let's create a JavaScript file named <em>main.js.</em> Add a console.log statement and display a message of your choice. Here is what I've created:4</p>
<pre><code class="language-js">onst msg = 'Hello, World! Here is a message from main.js'

console.log(msg
</code></pre>
<p>From your terminal (within the same directory where you saved the file), type <code>node main.js</code> and press enter. You should see something similar to the following:</p>
<pre><code class="language-js">node main.js
&gt; Hello, World! Here is a message from main.js!
</code></pre>
<p>Let's do one more thing with Node and build something more complex.</p>
<p>In this last example, we will leverage some built-in Node modules to create an HTML file and then serve that file all with JavaScript (within the Node runtime, of course!).</p>
<p>First, we will import three modules: FS, OS, and HTTP. These are core modules provided by Node JS.</p>
<pre><code class="language-js">const fs = require('fs');
const http = require('http);
const os = require('os');
</code></pre>
<p>Next, we will create the content that we will add to the index.html file we will create. We will get the operating system type of our machine and eventually populate our HTML file with that information.</p>
<pre><code class="language-js">// Get the OS type of our machine
osType = os.type();

// Create a string of HTML content for a file we will create
htmlContent = '&lt;html&gt;&lt;h3&gt;Hello, World! Your OS type is ${osType}&lt;/h3&gt;&lt;/html&gt;
</code></pre>
<p>Now that we have the content prepared for our HTML file, it's time to create the file. Most of what we do with Node JS will be writing asynchronous code. So for our example, we will use callback functions to run any code we want to ensure runs <em>after</em> our asynchronous code.</p>
<p>The next code to write will create the HTML file. We use the <code>fs</code> module and the <code>writeFile</code> method to do this. This function accepts a callback. We will use this callback to ensure the file has been created before we read the file and eventually create the server.</p>
<pre><code class="language-js">// Create an index.html file with the htmlContent variable as the content.
// Since this is async, we will provide a callback as a third argument
// that will run after the file has been created. It is in this callback that
// we will read the file. For code clarity, we won't handle errors.

fs.writeFile('./index.html', htmlContent, (err) =&gt; {
    const server = http.createServer((req, res) =&gt; {
        fs.readFile('.index.html', (err, content) =&gt; {
            res.setHeader('Content-Type', 'text/html');
            res.end(content);
        });
    });
}
</code></pre>
<p>We've created the file and prepared the server up to this point. But to serve the file, we need to start the server. We use the <code>listen</code> method on <code>createServer</code> to start the server. This function accepts several arguments. We will pass in a port number of 3000. So putting it all together:</p>
<pre><code class="language-js">const fs = require('fs');
const http = require('http);
const os = require('os');

// Get the OS type of our machine
osType = os.type();

// Create a string of HTML content for a file we will create
htmlContent = '&lt;html&gt;&lt;h3&gt;Hello, World! Your OS type is ${osType}&lt;/h3&gt;&lt;/html&gt;

// Create an index.html file with the htmlContent variable as the content.
// Since this is async, we will provide a callback as a third argument
// that will run after the file has been created. It is in this callback that
// we will read the file. For code clarity, we won't handle errors.

fs.writeFile('./index.html', htmlContent, (err) =&gt; {
    const server = http.createServer((req, res) =&gt; {
        fs.readFile('.index.html', (err, content) =&gt; {
            res.setHeader('Content-Type', 'text/html');
            res.end(content);
        });
    });
    server.listen(3000);
}
</code></pre>
<p>Now remember, this is just a JavaScript file. The file has the code to do everything we want to do, but we need to execute the script. Let's run the script and see what happens:</p>
<pre><code class="language-js">node main.js
&gt;
</code></pre>
<p>It may appear that the script is stuck or broken. Remember, however, that we've started a server. Until we cancel the script, the script is running, and it may appear that is the script has timed out.</p>
<p>Let's cancel the server (press <em>ctrl + c</em> twice), and then add a console.log to our <code>listen</code> method to help provide some feedback when the server is running. <code>listen</code> can accept a callback as the second argument. We will pass in a callback function to log some output.</p>
<pre><code class="language-js">server.listen(3000, () =&gt; {
    console.log('Listening on port 3000!');
});
</code></pre>
<p>Now, when we run the script we should see:</p>
<p>To run this file, change to the directory where the file is and run the following command:</p>
<pre><code class="language-bash">node main.js
&gt; Listening on port 3000!
</code></pre>
<p>The server is running. But where is our webpage?</p>
<p>Open a browser, enter <em>localhost:3000</em> for the URL, and hit enter. You should see something similar to this:</p>
<p><em>The content of the index.html file we have created and served with Node!</em></p>
<p>You've done it! You've created a straightforward web application and served it with NodeJS.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>JavaScript, the language, is written syntax executed by a JavaScript engine, which adheres to the rules set by the ECMAScript standard.</p>
<p>In addition to the language standard, the engine incorporates additional features for interacting with the outside world. The JavaScript runtime provides these features. The most common runtimes are the browser and Node, but there are others like Deno (similar to Node but offering additional features like native TypeScript support).</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Parallel Threads of Life and Programming ]]>
                </title>
                <description>
                    <![CDATA[ I’m convinced our deepest desire is, by paying the cost of time, to be shown a glimmer of some fundamental truth about the universe. To hear it whisper its lessons and point towards its purpose. And,  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-parallel-threads-of-life-and-programming-2/</link>
                <guid isPermaLink="false">66d4617f3dce891ac3a96842</guid>
                
                    <category>
                        <![CDATA[ Life lessons ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Sun, 23 Feb 2020 16:50:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/02/daria-sukhorukova-I51HSIo8k-4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I’m convinced our deepest desire is, by paying the cost of time, to be shown a glimmer of some fundamental truth about the universe. To hear it whisper its lessons and point towards its purpose.</p>
<p>And, if you look hard enough for these lessons, you will find them. Whether they are a manifestation of your mind or can be held in your hand, once you see them, they remain yours forever.</p>
<p>Programming offers significant parallels to life. We are tasked with creating something–something whose sum <em>feels</em> more significant than the parts. Like life, it is a test of bounded creativity. There are rules we <em>must</em> follow, some we <em>should</em> follow, and others we are free to ignore. Programming offers us a glimpse, however ephemeral it may be, into some fundamental truths about the world in which we reside.</p>
<h2 id="heading-the-four-parallels-between-programming-and-life">The Four Parallels Between Programming and Life</h2>
<h3 id="heading-iteration-is-progress">Iteration is progress.</h3>
<p>Did you know, if you started the month with a single penny and it doubled every day, you would have \(163 on the 15th of the month? Surely, you think, there must be a better way to make \)163 in 15 days. But, if you wait another 15 days, you would have more than 5 million dollars.</p>
<p>Go ahead, I’ll wait while you do the math.</p>
<p>In programming, we use the term <em>iterate</em> to indicate repeating something. In a more formal definition, it is repeatedly applying a procedure to the previous result of that procedure. For example, adding the numbers 1 and 1 to get 2, then adding 1 and 2 to get 3, and so forth.</p>
<p>When we iterate, we look for feedback. We wait for some condition to be met so we can either stop iterating or adjust <em>how</em> we are iterating. If we fail to listen for that feedback, we can get stuck in an infinite loop.</p>
<p>Life is no different. We often expect we can jump from point A to point B without ever defining what point A or point B is. And, even when we identify those points, we expect an immediate move from start to finish. Instead, what is often the truth, is we must incrementally make our way from beginning to end. We must listen for feedback that tells us where we are so we can make adjustments.</p>
<p>When we have goals, progress can often feel–for the first few days, weeks, or even months–non-existent. We’re often enticed to start over or start fresh. But in doing so, we fail to realize, while we might not have reached our destination, we are somewhere far past where we started. A complete restart isn’t necessary, we just need to make some minor adjustments.</p>
<p>Stop starting over. Let iteration be the force the creates progress.</p>
<h3 id="heading-most-complex-problems-are-collections-of-smaller-problems-that-have-already-been-solved">Most complex problems are collections of smaller problems that have already been solved.</h3>
<p>Even the most fascinating apps are a series of mostly mundane solutions to mundane problems. In fact, most of the solutions implemented within a program are nothing unique. It is the combination of those ordinary solutions that creates an extraordinary product.</p>
<p>In programming, there are different ways to use these quite-ordinary solutions. One way is through a term called <em>abstraction</em>. To abstract something is to move something away from something else.</p>
<p>In computer programming, when we abstract something, we are often building higher-level technology on top of lower-level technology. This makes it easier to work with lower-level technologies.</p>
<p>For example, most programming languages are <em>abstractions</em> of the enigmatic binary language (0s and 1s). They put a layer between us and some more fundamental, but cumbersome, level of interaction with the computer. These higher-level languages allow us to focus on higher-level problems.</p>
<p>Another way we can more efficiently solve problems is by using someone else’s solutions. You may have also heard the term <em>library</em>. And, while I am not speaking of a poorly lit, dusty, and quiet location where books live, it isn’t far off.</p>
<p>A <em>library</em>, in programming terms, is code that someone else wrote that solves routine problems. It also abstracts away those things which aren’t absolutely fundamental to solving whatever problem you have.</p>
<p>For example, if you are writing a program that requires someone to log in to use your application, you <em>could</em> write the code to encrypt and decrypt passwords yourself, <em>or,</em> you could use code written by someone else to do that for you. With the latter option, we free up time to focus on more significant problems our application is trying to solve.</p>
<p>All of us use abstractions and libraries in some shape or form. For example, the grocery store is an abstraction of producing our own food. A car is an abstraction of traveling on foot. An oven is an abstraction of building a fire. These are layers we place in front of us that allows us to allocate time to higher-level problems.</p>
<p>Reinvent the wheel only to learn how to make a wheel, not to drive to the store.</p>
<h3 id="heading-how-you-define-a-problem-is-how-you-will-solve-it">How you define a problem is how you will solve it.</h3>
<p>Recall the story of a truck that drove under a bridge and got stuck. Engineers spent hours trying to figure out how to move the bridge. A small child came up, face to face with the tires of the truck, and said, “what if you let the air out of the tires?”</p>
<p>From the child’s vantage point, the problem wasn’t the bridge was too short, but rather the truck was too tall.</p>
<p>Most people can solve any problem. In fact, most problems state the solution. For example, if the bridge is causing the issue, the answer is to do something with the bridge. If, however, the problem is that the truck is too tall, then the solution–almost glaringly obvious–is to make the truck shorter.</p>
<h3 id="heading-the-arrangement-of-parts-is-much-more-important-than-the-parts-themselves">The arrangement of parts is much more important than the parts themselves.</h3>
<p>What does the Google Maps codebase, the Declaration of Independence, Martin Luther King Jr.’s <em>I have a dream</em> speech, Steve Jobs’s 2005 commencement address, and my first app, <em>Hello, World</em> have in common?</p>
<p>The access to the same 26 letters of the English alphabet.</p>
<p>There is very little that is more fascinating to me than the written word. The written word is one of the most powerful <em>technologies</em> that emerged from humans.</p>
<p>Yes, I use the term <em>technology</em> because–even carved into the wall of a cave–it fundamentally changed how we persist information. No longer was data constrained within the boundaries of our minds.</p>
<p>While the purpose of the written word was initially linked to record-keeping, it quickly became a way to spread ideas. Some of these ideas would anger, and others inspire.</p>
<p>Every language (including computer language) has subtleties when transmitting information through writing or speech. The words and their constituent parts may be slightly different. Still, however, a language is a set of symbols that can be arranged into what seems to be an infinite number of ideas.</p>
<p>For example, in the English language, there are roughly 29 symbols that I can use to represent nearly my entire universe. I’ve mentioned the 26 letters, but it is also helpful to have access to periods, commas, and question marks.</p>
<p>Those 29 characters are available to you, me, and were available to Steve Jobs. Yet, each of us, throughout our lives, will follow different trajectories based on the combination of letters we chose to believe and speak into existence.</p>
<p>Interestingly, while we often add words to the dictionary, we don’t usually add letters. This means, at the most fundamental level, that all the ideas that can exist, already do, with their constituent parts quietly waiting for us to shuffle them into existence.</p>
<p><strong><em>Les Brown</em> sums it up well with this thought experiment:</strong></p>
<p><em>Imagine if you will, being on your death bed. And standing around your bed–the ghosts of the ideas, the dreams, the abilities, the talents given to you by life.</em></p>
<p><em>And that you, for whatever reason, never acted on those ideas. You never pursued that dream. You never used those talents. We never saw your leadership. You never used your voice. You never wrote that book.</em></p>
<p><em>And there they are, standing around your bed, looking at you with large angry eyes saying: “We came to you. And only you could have given us life! Now we must die with you forever.”</em></p>
<p><em>The question is — if you die today–what ideas, what dreams, what abilities, what talents, what gifts, would die with you?</em></p>
<p>Thank you for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ When to capitalize your JavaScript constants ]]>
                </title>
                <description>
                    <![CDATA[ Many JavaScript style guides suggest capitalizing constant names. Personally, I rarely see this convention used where I thought it should be. This was because my definition of a constant was a bit off ]]>
                </description>
                <link>https://www.freecodecamp.org/news/when-to-capitalize-your-javascript-constants-4fabc0a4a4c4/</link>
                <guid isPermaLink="false">66d461843dce891ac3a96846</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ variables ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 08 Mar 2019 18:14:14 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*XhNtWWMZPXU--QwrKShjpQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Many JavaScript style guides suggest capitalizing constant names. Personally, I rarely see this convention used where I thought it should be. This was because my definition of a constant was a bit off. I decided to do a bit of digging and become a bit more familiar with this convention.</p>
<h4 id="heading-how-do-we-define-the-term-constant">How do we define the term “constant”?</h4>
<p>In programming, a constant it something that doesn’t change.</p>
<blockquote>
<p><a href="https://en.wikipedia.org/wiki/Constant_(computer_programming)">It is a value that cannot be altered by the program during normal execution</a>.</p>
</blockquote>
<p>So, does JavaScript gives us a way to declare a value that can’t be changed? Before we answer this, let’s look at the roots of this convention.</p>
<h4 id="heading-the-capitalization-convention-has-roots-in-c">The capitalization convention has roots in C</h4>
<p>C is a compiled language. This means that another program converts all of your code into machine code before it runs.</p>
<p>JavaScript, on the other hand, is an interpreted language. An interpreter reads your code, line-by-line, as it runs.</p>
<p>The difference between compilation and interpretation plays a role in how we declare constant values in C.</p>
<p>In C, I can declare a variable like this:</p>
<p><code>int hoursInDay = 24;</code></p>
<p>Or, a constant like this:</p>
<p><code>#define hoursInDay 24</code></p>
<p>The second example is called a <strong>symbolic constant</strong>. Symbolic constants can be a sequence of characters, a numeric constant, or a string. These are also called primitive values. The primitive values in JavaScript are strings, numbers, booleans, null, undefined, symbol (not to be confused with symbolic constants) and big int.</p>
<p>Now, let’s revisit compilation.</p>
<p>Before compilation, there is a pre-compilation phase. Here, the pre-compiler replaces all instances of symbolic constants with the respective value. The compiler never knows that the programmer wrote <code>hoursInDay</code>. It only sees the number <code>24</code>.</p>
<p>Capitalization helps the programmer see these truly constant values.</p>
<p><code>#define HOURS_IN_DAY 24</code></p>
<h4 id="heading-javascript-constants-are-different-than-symbolic-constants">JavaScript constants are different than symbolic constants</h4>
<p>Before ES6, we stored most values in variables, even those values that you wanted to remain constant.</p>
<p>Capitalization helped us see values we wanted to remain constant.</p>
<pre><code class="language-js">var HOURS_IN_DAY = 24;
var hoursRemaining = currentHour - HOURS_IN_DAY;
var MY_NAME = 'Brandon';
MY_NAME = ... // oops don't want to do this.
</code></pre>
<p>ES6 introduced the declaration <code>const</code> which isn’t a “constant” in the purest sense.</p>
<p>ES6 added the terms <code>const</code> and <code>let</code> as ways to create variables with different intentions.</p>
<p>With those two terms, you may think that we either:</p>
<ol>
<li><p>don’t need to capitalize anything since we can clearly see which variables are intended to remain the same, or</p>
</li>
<li><p>we should capitalize everything that we declare with <code>const</code>.</p>
</li>
</ol>
<p>By definition, <code>const</code> creates a constant that is a read-only reference to a value. This does not mean the value it holds is immutable. It only says that <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const">the variable identifier cannot be reassigned</a>.</p>
<p>In other words, some <code>const</code> references can change.</p>
<pre><code class="language-js">const firstPerson = {
  favoriteNumber: 10,
};
const secondPerson = firstPerson;
console.log(secondPerson.favoriteNumber); //10
firstPerson.favoriteNumber +=1;
console.log(secondPerson.favoriteNumber); //11
</code></pre>
<p>The above example shows that the declaration <code>const</code> doesn’t ensure that the variable is immutable.</p>
<p><code>const</code> only prevents us from trying to reassign the variable name. It doesn’t stop the object property from changing. Remember: objects are pass-by-reference.</p>
<pre><code class="language-js">// "TypeError: Assignment to constant variable."secondPerson = 'something else';
const secondPerson = 'Me'
secondPerson = 'something else';
</code></pre>
<p>So, for JavaScript, we have to go beyond merely looking for a <code>const</code> declaration. We need to ask two questions to determine if a variable is a constant:</p>
<ol>
<li><p>Is the value of the variable primitive?</p>
</li>
<li><p>Do we intend to keep the variable name pointing at the same value throughout our program?</p>
</li>
</ol>
<p>If the answer is yes to both, we should declare the variable with <code>const</code> and may capitalize the name.</p>
<p>Notice I said “may.” The spirit of this convention comes from different languages that had actual constants. JavaScript doesn’t. At least in the purest sense. This may be why you see this convention less often than you might expect. <a href="https://github.com/airbnb/javascript/#naming--uppercase">Airbnb has a great section in their style guide with their take here.</a></p>
<p>The <strong>key takeaway</strong> is to recognize defining a constant in JavaScript has to include the programmer's intentions.</p>
<p>In addition, not every convention from one language makes sense in a different language. Finally, I can only imagine many conventions were used long before IDEs had the capabilities they have today. I’m convinced my IDE takes pleasure in telling me I’m wrong. It happens a lot.</p>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
<h4 id="heading-notes">Notes</h4>
<ul>
<li>You may wonder why I didn’t use <code>PI</code> in any of these examples. Acronyms– especially two-letter acronyms–tend to be either always capitalized or always lowercase by convention.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript naming conventions: do’s and don’ts ]]>
                </title>
                <description>
                    <![CDATA[ I find it amazing how many different meanings we can get from less than 30 characters. I’m talking about the alphabet with some well-placed punctuation, of course. From a love story to a computer prog ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-naming-conventions-dos-and-don-ts-99c0e2fdd78a/</link>
                <guid isPermaLink="false">66d4617b33b83c4378a5184f</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Naming Conventions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Wed, 06 Mar 2019 15:51:47 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*xiJRjtRIJoosH5sI_fMdgQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I find it amazing how many different meanings we can get from less than 30 characters. I’m talking about the alphabet with some well-placed punctuation, of course. From a love story to a computer program, writing has allowed us to create extraordinarily different worlds. And language, in general, provides a framework in which we can hang a stream of ideas.</p>
<p>Most programming languages seem to have very strict standards — certain terms have to be used in certain places. But one area where there is an enormous amount of freedom is how we name those terms.</p>
<p>Take this simple program which creates a sentence from an array of words, adds a punctuation mark, and logs it to the console:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/dRQKspy4V21MPbO8LW1bFXtIOwTMvnNeRp5i" alt="Image" width="600" height="400" loading="lazy">

<p>Nothing too special, right? But what you may not have considered is how many <em>terms</em> you were responsible to name.</p>
<p>There are 23 words (not including hard-coded values) in the above program. We controlled the names of 14 of those words. That is more than 60% of what was typed, was our responsibility to name!</p>
<img src="https://cdn-media-1.freecodecamp.org/images/rQnG17-jJTsPsKtn0NCIPVD60qKRR8nhHNMX" alt="Image" width="600" height="400" loading="lazy">

<p><em>You are responsible for the majority of the names in your program</em></p>
<p>Whether you are building an enterprise application or a simple <em>Hello, World,</em> you want your program to read like a Times Bestseller, not a Mad Libs workbook.</p>
<p>This is <em>not</em> a manifesto on how to structure an entire JavaScript application, but rather a chapter on how to choose names for those things in which you have the freedom to do so. I’ve included the various references at the bottom if you want to learn more. One last thing, the key takeaway of all of our conventions and standards is this:</p>
<blockquote>
<p><em>Most of these conventions are not for you today, but instead, for you and the people reading your code tomorrow.</em></p>
</blockquote>
<img src="https://cdn-media-1.freecodecamp.org/images/-Se0xzoDIzsROxX4YKSWtQuD6Z7Mq4UbT-ub" alt="Image" width="600" height="400" loading="lazy">

<h4 id="heading-references-and-continued-learning">References and continued learning</h4>
<ol>
<li><p><a href="https://www.amazon.com/gp/product/0132350882/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0132350882&amp;linkCode=as2&amp;tag=brandonwoz-20&amp;linkId=8af093cb2b8d9a87993f285341ff015a">“Clean Code” by Robert C. Martin</a> — <em>A great read for all languages. It goes beyond naming conventions and proposes the entire structure of your program. The examples are in Java, but the principles apply to JavaScript.</em></p>
</li>
<li><p><a href="https://github.com/ryanmcdermott/clean-code-javascript">“Clean Code JavaScript” by Ryan Mcdermott</a> — <em>The above book, but remade for JavaScript. It is available online and is free.</em></p>
</li>
<li><p><a href="https://github.com/airbnb/javascript">Airbnb JavaScript Style Guide</a> — <em>Possibly the most comprehensive style guide for JavaScript. It contains not only the what, but also the why. (If you’re on a small device, you may need to click on “view all readme” to see the entire document).</em></p>
</li>
<li><p><a href="https://www.w3schools.com/js/js_conventions.asp">W3 JavaScript Style Guide</a> — A s_hort and concise guide._</p>
</li>
<li><p><a href="https://google.github.io/styleguide/jsguide.html">Google’s ES6 Style Guide</a> — <em>Google’s style guide for JavaScript.</em></p>
</li>
</ol>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write a JavaScript Promise ]]>
                </title>
                <description>
                    <![CDATA[ What is a promise? A JavaScript promise is an object that represents the completion or failure of an asynchronous task and its resulting value.¹ The end. I’m kidding of course. So, what does that defi ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-a-javascript-promise-4ed8d44292b8/</link>
                <guid isPermaLink="false">66d461793dce891ac3a96840</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ promises ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Tue, 05 Feb 2019 16:30:16 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*RR8oubeQOm63YN90Uth0CA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h3 id="heading-what-is-a-promise">What is a promise?</h3>
<p>A JavaScript promise is an object that represents the completion or failure of an asynchronous task and its resulting value.¹</p>
<p>The end.</p>
<p>I’m kidding of course. So, what does that definition even mean?</p>
<p>First of all, many things in JavaScript are objects. You can create an object a few different ways. The most common way is with object literal syntax:</p>
<pre><code class="language-js">const myCar = {
   color: 'blue',
   type: 'sedan',
   doors: '4',
};
</code></pre>
<p>You could also create a <code>class</code> and instantiate it with the <code>new</code> keyword.</p>
<pre><code class="language-js">class Car {
   constructor(color, type, doors) {
      this.color = color;
      this.type = type;
      this.doors = doors
   }
}

const myCar = new Car('blue', 'sedan', '4');
</code></pre>
<p><code>console.log(myCar);</code></p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*QUB10cb7QMBVBEGM2JRo1g.png" alt="Image" width="636" height="166" loading="lazy">

<p>A promise is simply an object that we create like the later example. We instantiate it with the <code>new</code> keyword. Instead of the three parameters we passed in to make our car (color, type, and doors), we pass in a function that takes two arguments: <code>resolve</code> and <code>reject</code>.</p>
<p>Ultimately, promises tell us something about the completion of the asynchronous function we returned it from–if it worked or didn’t. We say the function was successful by saying the promise <em>resolved</em>, and unsuccessful by saying the promise <em>rejected.</em></p>
<pre><code class="language-js">const myPromise = new Promise(function(resolve, reject) {});
</code></pre>
<p><code>console.log(myPromise);</code></p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*z8UFY0q1iVmr4xzOqOvFlA.png" alt="Image" width="600" height="400" loading="lazy">

<p><em>Notice the promise is “pending.”</em></p>
<pre><code class="language-js">const myPromise = new Promise(function(resolve, reject) {
   resolve(10);
});
</code></pre>
<img src="https://cdn-media-1.freecodecamp.org/images/1*voamRd9sJg_NZ0vOdbYJgg.png" alt="Image" width="600" height="400" loading="lazy">

<p><em>Notice we resolved the promise with the value 10.</em></p>
<p>See, not too scary–just an object we created. And, if we expand it a bit:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*szpVAwKfKzMasjP9Wlpigg.png" alt="Image" width="596" height="320" loading="lazy">

<p><em>Notice we have some methods we have access to namely “then” and “catch”</em></p>
<p>In addition, we can pass anything we’d like to into resolve and reject. For example, we could pass an object instead of a string:</p>
<pre><code class="language-js">return new Promise((resolve, reject) =&gt; {
   if(somethingSuccesfulHappened) {
      const successObject = {
         msg: 'Success',
         data,//...some data we got back
      }
      resolve(successObject); 
   } else {
      const errorObject = {
         msg: 'An error occured',
         error, //...some error we got back
      }
      reject(errorObject);
   }
});
</code></pre>
<p>Or, as we saw earlier, we don’t have to pass anything:</p>
<pre><code class="language-js">return new Promise((resolve, reject) =&gt; {
   if(somethingSuccesfulHappend) {
      resolve()
   } else {
      reject();
   }
});
</code></pre>
<h4 id="heading-what-about-the-asynchronous-part-of-the-definition">What about the “asynchronous” part of the definition?</h4>
<p>JavaScript is single threaded. This means it can only run one thing at a time. If you can imagine a road, you can think of JavaScript as a single lane highway. Certain code (asynchronous code) can slide over to the shoulder to allow other code to pass it. When that asynchronous code is done, it returns to the roadway.</p>
<blockquote>
<p>As a side note, we can return a promise from <em>any</em> function. It doesn’t have to be asynchronous. That being said, promises are normally returned in cases where the function they return from is asynchronous. For example, an API that has methods for saving data to a server would be a great candidate to return a promise!</p>
</blockquote>
<p><strong>The takeaway:</strong></p>
<p>Promises give us a way to wait for our asynchronous code to complete, capture some values from it, and pass those values on to other parts of our program.</p>
<p><em>I have an article here that dives deeper into these concepts:</em> <a href="https://www.freecodecamp.org/news/thrown-for-a-loop-understanding-for-loops-and-timeouts-in-javascript-558d8255d8a4/"><em>Thrown For a Loop: Understanding Loops and Timeouts in JavaScript.</em></a></p>
<h3 id="heading-how-do-we-use-a-promise">How do we use a promise?</h3>
<p>Using a promise is also called <em>consuming</em> a promise. In our example above, our function returns a promise object. This allows us to use method chaining with our function.</p>
<p>Here is an example of method chaining I bet you’ve seen:</p>
<pre><code class="language-js">const a = 'Some awesome string';
const b = a.toUpperCase().replace('ST', '').toLowerCase();

console.log(b); // some awesome ring
</code></pre>
<p>Now, recall our (pretend) promise:</p>
<pre><code class="language-js">const somethingWasSuccesful = true;

function someAsynFunction() {
   return new Promise((resolve, reject){
      if (somethingWasSuccesful) {
         resolve();     
      } else {
         reject()
      }
   });
}
</code></pre>
<p>And, consuming our promise by using method chaining:</p>
<pre><code class="language-js">someAsyncFunction
   .then(runAFunctionIfItResolved(withTheResolvedValue))
   .catch(orARunAfunctionIfItRejected(withTheRejectedValue));
</code></pre>
<h3 id="heading-a-more-real-example">A (more) real example.</h3>
<p>Imagine you have a function that gets users from a database. I’ve written an example function on Codepen that simulates an API you might use. It provides two options for accessing the results. One, you can provide a callback function where you can access the user or any error. Or two, the function returns a promise as a way to access the user or error.</p>
<div class="embed-wrapper"><iframe width="100%" height="350" src="https://codepen.io/brandonwoz/embed/NoNMgJ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>

<p>Traditionally, we would access the results of asynchronous code through the use of callbacks.</p>
<pre><code class="language-js">rr someDatabaseThing(maybeAnID, function(err, result)) {
   //...Once we get back the thing from the database...
   if(err) {
      doSomethingWithTheError(error)
   }   else {
      doSomethingWithResults(results);
   }
}
</code></pre>
<p>The use of callbacks is <em>ok</em> until they become overly nested. In other words, you have to run more asynchronous code with each new result. This pattern of callbacks within callbacks can lead to something known as “callback hell.”</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*DxEgvtymVuqpLOSx8NJ57A.png" alt="Image" width="800" height="312" loading="lazy">

<p><em>The beginnings of callback hell</em></p>
<p>Promises offer us a more elegant and readable way to see the flow of our program.</p>
<pre><code class="language-js">doSomething()
   .then(doSomethingElse) // and if you wouldn't mind
   .catch(anyErrorsPlease);
</code></pre>
<h3 id="heading-writing-our-own-promise-goldilocks-the-three-bears-and-a-supercomputer">Writing our own promise: Goldilocks, the Three Bears, and a Supercomputer</h3>
<p>Imagine you found a bowl of soup. You’d like to know the temperature of that soup before you eat it. You're out of thermometers, but luckily, you have access to a supercomputer that tells you the temperature of the bowl of soup. Unfortunately, this supercomputer can take up to 10 seconds to get the results.</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*XtBW084Eg2feXeR97W2yvw.png" alt="Image" width="800" height="405" loading="lazy">

<p>Here are a couple of things to notice.</p>
<ol>
<li><p>We initiate a global variable called <code>result</code>.</p>
</li>
<li><p>We simulate the duration of the network delay with <code>Math.random()</code> and <code>setTimeout()</code>.</p>
</li>
<li><p>We simulate a temperature with <code>Math.random()</code>.</p>
</li>
<li><p>We keep the delay and temperature values confined within a range by adding some extra “math”. The range for <code>temp</code> is 1 to 300; the range for <code>delay</code> is 1000ms to 10000ms (1s to 10 seconds).</p>
</li>
<li><p>We log the delay and temperature so we have an idea of how long this function will take and the results we expect to see when it’s done.</p>
</li>
</ol>
<p>Run the function and log the results.</p>
<pre><code class="language-js">getTemperature(); 
console.log(results); // undefined
</code></pre>
<h4 id="heading-the-temperature-is-undefined-what-happened">The temperature is undefined. What happened?</h4>
<p>The function will take a certain amount of time to run. The variable is not set until the delay is over. So while we run the function, <code>setTimeout</code> is asynchronous. The part of the code in <code>setTimeout</code> moves out of the main thread into a waiting area.</p>
<p><em>I have an article here that dives deeper into this process:</em> <a href="https://www.freecodecamp.org/news/thrown-for-a-loop-understanding-for-loops-and-timeouts-in-javascript-558d8255d8a4/"><em>Thrown For a Loop: Understanding Loops and Timeouts in JavaScript.</em></a></p>
<p>Since the part of our function that sets the variable <code>result</code> moves into a holding area until it is done, our parser is free to move onto the next line. In our case, it’s our <code>console.log()</code>. At this point, <code>result</code> is still undefined since our <code>setTimeout</code> is not over.</p>
<p>So what else could we try? We could run <code>getTemperature()</code> and then wait 11 seconds (since our max delay is ten seconds) and <em>then</em> console.log the results.</p>
<pre><code class="language-js">getTemperature();
   setTimeout(() =&gt; {
      console.log(result); 
   }, 11000);
   
// Too Hot | Delay: 3323 | Temperature: 209 deg
</code></pre>
<p>This works, but the problem with this technique is, although in our example we know the maximum network delay, in a real-life example it might occasionally take longer than ten seconds. And, even if we could guarantee a maximum delay of ten seconds, if the result is ready sooner, we are wasting time.</p>
<h3 id="heading-promises-to-the-rescue">Promises to the Rescue</h3>
<p>We are going to refactor our <code>getTemperature()</code> function to return a promise. And instead of setting the result, we will reject the promise unless the result is “Just Right,” in which case we will resolve the promise. In either case, we will pass in some values to both resolve and reject.</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*4RJERRgVUtHlIYRFm2piVQ.png" alt="Image" width="800" height="432" loading="lazy">

<p>We can now use the results of our promise we are returning (also know as <em>consuming</em> the promise).</p>
<pre><code class="language-js">getTemperature()
   .then(result =&gt; console.log(result))
   .catch(error =&gt; console.log(error));
   
// Reject: Too Cold | Delay: 7880 | Temperature: 43 deg
</code></pre>
<p><code>.then</code> will get called when our promise resolves and will return whatever information we pass into <code>resolve</code>.</p>
<p><code>.catch</code> will get called when our promise rejects and will return whatever information we pass into <code>reject</code>.</p>
<p>Most likely, you’ll consume promises more than you will create them. In either case, they help make our code more elegant, readable, and efficient.</p>
<h3 id="heading-summary">Summary</h3>
<ol>
<li><p>Promises are objects that contain information about the completion of some asynchronous code and any resulting values we want to pass in.</p>
</li>
<li><p>To return a promise we use <code>return new Promise((resolve, reject)=&gt; {})</code></p>
</li>
<li><p>To consume a promise we use <code>.then</code> to get the information from a promise that has resolved, and <code>.catch</code> to get the information from a promise that has rejected.</p>
</li>
<li><p>You’ll probably use (consume) promises more than you’ll write.</p>
</li>
</ol>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
<h4 id="heading-references">References</h4>
<p>1.) <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"><em>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise</em></a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ An Introduction to Test-Driven Development ]]>
                </title>
                <description>
                    <![CDATA[ I’ve been programming for five years and, honestly, I have avoided test-driven development. I haven’t avoided it because I didn’t think it was important. In fact, it seemed very important–but rather b ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-introduction-to-test-driven-development-c4de6dce5c/</link>
                <guid isPermaLink="false">66d4617247a8245f78752ace</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TDD (Test-driven development) ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ unit testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Mon, 04 Feb 2019 16:44:44 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*UILpgckM9QDwSXuy6l1WTg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I’ve been programming for five years and, honestly, I have avoided test-driven development. I haven’t avoided it because I didn’t think it was important. In fact, it seemed very important–but rather because I was too comfortable not doing it. That’s changed.</p>
<h3 id="heading-what-is-testing">What is Testing?</h3>
<p>Testing is the process of ensuring a program receives the correct input and generates the correct output and intended side-effects. We define these correct inputs, outputs, and side-effects with <em>specifications</em>. You may have seen testing files with the naming convention <code>filename.spec.js</code>. The <code>spec</code> stands for specification. It is the file where we specify or <em>assert</em> what our code should do and then test it to verify it does it.</p>
<p>You have two choices when it comes to testing: manual testing and automated testing.</p>
<h4 id="heading-manual-testing">Manual Testing</h4>
<p>Manual testing is the process of checking your application or code from the user’s perspective. Opening up the browser or program and navigating around in an attempt to test functionality and find bugs.</p>
<h4 id="heading-automated-testing">Automated Testing</h4>
<p>Automated testing, on the other hand, is writing code that checks to see if other code works. Contrary to manual testing, the specifications remain constant from test to test. The biggest advantage is being able to test <em>many</em> things much faster.</p>
<p>It’s the combination of these two testing techniques that will flush out as many bugs and unintended side-effects as possible, and ensure your program does what you say it will. The focus of this article is on automated testing, and in particular, unit testing.</p>
<blockquote>
<p>There are two main types of automated tests: Unit and End-to-End (E2E). E2E tests test an application as a whole. Unit tests test the smallest pieces of code, or units. What is a unit? Well, we define what a unit is, but in general, it’s a relatively small piece of application functionality.</p>
</blockquote>
<h4 id="heading-recap">Recap:</h4>
<ol>
<li><p>Testing is verifying our application does what it should.</p>
</li>
<li><p>There are two types of tests: manual and automated</p>
</li>
<li><p>Tests <em>assert</em> that your program will behave a certain way. Then the test itself proves or disproves that assertion.</p>
</li>
</ol>
<h3 id="heading-test-driven-development">Test-Driven Development</h3>
<p>Test-driven development is the act of first deciding what you want your program to do (the specifications), formulating a failing test, <em>then</em> writing the code to make that test pass. It is most often associated with automated testing. Although you could apply the principals to manual testing as well.</p>
<p>Let’s look at a simple example: Building a wooden table. Traditionally, we would make a table, then once the table is made, test it to make sure it does, well, what a table should do. TDD, on the other hand, would have us first define what the table should do. Then when it isn’t doing those things, add the minimum amount of “table” to make each unit work.</p>
<p>Here an example of TDD for building a wooden table:</p>
<pre><code class="language-python">I expect the table to be four feet in diameter.

The test fails because I have no table.

I cut a circular piece of wood four feet in diameter.

The test passes.

__________

I expect the table to be three feet high.

The test fails because it is sitting on the ground.

I add one leg in the middle of the table.

The test passes.

__________

I expect the table to hold a 20-pound object.

The test fails because when I place the object on the edge, it makes the table fall over since there is only one leg in the middle.

I move the one leg to the outer edge of the table and add two more legs to create a tripod structure.

The test passes.
</code></pre>
<p>This would continue on and on until the table is complete.</p>
<h4 id="heading-recap">Recap</h4>
<ol>
<li>With TDD, test logic precedes application logic.</li>
</ol>
<h3 id="heading-a-practical-example">A Practical Example</h3>
<p>Imagine we have a program that manages users and their blog posts. We need a way to keep track of the posts a user writes in our database with more precision. Right now, the user is an object with a name and email property:</p>
<pre><code class="language-js">user = { 
   name: 'John Smith', 
   email: 'js@somePretendEmail.com' 
}
</code></pre>
<p>We will track the posts a user creates in the same user object.</p>
<pre><code class="language-js">user = { 
   name: 'John Smith', 
   email: 'js@someFakeEmailServer.com'
   posts: [Array Of Posts] // &lt;-----
}
</code></pre>
<p>Each post has a title and content. Instead of storing the entire post with each user, we’d like to store something unique that could be used to reference the post. We first thought we would store the title. But, if the user ever changes the title, or if–although somewhat unlikely–two titles are exactly the same, we’d have some issues referencing that blog post. Instead, we will create a unique ID for each blog post that we will store in the <code>user</code>Object.</p>
<pre><code class="language-js">user = { 
   name: 'John Smith', 
   email: 'js@someFakeEmailServer.com'
   posts: [Array Of Post IDs]
}
</code></pre>
<h4 id="heading-set-up-our-testing-environment">Set up our testing environment</h4>
<p>For this example, we will be using Jest. Jest is a testing suite. Often, you’ll need a testing library and a separate assertion library, but Jest is an all-in-one solution.</p>
<blockquote>
<p>An assertion library allows us to make assertions about our code. So in our wooden table example, our assertion is: “I expect the table to hold a 20-pound object.” In other words, I am asserting something about what the table should do.</p>
</blockquote>
<h4 id="heading-project-setup">Project setup</h4>
<ol>
<li><p>Create an NPM project: <code>npm init</code>.</p>
</li>
<li><p>Create <code>id.js</code> and add it to the project’s root.</p>
</li>
<li><p>Install Jest: <code>npm install jest --D</code></p>
</li>
<li><p>Update the package.json <code>test</code> script</p>
</li>
</ol>
<pre><code class="language-json">// package.json

{
   ...other package.json stuff
   "scripts": {   
     "test": "jest" // this will run jest with "npm run test"
   }
}
</code></pre>
<p>That’s it for the project setup! We aren’t going to have any HTML or any styling. We are approaching this purely from a unit-testing standpoint. And, believe it or not, we have enough to run Jest right now.</p>
<p>In the command line, run our test script: <code>npm run test</code>.</p>
<p>You should have received an error:</p>
<pre><code class="language-bash">No tests found
In /****/
  3 files checked.
  testMatch: **/__tests__/**/*.js?(x),**/?(*.)+(spec|test).js?(x) - 0 matches
  testPathIgnorePatterns: /node_modules/ - 3 matches
</code></pre>
<p>Jest is looking for a file name with some specific characteristics such as a <code>.spec</code> or <code>.test</code> contained within the file name.</p>
<p>Let’s update <code>id.js</code> to be <code>id.spec.js</code>.</p>
<p>Run the test again</p>
<p>You should receive another error:</p>
<pre><code class="language-bash">FAIL  ./id.spec.js
  ● Test suite failed to run
  
Your test suite must contain at least one test.
</code></pre>
<p>A little bit better, it found the file, but not a test. That makes sense; it’s an empty file.</p>
<h4 id="heading-how-do-we-write-a-test">How Do We Write a Test?</h4>
<p>Tests are just functions that receive a couple of arguments. We can call our test with either <code>it()</code> or <code>test()</code>.</p>
<blockquote>
<p><code>it()</code>is an alias of <code>test()</code>.</p>
</blockquote>
<p>Let’s write a very basic test just to make sure Jest is working.</p>
<pre><code class="language-js">// id.spec.js

test('Jest is working', () =&gt; {
   expect(1).toBe(1);
});
</code></pre>
<p>Run the test again.</p>
<pre><code class="language-bash">PASS  ./id.spec.js
  ✓ Jest is working (3ms)
  
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.254s
Ran all test suites.
</code></pre>
<p>We passed our first test! Let’s analyze the test and results output.</p>
<p>We pass a title or description as the first argument.</p>
<p><code>test('Jest is Working')</code></p>
<p>The second argument we pass is a function where we actually assert something about our code. Although, in this case, we aren’t asserting something about our code, but rather something truthy in general that will pass, a sort of sanity check.</p>
<p><code>...() =&gt; { expect(1).toBe(1)</code> });</p>
<p>This assertion is mathematically true, so it’s a simple test to ensure we’ve wired up Jest correctly.</p>
<p>The results tell us whether the test passes or fails. It also tells us the number of tests and test suites.</p>
<h4 id="heading-a-side-note-about-organizing-our-tests">A side note about organizing our tests</h4>
<p>There is another way we could organize our code. We could wrap each test in a <code>describe</code> function.</p>
<pre><code class="language-js">describe('First group of tests', () =&gt; {
   test('Jest is working', () =&gt; {
      expect(1).toBe(1);
   });
});

describe('Another group of tests', () =&gt; {
   // ...more tests here
});
</code></pre>
<p><code>describe()</code> allows us to divide up our tests into sections:</p>
<pre><code class="language-bash">PASS  ./id.spec.js
  First group of tests
    ✓ Jest is working(4ms)
    ✓ Some other test (1ms)
  Another group of tests
    ✓ And another test
    ✓ One more test (12ms)
    ✓ And yes, one more test
</code></pre>
<p>We won’t use <code>describe</code>, but <em>it is</em> more common than not to see a <code>describe</code> function that wraps tests. Or even a couple of <code>describes</code>–maybe one for each file we are testing. For our purposes, we will just focus on <code>test</code> and keep the files fairly simple.</p>
<h4 id="heading-testing-based-on-specifications">Testing Based on Specifications</h4>
<p>As tempting as it is to just sit down and start typing application logic, a well-formulated plan will make development easier. We need to define what our program will do. We define these goals with specifications.</p>
<p>Our high-level specification for this project is to create a unique ID, although we should break that down into smaller units that we will test. For our small project we will use the following specifications:</p>
<ol>
<li><p>Create a random number</p>
</li>
<li><p>The number is an integer.</p>
</li>
<li><p>The number created is within a specified range.</p>
</li>
<li><p>The number is unique.</p>
</li>
</ol>
<h4 id="heading-recap">Recap</h4>
<ol>
<li><p>Jest is a testing suite and has a built-in assertion library.</p>
</li>
<li><p>A test is just a function whose arguments define the test.</p>
</li>
<li><p>Specifications define what our code should do and are ultimately what we test.</p>
</li>
</ol>
<h3 id="heading-specification-1-create-a-random-number">Specification 1: Create a Random Number</h3>
<p>JavaScript has a built-in function to create random numbers–<code>Math.random()</code>. Our first unit test will look to see that a random number was created and returned. What we want to do is use <code>math.random()</code> to create a number and then ensure that is the number that gets returned.</p>
<p>So you might think we would do something like the following:</p>
<p><code>expect(our-functions-output).toBe(some-expected-value)</code>. The problem with our return value being random, is we have no way to know what to expect. We need to re-assign the <code>Math.random()</code> function to some constant value. This way, when our function runs, Jest replaces <code>Math.random()</code>with something constant. This process is called <em>mocking.</em> So, what we are really testing for is that <code>Math.random()</code>gets called and returns some expected value that we can plan for.</p>
<p>Now, Jest also provides a way to prove a function is called. However, in our example, that assertion alone only assures us <code>Math.random()</code>was called somewhere in our code. It won’t tell us that the result of <code>Math.random()</code>was also the return value.</p>
<blockquote>
<p>Why would you want to mock a function? Isn’t the point to test the real code? Yes and no. Many functions contain things we cannot control, for example an HTTP request. We aren’t trying to test this code. We assume those dependencies will do what they are supposed or make pretend functions that simulate their behavior. And, in the event those are dependencies we’ve written, we will likely write separate tests for them.</p>
</blockquote>
<p>Add the following test to <code>id.spec.js</code></p>
<pre><code class="language-js">test('returns a random number', () =&gt; {
   const mockMath = Object.create(global.Math);
   mockMath.random = jest.fn(() =&gt; 0.75);
   global.Math = mockMath;
   const id = getNewId();
   expect(id).toBe(0.75);
});
</code></pre>
<h4 id="heading-breaking-the-above-test-down">Breaking the above test down</h4>
<p>First, we copy the global Math object. Then we change the <code>random</code> method to return a constant value, something we can <em>expect</em>. Finally, we replace the global <code>Math</code> object with our mocked <code>Math</code> object.</p>
<p>We should get an ID back from a function (that we haven't created yet–remember this TDD). Then, we expect that ID to equal 0.75–our mocked return value.</p>
<blockquote>
<p>Notice I’ve chosen to use a built-in method that Jest provides for mocking functions: <code>jest.fn()</code>. We could have also passed in a anonymous function instead. However, I wanted to show you this method, since there will be times that a Jest-mocked function will be required for other functionality in our tests to work .</p>
</blockquote>
<p>Run the test: <code>npm run test</code></p>
<pre><code class="language-bash">FAIL  ./id.spec.js
✕ returns a random number (4ms)
● returns a random number
   ReferenceError: getNewId is not defined
</code></pre>
<p>Notice we get a reference error just like we should. Our test can’t find our <code>getNewId()</code>.</p>
<p>Add the following code above the test.</p>
<pre><code class="language-js">function getNewId() {
   Math.random()
}
</code></pre>
<blockquote>
<p>I am keeping the code and testing in the same file for simplicity. Normally, the test would be written in a separate file, with any dependencies imported as they are needed.</p>
</blockquote>
<pre><code class="language-bash">FAIL  ./id.spec.js
   ✕ returns a random number (4ms)
   ● returns a random number
   
   expect(received).toBe(expected) // Object.is equality
   Expected: 0.75
   Received: undefined
</code></pre>
<p>We failed again with what is called an <em>assertion error</em>. Our first error was a reference error. This second error tells us it received <code>undefined</code>. But we called <code>Math.random()</code>so what happened? Remember, functions that don’t explicitly return something will implicitly return <code>undefined</code>. This error is a good hint that something wasn’t defined such as a variable, or, like in our case, our function isn’t returning anything.</p>
<p>Update the code to the following:</p>
<pre><code class="language-js">function getNewId() {
   return Math.random()
}
</code></pre>
<p>Run the test</p>
<pre><code class="language-bash">PASS  ./id.spec.js
✓ returns a random number (1ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
</code></pre>
<p>Congratulations! We passed our first test.</p>
<blockquote>
<p>Ideally, we want to get to our assertion errors as quickly as possible. Assertion errors–specifically <em>value assertion errors</em> like this one, although we will touch on <em>boolean assertions errors</em> in a bit–give us hints to what is wrong.</p>
</blockquote>
<h3 id="heading-specification-2-the-number-we-return-is-an-integer">Specification 2: The number we return is an integer.</h3>
<p><code>Math.random()</code> generates a number between 0 and 1 (not inclusive). The code we have will never generate such an integer. That’s ok though, this is TDD. We will check for an integer and then write the logic to transform our number to an integer.</p>
<p>So, how do we check if a number is an integer? We have a few options. Recall, we mocked <code>Math.random()</code> above, and we are returning a constant value. In fact, we are creating a real value as well since we are returning a number between 0 and 1 (not inclusive). If we were returning a string, for example, we couldn’t get this test to pass. Or if on the other hand, we were returning an integer for our mocked value, the test would always (falsely) pass.</p>
<p>So a key takeaway is if you going to use mocked return values, they should be realistic so our tests return meaningful information with those values.</p>
<p>Another option would be to use the <code>Number.isInteger()</code>, passing our ID as the argument and seeing if that returns true.</p>
<p>Finally, without using the mocked values, we could compare the ID we get back with its integer version.</p>
<p>Let’s look at option 2 and 3.</p>
<p><strong>Option 2: Using Number.isInteger()</strong></p>
<pre><code class="language-js">test('returns an integer', () =&gt; {
   const id = getRandomId();
   expect(Number.isInteger(id)).toBe(true);
});
</code></pre>
<p>The test fails as it should.</p>
<pre><code class="language-bash">FAIL  ./id.spec.js
✓ returns a random number (1ms)
✕ returns an integer (3ms)

● returns an integer
expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false
</code></pre>
<p>The test fails with a <em>boolean assertion error</em>. Recall, there are multiple ways a test might fail. We want them to fail with assertion errors. In other words, our assertion isn’t what we say it is. But even more so, we want our test to fail with <em>value assertion errors</em>.</p>
<p>Boolean assertion errors (true/false errors) don’t give us very much information, but a value assertion error does.</p>
<p>Let’s return to our wooden table example. Now bear with me, the following two statements might seem awkward and difficult to read, but they’re here to highlight a point:</p>
<p>First, you might assert that <strong>the table is blue [to be] true</strong>. In another assertion, you might assert <strong>the table color [to be] blue</strong>. I know, these are awkward to say and might even look like identical assertions but they're not. Take a look at this:</p>
<p><code>expect(table.isBlue).toBe(true)</code></p>
<p>vs</p>
<p><code>expect(table.color).toBe(blue)</code></p>
<p>Assuming the table isn’t blue, the first examples error will tell us it expected true but received false. You have no idea what color the table is. We very well may have forgotten to paint it altogether. The second examples error, however, might tell us it expected blue but received red. The second example is much more informative. It points to the root of the problem much quicker.</p>
<p>Let’s rewrite the test, using option 2, to receive a value assertion error instead.</p>
<pre><code class="language-js">test('returns an integer', () =&gt; {
   const id = getRandomId();
   expect(id).toBe(Math.floor(id));
});
</code></pre>
<p>We are saying we expect the ID we get from our function to be equal to the floor of that ID. In other words, if we are getting an integer back, then the floor of that integer is equal to the integer itself.</p>
<pre><code class="language-bash">FAIL  ./id.spec.js
✓ returns a random number (1ms)
✕ returns an integer (4ms)
● returns an integer
expect(received).toBe(expected) // Object.is equality

Expected: 0
Received: 0.75
</code></pre>
<p>Wow, what are the chances this function just happened to return the mocked value! Well, they are 100% actually. Even though our mocked value seems to be scoped to only the first test, we are actually reassigning the global value. So no matter how nested that re-assignment takes place, we are changing the global <code>Math</code> object.</p>
<p>If we want to change something before each test, there is a better place to put it. Jest offers us a <code>beforeEach()</code> method. We pass in a function that runs any code we want to run before each of our tests. For example:</p>
<pre><code class="language-js">beforeEach(() =&gt; {
   someVariable = someNewValue;
});

test(...)
</code></pre>
<p>For our purposes, we won’t use this. But let's change our code a bit so that we reset the global <code>Math</code> object back to the default. Go back into the first test and update the code as follows:</p>
<pre><code class="language-js">test('returns a random number', () =&gt; {
   const originalMath = Object.create(global.Math);
   const mockMath = Object.create(global.Math);
   mockMath.random = () =&gt; 0.75;
   global.Math = mockMath;
   const id = getNewId();
   expect(id).toBe(0.75);
   global.Math = originalMath;
});
</code></pre>
<p>What we do here is save the default <code>Math</code> object before we overwrite any of it, then reassign it after our test is complete.</p>
<p>Let’s run our tests again, specifically focusing back on our second test.</p>
<pre><code class="language-bash">✓ returns a random number (1ms)
✕ returns an integer (3ms)
● returns an integer
expect(received).toBe(expected) // Object.is equality

Expected: 0
Received: 0.9080890805713182
</code></pre>
<p>Since we’ve updated our first test to go back to the default <code>Math</code> object, we are truly getting a random number now. And just like the test before, we are expecting to receive an integer, or in other words, the floor of the number generated.</p>
<p>Update our application logic.</p>
<pre><code class="language-js">function getRandomId() {
   return Math.floor(Math.random()); // convert to integer
}

FAIL  ./id.spec.js
✕ returns a random number (5ms)
✓ returns an integer
● returns a random number
expect(received).toBe(expected) // Object.is equality
Expected: 0.75
Received: 0
</code></pre>
<p>Uh oh, our first test failed. So what happened?</p>
<p>Well, because we are mocking our return value. Our first test returns 0.75, no matter what. We expect, however, to get 0 (the floor of 0.75). Maybe it would be better to check if <code>Math.random()</code> gets called. Although, that is somewhat meaningless, because we could call <code>Math.random()</code>anywhere in our code, never use it, and the test still passes. Maybe, we should test whether our function returns a number. After all, our ID must be a number. Yet again, we are already testing if we are receiving an integer. And all integers are numbers; that test would be redundant. But there is one more test we could try.</p>
<p>When it is all said and done, we expect to get an integer back. We know we will use <code>Math.floor()</code> to do so. So maybe we can check if <code>Math.floor()</code> gets called with <code>Math.random()</code> as an argument.</p>
<pre><code class="language-js">test('returns a random number', () =&gt; {
   jest.spyOn(Math, 'floor'); // &lt;--------------------changed
   const mockMath = Object.create(global.Math); 
   const globalMath = Object.create(global.Math);
   mockMath.random = () =&gt; 0.75;
   global.Math = mockMath;
   const id = getNewId();
   getNewId(); //&lt;------------------------------------changed
   expect(Math.floor).toHaveBeenCalledWith(0.75); //&lt;-changed
   global.Math = globalMath;
});
</code></pre>
<p>I’ve commented the lines we changed. First, move your attention towards the end of the snippet. We are asserting that a function was called. Now, go back to the first change: <code>jest.spyOn()</code>. In order to watch if a function has been called, jest requires us to either mock that function, or spy on it. We’ve already seen how to mock a function, so here we spy on <code>Math.floor()</code>. Finally, the other change we’ve made was to simply call <code>getNewId()</code> without assigning its return value to a variable. We are not using the ID, we are simply asserting it calls some function with some argument.</p>
<p>Run our tests</p>
<pre><code class="language-bash">PASS  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
</code></pre>
<p>Congratulations on a second successful test.</p>
<h3 id="heading-specification-3-the-number-is-within-a-specified-range">Specification 3: The number is within a specified range.</h3>
<p>We know <code>Math.random()</code> returns a random number between 0 and 1 (not inclusive). If the developer wants to return a number between 3 and 10, what could she do?</p>
<p>Here is the answer:</p>
<p><code>Math.floor(Math.random() * (max — min + 1))) + min;</code></p>
<p>The above code will produce a random number in a range. Let’s look at two examples to show how it works. I’ll simulate two random numbers being created and then apply the remainder of the formula.</p>
<p><strong>Example:</strong> A number between 3 and 10. Our random numbers will be .001 and .999. I’ve chosen the extreme values as the random numbers so you could see the final result stays within the range.</p>
<p><code>0.001 * (10-3+1) + 3 = 3.008</code> the floor of that is <code>3</code></p>
<p><code>0.999 * (10-3+1) + 3 = 10.992</code> the floor of that is <code>10</code></p>
<p>Let’s write a test</p>
<pre><code class="language-js">test('generates a number within a specified range', () =&gt; {
   const id = getRandomId(10, 100);
   expect(id).toBeLessThanOrEqual(100);
   expect(id).toBeGreaterThanOrEqual(10);
});

FAIL  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer (1ms)
✕ generates a number within a specified range (19ms)

● generates a number within a specified range
expect(received).toBeGreaterThanOrEqual(expected)

Expected: 10
Received: 0
</code></pre>
<p>The floor of <code>Math.random()</code> will always be 0 until we update our code. Update the code.</p>
<pre><code class="language-js">function getRandomId(min, max) {
   return Math.floor(Math.random() * (max - min + 1) + min);
}

FAIL  ./id.spec.js
✕ returns a random number (5ms)
✓ returns an integer (1ms)
✓ generates a number within a specified range (1ms)

● returns a random number

expect(jest.fn()).toHaveBeenCalledWith(expected)

Expected mock function to have been called with:

0.75 as argument 1, but it was called with NaN.
</code></pre>
<p>Oh no, our first test failed again! What happened?</p>
<p>Simple, our test is asserting that we are calling <code>Math.floor()</code> with <code>0.75</code>. However, we actually call it with 0.75 plus and minus a max and min value that isn’t yet defined. Here we will re-write the first test to include some of our new knowledge.</p>
<pre><code class="language-js">test('returns a random number', () =&gt; {
   jest.spyOn(Math, 'floor');
   const mockMath = Object.create(global.Math);
   const originalMath = Object.create(global.Math);
   mockMath.random = () =&gt; 0.75;
   global.Math = mockMath;
   const id = getNewId(10, 100);
   expect(id).toBe(78);
   global.Math = originalMath;
});

PASS  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer
✓ generates a number within a specified range (1ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
</code></pre>
<p>We’ve made some pretty big changes. We’ve passed some sample numbers into our function (10, and 100 as minimum and maximum values), and we’ve changed our assertion once again to check for a certain return value. We can do this because we know if <code>Math.random()</code> gets called, the value is set to 0.75. And, when we apply our min and max calculations to <code>0.75</code> we will get the same number each time, which in our case is 78.</p>
<p>Now we have to start wondering if this is even a good test. We’ve had to go back in and mold our test to fit our code. That goes against the spirit of TDD a bit. TDD says to change your code to make the test pass, not to change the test to make the test pass. If you find yourself trying to fix tests so they pass, that may be a sign of a bad test. Yet, I’d like to leave the test in here, as there are a couple of good concepts. However, I urge you to consider the efficacy of a test such as this, as well as a better way to write it, or if it’s even critical to include at all.</p>
<p>Let’s return to our third test which was generating a number within a range.</p>
<p>We see it has passed, but we have a problem. Can you think of it?</p>
<p>The question I am wondering is whether we just get lucky? We only generated a single random number. What are the chances that number just happened to be in the range and pass the test?</p>
<p>Fortunately here, we can mathematically prove our code works. However, for fun (if you can call it fun), we will wrap our code in a <code>for loop</code> that runs 100 times.</p>
<pre><code class="language-js">test('generates a number within a defined range', () =&gt; {
   for (let i = 0; i &lt; 100; i ++) {
      const id = getRandomId(10, 100);    
   
      expect(id).toBeLessThanOrEqual(100);
      expect(id).toBeGreaterThanOrEqual(10);
      expect(id).not.toBeLessThan(10);
      expect(id).not.toBeGreaterThan(100);
   }
});
</code></pre>
<p>I added a few new assertions. I use the <code>.not</code> only to demonstrate other Jest API’s available.</p>
<pre><code class="language-bash">PASS  ./id.spec.js
  ✓ is working (2ms)
  ✓ Math.random() is called within the function (3ms)
  ✓ receives an integer from our function (1ms)
  ✓ generates a number within a defined range (24ms)
  
Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.806s
</code></pre>
<p>With 100 iterations, we can feel fairly confident our code keeps our ID within the specified range. You could also purposely try to fail the test for added confirmation. For example, you could change one of the assertions to <em>not</em> expect a value greater than 50 but still pass in 100 as the maximum argument.</p>
<h4 id="heading-is-it-ok-to-use-multiple-assertions-in-one-test">Is it ok to use multiple assertions in one test?</h4>
<p>Yes. That isn’t to say you shouldn’t attempt to reduce those multiple assertions to a single assertion that is more robust. For example, we could rewrite our test to be more robust and reduce our assertions to just one.</p>
<pre><code class="language-js">test('generates a number within a defined range', () =&gt; {
   const min = 10;
   const max = 100;
   const range = [];
   for (let i = min; i &lt; max+1; i ++) {
     range.push(i);
   }
   for (let i = 0; i &lt; 100; i ++) {
      const id = getRandomId(min, max);
      expect(range).toContain(id);
   }
});
</code></pre>
<p>Here, we created an array that contains all the numbers in our range. We then check to see if the ID is in the array.</p>
<h3 id="heading-specification-4-the-number-is-unique">Specification 4: The number is unique</h3>
<p>How can we check if a number is unique? First, we need to define what unique to us means. Most likely, somewhere in our application, we would have access to all ID’s being used already. Our test should assert that the number that is generated is not in the list of current IDs. There are a few different ways to solve this. We could use the <code>.not.toContain()</code> we saw earlier, or we could use something with <code>index</code>.</p>
<h4 id="heading-indexof"><strong>indexOf()</strong></h4>
<pre><code class="language-js">test('generates a unique number', () =&gt; {
   const id = getRandomId();
   const index = currentIds.indexOf(id);
   expect(index).toBe(-1);
});
</code></pre>
<p><code>array.indexOf()</code> returns the position in the array of the element you pass in. It returns <code>-1</code> if the array doesn’t contain the element.</p>
<pre><code class="language-bash">FAIL  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer
✓ generates a number within a defined range (25ms)
✕ generates a unique number (10ms)

● generates a unique number

ReferenceError: currentIds is not defined
</code></pre>
<p>The test fails with a reference error. <code>currentIds</code> is not defined. Let's add an array to simulate some ID’s that might already exist.</p>
<pre><code class="language-js">const currentIds = [1, 3, 2, 4];
</code></pre>
<p>Re-run the test.</p>
<pre><code class="language-bash">PASS  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer
✓ generates a number within a defined range (27ms)
✓ generates a unique number

Test Suites: 1 passed, 1 total

Tests:       4 passed, 4 total
</code></pre>
<p>While the test passes, this should once again raise a red flag. We have absolutely <em>nothing</em> that ensures the number is unique. So, what happened?</p>
<p>Again, we are getting lucky. In fact, <em>your</em> test may have failed. Although if you ran it over and over, you’d likely get a mix of both with far more passes than failures due to the size of <code>currentIds</code>.</p>
<p>One thing we could try is to wrap this in a <code>for loop</code>. A large enough <code>for loop</code> would likely cause us to fail, although it would be possible they all pass. What we could do is check to see that our <code>getNewId()</code> function could somehow be self-aware when a number is or is not unique.</p>
<p>For example. we could set <code>currentIds = [1, 2, 3, 4, 5]</code>. Then call <code>getRandomId(1, 5)</code> . Our function should realize there is no value it can generate due to the constraints and pass back some sort of error message. We could test for that error message.</p>
<pre><code class="language-js">test('generates a unique number', () =&gt; {
   mockIds = [1, 2, 3, 4, 5];
   let id = getRandomId(1, 5, mockIds);
   expect(id).toBe('failed');
    
   id = getRandomId(1, 6, mockIds);
   expect(id).toBe(6);
});
</code></pre>
<p>There are a few things to notice. There are two assertions. In the first assertion, we expect our function to fail since we constrain it in a way that it shouldn’t return any number. In the second example, we constrain it in a way where it should only be able to return <code>6</code>.</p>
<pre><code class="language-bash">FAIL  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer (1ms)
✓ generates a number within a defined range (24ms)
✕ generates a unique number (6ms)

● generates a unique number

expect(received).toBe(expected) // Object.is equality

Expected: "failed"
Received: 1
</code></pre>
<p>Our test fails. Since our code isn’t checking for anything or returning <code>failed</code>, this is expected. Although, it is possible your code received a 2 through 6.</p>
<p>How can we check if our function <em>can’t</em> find a unique number?</p>
<p>First, we need to do some sort of loop that will continue creating numbers until it finds one that’s valid. At some point though, if there are no valid numbers, we need to exit the loop so we avoid an infinite loop situation.</p>
<p>What we will do is keep track of each number we’ve created, and when we’ve created every number we can, and none of those numbers pass our unique check, we will break out of the loop and provide some feedback.</p>
<pre><code class="language-js">function getNewId(min = 0, max = 100, ids =[]) {
   let id;
   do {
      id = Math.floor(Math.random() * (max - min + 1)) + min;
   } while (ids.indexOf(id) &gt; -1);
   return id;
}
</code></pre>
<p>First, we refactored <code>getNewId()</code> to include a parameter that is a list of current ID’s. In addition, we updated our parameters to provide default values in the event they aren’t specified.</p>
<p>Second, we use a <code>do-while</code> loop since we don’t know how many times it will take to create a random number that is unique. For example, we could specify a number from 1 to 1000 with the <em>only</em> number unavailable being 7. In other words, our current ID’s only has a single 7 in it. Although our function has 999 other numbers to choose from, it could theoretically produce the number 7 over and over again. While this is very unlikely, we use a <code>do-while</code> loop since we are not sure how many times it will run.</p>
<p>Additionally, notice we break out of the loop when our ID <em>is</em> unique. We determine this with <code>indexOf()</code>.</p>
<p>We still have a problem, with the code currently how it is, if there are no numbers available, the loop will continue to run and we will be in an infinite loop. We need to keep track of all the numbers we create, so we know when we’ve run out of numbers.</p>
<pre><code class="language-js">function getRandomId(min = 0, max = 0, ids =[]) {
   let id;
   let a = [];
   do {
      id = Math.floor(Math.random() * (max - min + 1)) + min;
      if (a.indexOf(id) === -1) {
         a.push(id);
      }
      if (a.length === max - min + 1) {
         if (ids.indexOf(id) &gt; -1) {
            return 'failed';
         }
      }
   } while (ids.indexOf(id) &gt; -1);
   return id;
}
</code></pre>
<p>Here is what we did. We solve this problem by creating an array. And every time we create a number, add it to the array (unless it already in there). We know we’ve tried every number at least once when the length of that array is equal to the range we’ve chosen plus one. If we get to that point, we’ve created the last number. However, we still want to make sure the last number we created doesn’t pass the unique test. Because if it does, although we want the loop to be over, we still want to return that number. If not, we return “failed”.</p>
<pre><code class="language-bash">PASS  ./id.spec.js
✓ returns a random number (1ms)
✓ returns an integer (1ms)
✓ generates a number within a defined range (24ms)
✓ generates a unique number (1ms)

Test Suites: 1 passed, 1 total

Tests:       4 passed, 4 total
</code></pre>
<p>Congratulations, we can ship our ID generator and make our millions!</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Some of what we did was for demonstration purposes. Testing whether our number was within a specified range is fun, but that formula can be mathematically proven. So a better test might be to make sure the formula is called.</p>
<p>Also, you could get more creative with the random ID generator. For example, if it can’t find a unique number, the function could automatically increase the range by one.</p>
<p>One other thing we saw was how our tests and even specifications might crystalize a bit as we test and refactor. In other words, it would be silly to think nothing will change throughout the process.</p>
<p>Ultimately, test-driven development provides us with a framework to think about our code at a more granular level. It is up to you, the developer, to determine how granular you should define your tests and assertions. Keep in mind, the more tests you have, and the more narrowly focused your tests are, the more tightly coupled they become with your code. This might cause a reluctance to refactor because now you must also update your tests. There is certainly a balance in the number and granularity of your tests. The balance is up to you, the developer, to figure out.</p>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Difference Between a Framework and a Library ]]>
                </title>
                <description>
                    <![CDATA[ Developers often use the terms “library” and “framework” interchangeably. But there is a difference. Both frameworks and libraries are code written by someone else that is used to help solve common pr ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-difference-between-a-framework-and-a-library-bd133054023f/</link>
                <guid isPermaLink="false">66d4617d57503cc72873dee2</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jQuery ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vue.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 01 Feb 2019 17:28:23 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*tO6yh-odg-YDLazUQ6FWVQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Developers often use the terms “library” and “framework” interchangeably. But there is a difference.</p>
<p>Both frameworks and libraries are code written by someone else that is used to help solve common problems.</p>
<p>For example, let’s say you have a program where you plan on working with strings. You decide to keep your code DRY (don’t repeat yourself) and write some reusable functions like these:</p>
<pre><code class="language-js">function getWords(str) {
   const words = str.split(' ');
   return words;
}
function createSentence(words) {
   const sentence = words.join(' ');
   return sentence;
}
</code></pre>
<p>Congratulations. You’ve created a library.</p>
<p>There isn’t anything magic about frameworks or library. Both libraries and frameworks are reusable code written by someone else. Their purpose is to help you solve common problems in easier ways.</p>
<p>I often use a house as a metaphor for web development concepts.</p>
<p>A library is like going to Ikea. You already have a home, but you need a bit of help with furniture. You don’t feel like making your own table from scratch. Ikea allows you to pick and choose different things to go in your home. You are in control.</p>
<p>A framework, on the other hand, is like building a model home. You have a set of blueprints and a few <em>limited</em> choices when it comes to architecture and design. Ultimately, the contractor and blueprint are in control. And they will let you know when and where you can provide your input.</p>
<h4 id="heading-the-technical-difference">The Technical Difference</h4>
<p>The technical difference between a framework and library lies in a term called inversion of control.</p>
<p>When you use a library, you are in charge of the flow of the application. You are choosing when and where to call the library. When you use a framework, the framework is in charge of the flow. It provides some places for you to plug in your code, but it calls the code you plugged in as needed.</p>
<p>Let’s look at an example using jQuery (a library) and Vue.js (a framework).</p>
<p>Imagine we want to display an error message when an error is present. In our example, we will click a button, and pretend an error occurs.</p>
<h4 id="heading-with-jquery">With jQuery:</h4>
<pre><code class="language-html">// index.html
&lt;html&gt;
   &lt;head&gt;
      &lt;script src="https://code.jquery.com/jquery-3.3.1.min.js"
      &lt;/script&gt;
      &lt;script src="./app.js"&gt;&lt;/script&gt;
   &lt;/head&gt;
   &lt;body&gt;
      &lt;div id="app"&gt;
         &lt;button id="myButton"&gt;Submit&lt;/button&gt;
       &lt;/div&gt;
   &lt;/body&gt;
&lt;/html&gt;
// app.js
// A bunch of our own code, 
// followed by calling the jQuery library
let error = false;
const errorMessage = 'An Error Occurred';
$('#myButton').on('click', () =&gt; {
  error = true; // pretend some error occurs and set error = true
  if (error) {
    $('#app')
       .append(`&lt;p id="error"&gt;${errorMessage}&lt;/p&gt;`);
  } else {
    $('#error').remove();
  }
});
</code></pre>
<p>Notice how we use jQuery. <em>We</em> tell our program where we want to call it. This is much like going to a physical library and pulling certain books off the shelf as we want them.</p>
<p>That’s not to say jQuery functions don’t require certain inputs <em>once</em> we call them, but jQuery itself is a library of those functions. We are in charge.</p>
<h4 id="heading-with-vuejs">With Vue.js</h4>
<pre><code class="language-html">//index.html
&lt;html&gt;
   &lt;head&gt;
      &lt;script src="https://cdn.jsdelivr.net/npm/vue"&gt;&lt;/script&gt;
      &lt;script src="./app.js"&gt;&lt;/script&gt;
   &lt;/head&gt;
   &lt;body&gt;
      &lt;div id="app"&gt;&lt;/div&gt;
   &lt;/body&gt;
&lt;/html&gt;
const vm = new Vue({
  template: `&lt;div id="vue-example"&gt;
               &lt;button @click="checkForErrors"&gt;Submit&lt;/button&gt;
               &lt;p v-if="error"&gt;{{ errorMessage }}&lt;/p&gt;
             &lt;/div&gt;`,
  el: '#vue-example',
  data: {
    error: null,
    errorMessage: 'An Error Occurred',
  },
  methods: {
    checkForErrors()  {
      this.error = !this.error;
    },
  },
});
</code></pre>
<p>With Vue, we have to fill in the blanks. The Vue constructor is an object with certain properties. It tells us what it needs, and then behind the scenes, Vue decides when it needs it. Vue inverts the control of the program. We plug our code into Vue. Vue is in charge.</p>
<p>The difference whether it is a library or framework is whether or not there is an inversion of control.</p>
<h4 id="heading-a-note-on-being-opinionated">A note on being “opinionated”</h4>
<p>You’ll often hear frameworks and libraries described as “opinionated” or “un-opinionated.” These terms are subjective. They attempt to define the level of freedom a developer has when structuring their code.</p>
<p>Frameworks are more opinionated than not since — by definition — the inversion of control requires a concession of application-design freedom.</p>
<p>Again, the degree to which something is opinionated is subjective. For example, I personally would consider Angular a highly opinionated framework, and Vue.js a less-opinionated framework.</p>
<h3 id="heading-in-summary">In summary</h3>
<ul>
<li><p>Frameworks and libraries are both code written by someone else that helps you perform some common tasks in a less verbose way.</p>
</li>
<li><p>A framework inverts the control of the program. It tells the developer what they need. A library doesn’t. The programmer calls the library where and when <em>they</em> need it.</p>
</li>
<li><p>The degree of freedom a library or framework gives the developer will dictate how “opinionated” it is.</p>
</li>
</ul>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Finding Your Way With .Map() ]]>
                </title>
                <description>
                    <![CDATA[ The verbosity and elegance of a solution are driven by the tools we have to solve a particular problem. While the goal of problem-solving is to solve a problem, it’s methods should move towards the mo ]]>
                </description>
                <link>https://www.freecodecamp.org/news/finding-your-way-with-map-aecb8ca038f6/</link>
                <guid isPermaLink="false">66d4617473634435aafceff7</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Thu, 24 Jan 2019 18:01:19 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*1m6Z6xg7J2DDFOsK_-HgBw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The verbosity and elegance of a solution are driven by the tools we have to solve a particular problem. While the goal of problem-solving is <em>to solve a problem</em>, it’s methods should move towards the most elegant way possible. The journey towards such a solution, however, seems to lie on an asymptotic curve. Perfection gets closer and closer but forever remains out of reach.</p>
<h4 id="heading-the-problem">The Problem</h4>
<p>Imagine having an array and needing to change each element in the array. Maybe, for example, taking an array of heights in inches and needing to convert them to centimeters. Or possibly converting an array of temperatures in Celcius to Fahrenheit. If you are new to programming, your mind might immediately go to some form of a loop. And, guess what? I’m sure you could make it work.</p>
<p>However, I am here to give you one more tool — something to get you just a little closer to elegant: <code>Array.prototype.map()</code>.</p>
<p>The <code>map</code> method allows us to transform each element of an array, without affecting the original array. It’s considered a <em>higher-order function</em> and a functional-programming technique because it takes a function as an argument and we are performing computation without mutating the state of our application.</p>
<blockquote>
<p><code>Map</code> is a property that is inherited from the array prototype. Prototypes provide built-in-methods that objects come with (arrays are special types of objects in the eyes of JavaScript). While <code>map</code> may be a little more foreign, this prototype is no different than, for example, the <code>Array.length</code> prototype. These are simply methods that are baked into JavaScript. Array prototypes can be added and mutated by: <code>Array.prototype.&lt;someMethodHere&gt;</code> = ...</p>
</blockquote>
<p>By the end of this lesson, we will discover how <code>map</code> works and write our own array prototype method.</p>
<h4 id="heading-so-what-does-map-do">So what does .map() do?</h4>
<p>Let’s say you have an array of temperatures in Celsius that you want to convert to Fahrenheit.</p>
<p>There are a number of ways to solve this problem. One way may be to write a <code>for</code> loop to create an array of Fahrenheit temperatures from the given Celsius temperatures.</p>
<p>With the <code>for</code> loop we might write:</p>
<pre><code class="language-js">const celciusTemps = [22, 36, 71, 54];
const getFahrenheitTemps = (function(temp) {
   const fahrenheitTemps = [];
   for (let i = 0; i &lt; celciusTemps.length; i += 1) {
      temp = celciusTemps[i] * (9/5) + 32
      fahrenheitTemps.push(temp);
   }
   console.log(fahrenheitTemps); [71.6, 96.8, 159.8, 129.2
})();
</code></pre>
<p>A couple things to note:</p>
<ol>
<li><p>It works.</p>
</li>
<li><p>We use an Immediately Invoked Function Expression (IIFE) to avoid also having to call the function.</p>
</li>
<li><p>It’s a bit verbose and not very elegant.</p>
</li>
</ol>
<p><code>Map</code> allows us to take the above code and refactor it to the following:</p>
<pre><code class="language-js">const fahrenheitTemps = celciusTemps.map(e =&gt; e * (9/5) + 32);
console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]
</code></pre>
<h4 id="heading-so-how-does-map-work">So how does map work?</h4>
<p><code>Map</code> takes a function and applies that function to each element in the array. We could write <code>map</code> a bit more verbose with ES5 to see this a bit more clearly.</p>
<pre><code class="language-js">const fahrenheitTemps = celciusTemps
   
   .map(function(elementOfArray) {
      return elementOfArray * (9/5) + 32;
   });
console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]
</code></pre>
<p>If our map function could say what it is doing, it would say:</p>
<p>“For every element in the array, I multiply it by (9/5), then add 32. When that is done, I return the result as an element in a new array called fahrenheitTemps.”</p>
<p>Let’s look at a more common use case. Let’s assume we have an array of <code>people</code> objects. Each object has a <code>name</code> and <code>age</code> key-value-pair. We want to create a variable that is just the names of everyone in the array. With our <code>for</code> loop method we might write:</p>
<pre><code class="language-js">const people = [
   {name: Steve, age: 32},
   {name: Mary, age: 28},
   {name: Bill, age: 41},
];
const getNames = (function(person) {
   const names = [];
   for (let i = 0; i &lt; people.length; i += 1) {
      name = people[i].name;
      names.push(name);
   }
   console.log(names); // [Steve, Mary, Bill];
})();
</code></pre>
<p>With <code>map</code>:</p>
<pre><code class="language-js">const names = people.map(e =&gt; e.name);
console.log(names) // [Steve, Mary, Bill];
</code></pre>
<p>Notice here we don’t transform anything, we simply return the key-value-pair <code>name</code>.</p>
<p>Again, the <code>for</code> loops works. But, it is verbose, and we have to create a new custom function every time we want to do a different transformation. A principal part of programming is writing DRY code (Don’t Repeat Yourself). These higher-order functions such as map, allows us to do more complex programming in fewer lines of code than we could without them.</p>
<h4 id="heading-reinventing-the-wheel">Reinventing the wheel:</h4>
<p>To better understand what is happening under the hood, we will make our own map function that we will attach to the array prototype.</p>
<p>First, to attach a prototype method to an Array, we will write:</p>
<p><code>Array.prototype.&lt;yourMethodHere&gt;</code></p>
<p>so for us:</p>
<p><code>Array.prototype.myMap = &lt;our code&gt;</code></p>
<p>But, what will our code be?</p>
<p>We already have the logic we need from the <code>for</code> loops above. All we need to do is refactor it a bit. Let’s refactor the last function we wrote <code>getNames()</code>.</p>
<p>Remember, this function took a person (in other words an element of our array), did a custom transformation to that element (with the <code>for</code> loop and some logic), and returned an array of names (or a new array).</p>
<pre><code class="language-js">const getNames = (function(person) {
   const names = [];
   for (let i = 0; i &lt; people.length; i += 1) {
      name = people[i].name;
      names.push(name);
   }
   console.log(names); // [Steve, Mary, Bill];
})();
</code></pre>
<p>First, let’s change the name of our function. After all, this new method doesn’t assume to know what kind of array it will be acting upon:</p>
<pre><code class="language-js">const myMap = (function(person) { //Changed name
   const names = [];
   for (let i = 0; i &lt; people.length; i += 1) {
      name = people[i].name;
      names.push(name);
   }
   console.log(names); // [Steve, Mary, Bill];
})();
</code></pre>
<p>Second, we are creating our own version of <code>.map()</code>. We know this will take a function that the user provides. Let’s change the parameter our function takes:</p>
<pre><code class="language-js">// It is a bit verbose, but a very clear parameter name
const myMap = (function(userProvidedFunction) { 
   const names = [];
   for (let i = 0; i &lt; people.length; i += 1) {
      name = people[i].name;
      names.push(name);
   }
   console.log(names); // [Steve, Mary, Bill];
})();
</code></pre>
<p>Finally, we have no idea what array this method will act on. So, we can’t refer to <code>people.length</code> but we <em>can</em> refer to <code>this.length</code>. <code>this</code>, will return the array the method is acting on. Also, let's clean up some of the other variable names:</p>
<pre><code class="language-js">const myMap = (function(userProvidedFunction) { 
   // change variable name
   const newArr = [];
   // use "this.length"   
   for (let i = 0; i &lt; this.length; i += 1) { 
   
      // use "this[i]", and change variable name      
      const newElement = this[i];
  
      // update the array we push into
      newArr.push(newElement); 
   }
   // Return the newly created array
   return newArr; 
})();
</code></pre>
<p>We’re almost there, but there is one thing we are forgetting. We haven’t transformed the array! All we’ve done above is return the old array. We have to apply the user-provided function to each element of the array:</p>
<pre><code class="language-js">const myMap = (function(userProvidedFunction) { 
   const newArr = [];
   for (let i = 0; i &lt; this.length; i += 1) {
      
      /* Transform the element by passing it into the 
       * user-provided function
       */
      const newElement = userProvidedFunction(this[i]); 
      
      newArr.push(newElement); 
   }
   return newArr;
})();
</code></pre>
<p>Finally, we can attach our new function to<code>Array.prototype</code>.</p>
<p><code>Array.prototype.myMap = myMap;</code></p>
<p>A final sanity check:</p>
<pre><code class="language-js">const myArray = [1, 2, 3];
// Multiply each element x 2
const myMappedArray = myArray.myMap(e =&gt; e * 2)
console.log(myMappedArray) // [2, 4, 6];
</code></pre>
<h4 id="heading-summary">Summary</h4>
<p><code>Map</code> is a prototype method offered by arrays. Behind the scenes, it iterates through the array, applying a user-provided function to each element. Ultimately, it returns a new array with the transformed values. It does this without mutating the original array. Because the parameter it takes is a function, it is considered a higher-order function. In addition, its use falls into the functional programming paradigm.</p>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
