<?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" version="2.0"><channel><title><![CDATA[Codefriar's blog]]></title><description><![CDATA[Codefriar's blog]]></description><link>https://codefriar.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1695448876395/8w2Uq1Rv1.png</url><title>Codefriar&apos;s blog</title><link>https://codefriar.com</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 10 Apr 2026 11:36:22 GMT</lastBuildDate><atom:link href="https://codefriar.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Hey #SalesforceDevs! do you suffer from mild to moderate JavaScript? If so, Async/Await can help.]]></title><description><![CDATA[Recently had a broseph tell me ‘Bro, Fr Fr do you even know how Async/Await works! Ya gotta use Promises.’
Honestly that bothered me more than a perky product owner up in my grill on a 8am standup after the dev team worked all weekend because said pr...]]></description><link>https://codefriar.com/hey-salesforcedevs-do-you-suffer-from-mild-to-moderate-javascript-if-so-asyncawait-can-help</link><guid isPermaLink="true">https://codefriar.com/hey-salesforcedevs-do-you-suffer-from-mild-to-moderate-javascript-if-so-asyncawait-can-help</guid><category><![CDATA[Salesforce]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[asynchronous]]></category><dc:creator><![CDATA[Kevin Poorman]]></dc:creator><pubDate>Wed, 22 Jan 2025 23:39:12 GMT</pubDate><content:encoded><![CDATA[<p>Recently had a broseph tell me ‘Bro, Fr Fr do you even know how Async/Await works! Ya gotta use Promises.’</p>
<p>Honestly that bothered me more than a perky product owner up in my grill on a 8am standup after the dev team worked all weekend because said product owner can’t say no.</p>
<p>So I looked at myself in the mirror through a fork - turns out I don’t look good behind bars - and wrote this. So lets all sit around this dumpster fire and discuss JavaScript concurrency! This quest has three chapters.</p>
<h2 id="heading-chapter-1-callbacks-aka-the-ancient-times-when-jquery-ruled-the-web-and-xmlhttprequest-was-a-novelty">🔄 Chapter 1: Callbacks (aka The Ancient Times when jQuery ruled the web and <strong>XMLHttpRequest</strong> was a novelty)</h2>
<p>Back then, JavaScript was a relative babe, and as we all know from the Christmas songs, you have to wrap the babe in swaddling clothes - or in this case, callbacks. That led to developers writing callback hell. Yo check my comments here.</p>
<pre><code class="lang-jsx">getAccount(accountId, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">account</span>) </span>{ <span class="hljs-comment">// getAccount()'s second argument is an anonymous function. AKA Callback. This anonymous method is executed by the JavaScript overlords when getAccount is finished.  </span>
    getContacts(account.Id, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">contacts</span>) </span>{ <span class="hljs-comment">// Also uses Callbacks</span>
        getOpportunities(contacts[<span class="hljs-number">0</span>].Id, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">opps</span>) </span>{ <span class="hljs-comment">// If you guessed also a callback, you win.</span>
            <span class="hljs-comment">// Welcome to the pyramid of doom!</span>
            <span class="hljs-comment">// Population: Your sanitys</span>
            <span class="hljs-comment">// Work harder, no one cares.</span>
        });
    });
});
</code></pre>
<p>We called this "callback hell" for a reason, folks. I once - and I can’t make this sh*t up - saw a function that had 33 nested callback methods. In a textbook. My therapist reminds me to go pet the dog at times like this. 🐕 If you’re wondering why this is terrible - well, I mean it works but that’s about the only bambi-kind thing I can say about it. This gets hard to break into maintainable-sized-methods and just … understanding the flow can be a challenge. Sure there were things you could do to de-structure this by calling named functions instead of anonymous ones, but … I don’t remember seeing a lot of that.</p>
<h2 id="heading-chapter-2-promises-the-betamax-of-javascript">⚡ Chapter 2: Promises - The Betamax of JavaScript</h2>
<p>So we hated on Callback hell an Promises came along and were like "Hold my coffee." ☕ Honestly most people were like ‘wtf is a promise’? Promises have a bit of a marketing problem. First, it’s a word that’s abused by politicians, managers everyone knows <em>that</em> PM. Secondly, it’s not sufficiently esoteric that you can Google it and get a very narrow set of explanations. Seriously, try Googling Promise; Yeah. Now try Googling ‘monad’. I’ll wait. See the difference? Personally, I think we should have called Promises ‘monadic composition’. Cause that’s … clearer. Check out this code while pondering my sanity.</p>
<pre><code class="lang-jsx">getAccount(accountId)
    .then(<span class="hljs-function"><span class="hljs-params">account</span> =&gt;</span> getContacts(account.Id)) <span class="hljs-comment">// look ma, no callback methods!</span>
    .then(<span class="hljs-function"><span class="hljs-params">contacts</span> =&gt;</span> getOpportunities(contacts[<span class="hljs-number">0</span>].Id)) <span class="hljs-comment">// OMG None here either!</span>
    .then(<span class="hljs-function"><span class="hljs-params">opps</span> =&gt;</span> {
        <span class="hljs-comment">// Look Ma, no pyramid!</span>
    })
    .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
        <span class="hljs-comment">// One error handler to rule them all</span>
    });
</code></pre>
<p>Ok so the key takeaway for promises is this: <strong>A promise provides flow control (try/catch) for asynchronous work by allowing you to attach work - functions - to be executed <em>after</em> the previous step concludes.</strong> Promises use the <code>then</code> method to chain work together. Grammatically it makes sense right? do this, then that, then this other thing… Still not sure why they’re called ‘Promises’ but there’s a whole heap of JavaScript that falls in to the ‘<a target="_blank" href="http://WTFJS.com">WTFJS.com</a>’ bucket. Honestly, JS as a language has all the hallmarks of a circular family tree, but … I don’t care what people say, I say it’s sweet.</p>
<p>Regardless of naming issues, Promises make our lives easier if for no other reason than there’s much less code to reason about. They’re also … just conceptually simpler. Once you grasp the language guarantee that each <code>then()</code> function is blocked from executing until the previous one completes… you’re good to go.</p>
<p>This is, as they say in my hood, ‘much better’. But let’s be honest, it feels a bit like someone shoehorned that into the language. (oh wait…) I mean, wouldn’t it be nice if the concurrency framework was keywords or operators instead of methods?</p>
<h2 id="heading-chapter-3-asyncawait-the-ts-evermore-era-of-javascript-concurrency-her-best-era-there-i-said-it">🌟 Chapter 3: Async/Await - The T.S. Evermore Era of JavaScript concurrency (Her best era. There, I said it.)</h2>
<p>Async and Await are keywords. Inside any method that you’ve prefaced with <code>async</code> you can use the <code>await</code> keyword</p>
<p>Here's the plot twist Broseph: Async/Await isn't new bbq sauce - it's just lipstick on the promise of a pig. AKA Promises wearing a really flattering Chelsea jersey. Check my comments yo.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getAccountData</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// &lt;- we start with that async keyword. </span>
    <span class="hljs-keyword">try</span> { <span class="hljs-comment">// but wait, what's this? more on that later larry.</span>
        <span class="hljs-keyword">const</span> account = <span class="hljs-keyword">await</span> getAccount(accountId); <span class="hljs-comment">// see that await? that stops execution of the following lines until it's completed. </span>
        <span class="hljs-keyword">const</span> contacts = <span class="hljs-keyword">await</span> getContacts(account.Id); <span class="hljs-comment">// Yep, another pause.</span>
        <span class="hljs-keyword">const</span> opps = <span class="hljs-keyword">await</span> getOpportunities(contacts[<span class="hljs-number">0</span>].Id); <span class="hljs-comment">// one more pause for good measure.</span>
        <span class="hljs-comment">// Same Promise chain, but reads like synchronous code! </span>
    } <span class="hljs-keyword">catch</span>(error) {
        <span class="hljs-comment">// Still just a .catch() under the hood which is how we can use a try/catch with async code</span>
    }
}
</code></pre>
<p>So here we got some asynchronous code that <em>reads</em> like synchronous code. And that’s pretty badass. Here’s your key takeaway for Async/Await - It allows developers to write <em>Async code that reads Synchronously. Keep in mind that every</em> <code>await</code> <em>keyword means the rest of the method is paused until the await’d line has completed (or errored out).</em></p>
<p>I, for one, think this is the only way one should write Async JavaScript. And honestly, you’ve read this far, so you must think this dog can hunt. But in my head (and inbox) I’m hearing people complain that Async/Await and Promises do different things so… Ok Broseph… here’s how Async/Await <em>works under the covers:</em> Every <code>async</code> function actually returns a Promise. This is literally(Yeah, read that with an exasperated valley accent) the same as our Promise example above:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// These are functionally identical!</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getData</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> fetchSomething();
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getData</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.resolve(fetchSomething());
}
</code></pre>
<p>🖖 So what does this mean for you?</p>
<p>If’n your a Salesforce dev writing some mighty fine LWC’s - you should use Async/Await. Anything else makes Codey Cry. Seriously, like you rubbed his eyes with onions. Just Bawling. Don’t do it, he’s not done nothing to deserve it. Even the creepy animatronic version.</p>
<p>Today You learned? You can Await your imperatively executed wire methods. <code>const foo = await myPreciousApexMethod()</code></p>
<p>Next time someone tells you Promises are better/faster/stronger/different than Async/Await, ask them if they’re interested in signing a petition to ban dihydrogen-monoxide…</p>
<p>Thank you for coming to my ted talk, and remember only you can prevent stupid code.</p>
]]></content:encoded></item><item><title><![CDATA[Universal Invocable]]></title><description><![CDATA[In a world where developers battle the relentless forces of boilerplate code, a new hero has emerged from the depths of Apex! Get ready to embark on an epic journey as we unveil Universal Invocable, the groundbreaking feature that's about to change t...]]></description><link>https://codefriar.com/universal-invocable</link><guid isPermaLink="true">https://codefriar.com/universal-invocable</guid><category><![CDATA[Salesforce]]></category><category><![CDATA[salesforce development]]></category><category><![CDATA[Apex]]></category><category><![CDATA[flow]]></category><dc:creator><![CDATA[Kevin Poorman]]></dc:creator><pubDate>Sat, 23 Sep 2023 05:54:14 GMT</pubDate><content:encoded><![CDATA[<p>In a world where developers battle the relentless forces of boilerplate code, a new hero has emerged from the depths of Apex! Get ready to embark on an epic journey as we unveil <em>Universal Invocable</em>, the groundbreaking feature that's about to change the game in Salesforce Flow development!</p>
<p>🌟 <em>Cue dramatic music</em> 🌟</p>
<p>Introducing Universal Invocable[1], the elegant solution that lets developers expose multiple Apex methods to flows without drowning in a sea of tiny, one-method classes. Say goodbye to the days of writing one-class-per-invocable-method. Universal Invocable is here to save the day!</p>
<p>But hold onto your developer hats, because harnessing the power of Universal Invocable does require a (teensy) bit of effort. You'll need to extend your classes with the provided <code>UFInvocable</code> class, masterfully patterned after Salesforce's own <code>Callable</code> Interface. Don't worry; this hero class is fully bulkified, enabling your flows to call multiple Apex methods from the same Action element!</p>
<p>🚀 <em>Explosions in the background</em> 🚀</p>
<p>But that's not all! Universal Invocable comes equipped with the incredible <code>UniversalInvocable</code> Invocable Action. This action is your trusty sidekick, capable of calling any Apex method from classes that extend the <code>UFInvocable</code> class. Together they're an unstoppable duo, ready to conquer any development challenge in their path!</p>
<p>🌠 <em>Epic montage of developers coding</em> 🌠</p>
<p>To get started on your own heroic journey with Universal Invocable, head over to the <a target="_blank" href="https://github.com/codefriar/ApexKit/tree/main/force-app/main/Universal%20Flow%20Invocable">source code</a>. For some light, and totally not dry, reading on the <code>Callable</code> Interface, <code>UFInvocable's</code> soul sister, consult the <a target="_blank" href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_interface_System_Callable.htm">Callable Interface documentation</a>.</p>
<p>🚨Shut up and take my money! 🚨</p>
<p>For now, the installation instructions are simple: manually copy the Universal Invocable classes from <a target="_blank" href="https://github.com/codefriar/ApexKit/tree/main/force-app/main/Universal%20Flow%20Invocable">the source link into your org</a>. Be sure to snag the <a target="_blank" href="https://github.com/codefriar/ApexKit/tree/main/force-app/main/Universal%20Flow%20Invocable/flows">example Flow to get a sense of how to invoke this from Flow!</a> (this is not a paid product. <a target="_blank" href="https://github.com/codefriar/apexkit">It’s open source, and freely available here.)</a></p>
<p>🔥 TL;DR; 🔥</p>
<p>Who is this for? Salesforce Developers who want to expose Apex methods to Flow without littering their org with a ton of Single-method classes.</p>
<p>What does this do? Establishes a ‘universal’ way of invoking almost any Apex code from your org through a single InvocableAction.</p>
<p>Seriously? Hell yes. You just need to extend the provided <code>UFInvocable</code> class and create the <code>call()</code> method.</p>
<p>What doesn’t it do? Slice, dice, and roast chickens work automagically without you having to do anything. You, a Salesforce developer, will need to add a small bit of Apex to the classes you want to expose, but this should be less work than generating a one-off, single-method <code>@invocableMethod</code> classes.</p>
<p>💳 Who made this? 💳</p>
<p>Listen, y’all. Back in August, I was laid off. I’ve been putting some of my (f)unemployed time into documenting and building on my pet project - ApexKit. I had the idea for Universal Invocable and put together a prototype using the <code>Callable</code> interface. I asked <a target="_blank" href="https://www.linkedin.com/in/brianfear/">Brian Fear</a> - better known as <a target="_blank" href="https://salesforce.stackexchange.com/users/2984/sfdcfox">sfdcfox</a> - to give me a code review, and not only did he fix my stupid dyslexic typos, but he also hit upon and implemented the bulkification that enables you to call multiple Apex methods from the same action block. In short, he took my Awesome idea (™) and made it positively Epic. If you’ve not heard, Brian is also (f)unemployed at the moment. If you like Universal Invocable, please consider throwing some love our way.</p>
<p>If you feel so moved, please do boost this post, and here’s our relevant information:</p>
<p><strong>Brian Fear, aka SfdcFox</strong></p>
<p>Paypal: <a target="_blank" href="mailto:brian.m.fear@gmail.com">brian.m.fear@gmail.com</a><br />Venmo: brianmfear<br />Buy Me A Coffee: <a target="_blank" href="https://buymeacoffee.com/brainmfear">brianmfear</a><br />Zelle: <a target="_blank" href="mailto:brianmfear@gmail.com">brianmfear@gmail.com</a><br />Cash App: $BrianFear</p>
<p><strong>Kevin Poorman, aka Codefriar</strong></p>
<p>Paypal: <a target="_blank" href="mailto:kjp@codefriar.com">kjp@codefriar.com</a><br />Venmo: Kevin-Poorman<br />Buy Me A Coffee: <a target="_blank" href="https://www.buymeacoffee.com/codefriar">Codefriar</a></p>
<p>[1]: Look, naming things is hard. I wanted to name this Project Hulk. (Because Hulk is easily the best Avenger. After all, he’s had a traumatic accident that granted him superpowers that he’s only able to access while he’s struggling with the worst aspects of himself, and he’s <strong><em>still</em></strong> attempting to do good for the rest of the world.) But well, Marvel said no. ¯\<em>(ツ)</em>/¯</p>
]]></content:encoded></item></channel></rss>