<?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[Dushyanth]]></title><description><![CDATA[Dushyanth]]></description><link>https://blog.dushyanth.in</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1768554623713/1c0599b9-1b04-4ebe-93ea-cfd0656c44e8.webp</url><title>Dushyanth</title><link>https://blog.dushyanth.in</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Apr 2026 21:50:58 GMT</lastBuildDate><atom:link href="https://blog.dushyanth.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Curo x Rive]]></title><description><![CDATA[I came across an EV fleet charging platform and saw a chance to push what a driver app could be.
https://youtu.be/q_OR0ewnfHg
 
Most charging apps just display data, charger location, status, availability. Functional, but flat. I wanted to see what h...]]></description><link>https://blog.dushyanth.in/curo-x-rive</link><guid isPermaLink="true">https://blog.dushyanth.in/curo-x-rive</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Tue, 16 Dec 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757939211139/90f9fb37-f8fd-44b1-8cdd-0b6ee48d9ed5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I came across an EV fleet charging platform and saw a chance to push what a driver app could be.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/q_OR0ewnfHg">https://youtu.be/q_OR0ewnfHg</a></div>
<p> </p>
<p>Most charging apps just display data, charger location, status, availability. Functional, but flat. I wanted to see what happens when you treat the interface as a craft problem: how do you make real-time charging data feel responsive and alive?</p>
<p>I built it with <strong>React Native (Expo)</strong> and <strong>Rive</strong>, which let me create interactions that react to live data and user input. Charging status transitions smoothly. Animations respond to actual charger states. The whole interface feels like it's breathing with the data behind it.</p>
<p>It's a charging app, but built like you'd build a premium product.</p>
<h2 id="heading-mood-board">Mood Board</h2>
<p>I started by building a mood board to shape the app flow and interactions.</p>
<p><a target="_blank" href="https://excalidraw.com/#json=6IuPPaDgiAE1vi3QmDjCn,jsHqv59BJZjhy6TY8nNi7g">Moodboard Link: Excalidraw</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758448693830/8a794ab7-4836-412d-9e93-c70c9cb6f050.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-home">Home 🏠</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758454505087/f7f963cb-9143-4390-920f-e4413b7a7062.png" alt class="image--center mx-auto" /></p>
<p>The <strong>Home screen</strong> is built using three Rive artboards:</p>
<ul>
<li><p><strong>Battery board</strong></p>
</li>
<li><p><strong>Charge unit</strong></p>
</li>
<li><p><strong>Main Home layout</strong></p>
</li>
</ul>
<p>The driver’s vehicle takes center stage, displaying interactive stats like charge prompts, charging status, and notifications. As a playful touch, tapping the vehicle toggles the headlights on and off, a fun detail made seamless with Rive’s state machine.</p>
<p><a target="_blank" href="https://rive.app/marketplace/24425-45629-ev-charge/">Check out the Rive Interaction</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758450897056/13708d9d-c49d-4d6f-bff8-6dfb0a990313.gif" alt class="image--center mx-auto" /></p>
<p>The chargeunit and the Battery board artboards are nested in the main Home artboard and these are turned active based on input tied to the state machine; Useful to create conditional interactions/animations based on data received from the backend.</p>
<p>The charger has 2 inputs to trigger - “isCharging” and “showShadow”</p>
<ul>
<li><p><code>isCharging</code> → activates charging animation.</p>
</li>
<li><p><code>showShadow</code> → casts a glow when headlights are on.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758450506110/5b32c143-f77c-4d57-b4b5-24ab2411832e.gif" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757941025533/07e0d2be-56fc-48f0-a164-a602964b0089.png" alt class="image--center mx-auto" /></p>
<p>The <strong>charge unit</strong> design draws inspiration from Tesla chargers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758448363779/6f5e88be-f6f7-4519-8895-6d2f0243fa09.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-map-lets-get-charge">Map - Let’s get charge!</h2>
<p>The map is built using the <strong>react-native-maps</strong> package, which runs on the device’s native maps library under the hood. This gives us the flexibility to add <strong>custom markers</strong>.</p>
<p>I had previously used custom images as markers, but I was curious about pushing it further. I came across a post on <a target="_blank" href="https://x.com/drcoderz/status/1844027815794229641">Twitter by Roman</a>, where he showcased using <strong>Rive components as map markers in Flutter</strong>, and that inspired me to try the same in React Native.</p>
<blockquote>
<p><strong>Note:</strong> At the time of testing, the Expo maps package was not yet compatible with Rive assets as markers. To get it working, you’ll need to use an Expo development build with <strong>react-native-maps</strong>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758451217294/14c9fa9f-15f6-4e22-aa3e-18c0d8e45364.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-markpin-interactions">Markpin Interactions 📍</h3>
<p>The state machine for markpin consists of 2 inputs - “portal” and “selected”</p>
<ul>
<li><p><code>selected</code> → this gets active when the user clicks on a specific markpin on the map; it bounces up and down.</p>
</li>
<li><p><code>portal</code> → when the user proceeds to book a charger at a specific location; we transition to the portal state on the user click event. We get to see the markpin morphing as a mascout going into the portal to get to the Charge station!</p>
<p>  <a target="_blank" href="https://rive.app/marketplace/24430-45634-markpin-interactions/">Check out the Rive Interaction</a></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758449955593/ab5056d1-d8ba-4de4-9bf9-77e22ccfd302.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-portal-suspense">Portal Suspense</h3>
<p>The Idea is to change the marker to a mascot on portal and suspend while we fetch data from the backend; When a user books a charger, the marker transforms into a mascot; ears flapping, fiery eye glowing, suspended midair until the backend responds. This keeps users entertained during loading, turning a typical “waiting state” into a moment of delight.</p>
<p><a target="_blank" href="https://rive.app/marketplace/24427-45631-portal-suspense/">Check out the Rive Interaction</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758452311767/36ddff51-1fdf-4d91-9c1a-87c139295f80.gif" alt class="image--center mx-auto" /></p>
<p>The mascot hovers in midair, ears flapping in the rush of wind as it scouts for the charge station. Once the backend responds, the state changes and the mascot swoops down to the selected charge station for booking.</p>
<p>This was an experiment to explore how interactions like these can keep users engaged during loading states. Unlike Lottie animations, which are static, Rive makes it possible to create <strong>dynamic, state-driven interactions</strong> that feel alive and responsive.</p>
<h2 id="heading-scan-in-3-2-1">Scan in 3, 2, 1!</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758453328095/435dddd9-4716-48ae-b5a8-5d36851b547e.png" alt class="image--center mx-auto" /></p>
<p>The Scanner page was created in Rive and includes a transparent area where we can overlay the camera display, allowing the user to see the QR code in real time. The main exploration here was demonstrating that <strong>Rive assets can coexist with native elements</strong>, positioned in front of or behind them. This sparked a thought: perhaps in the near future, entire UIs could be generated in Rive, with developers simply plugging in business logic :D a concept that feels both crazy and exciting.</p>
<p><a target="_blank" href="https://rive.app/marketplace/24428-45632-scan-in-3-2-1/">Check out the Rive Interaction</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758453725095/c29e5134-e354-41c6-a093-5484e3bc20de.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-successful-transaction">Successful Transaction</h3>
<p>After the user scans the QR code, a transaction is initiated to allocate a charge point. Since this process takes some time on the backend, it’s important to let the user know that it is in progress. To address this, I created a loader animation where the vehicle and charger sync to establish a connection, looping until the backend confirms with an “OK”</p>
<p><a target="_blank" href="https://rive.app/marketplace/24429-45633-successful-transaction/">Check out the Rive Interaction</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758454258003/892a7b4f-8b26-4b81-bb6a-25060eedb938.gif" alt class="image--center mx-auto" /></p>
<p>When the transaction is successful, the state machine updates the <code>AnimationState</code> from “0” to “1” to indicate completion. Seeing this transition play out is truly delightful!</p>
<h2 id="heading-splash-screen">Splash Screen</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758454757967/2d5732eb-e802-461b-ac58-da64fc06324c.gif" alt class="image--center mx-auto" /></p>
<p>The splash screen ties the entire theme together. The background transitions through four symbolic elements, each reflecting <strong>Curo’s mission and vision</strong>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758455468962/eb34e0db-d2a2-4cec-a180-d4edd36165a0.png" alt class="image--center mx-auto" /></p>
<p><strong>Rocks → Foundation / Resources</strong><br />Just like minerals form the foundation for batteries, Curo builds the infrastructure foundation for EV fleets. Rocks = strength, reliability, essential resources.</p>
<p><strong>Ocean → Flow / Connectivity</strong><br />The ocean symbolizes vast, seamless movement - Curo’s Virtual Depot network enables fluid, borderless EV operations, like an ocean current powering global mobility.</p>
<p><strong>Vegetation / Moss → Sustainability / Renewal</strong><br />Moss thrives anywhere, quietly regenerating ecosystems - like Curo’s platform, which turns underused assets into living infrastructure that supports a greener fleet ecosystem.</p>
<p><strong>Mars → Innovation / Future Vision</strong><br />Mars represents bold frontiers - Curo is pioneering the future of EV charging at scale, taking fleets from today’s challenges to tomorrow’s limitless opportunities.</p>
<h2 id="heading-looking-ahead">Looking Ahead</h2>
<p>As interactive technologies evolve and motion becomes central to every app experience, interfaces are no longer just screens. They respond. They guide. They invite you in.</p>
<p>The way we interact with apps is changing, and there’s so much potential to make every interaction feel alive and meaningful.</p>
<p>I’d love to hear what you think. Feel free to drop me a line at <a target="_blank" href="mailto:hey.dushyanth@gmail.com"><strong>hey.dushyanth@gmail.com</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Vibe Match: Building AI-Powered Vibe-Based Search]]></title><description><![CDATA[While many platforms allow you to filter profiles by structured attributes - like hair style, eye color, or hair color - I noticed a big opportunity: what if we could also search by vibe? Things like “loves dancing”, “who loves dogs”, or “bookworm wh...]]></description><link>https://blog.dushyanth.in/vibe-match</link><guid isPermaLink="true">https://blog.dushyanth.in/vibe-match</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sat, 17 May 2025 19:18:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747503580312/2d86ce62-15e5-4210-a5a9-907eab365c19.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While many platforms allow you to filter profiles by structured attributes - like hair style, eye color, or hair color - I noticed a big opportunity: what if we could also search by <em>vibe</em>? Things like <em>“loves dancing”</em>, <em>“who loves dogs”</em>, or <em>“bookworm who travels”</em>.</p>
<p>Traditional filter systems aren’t built for this. So I built a concept demo called <strong>Vibe Match</strong>, designed to showcase how AI and vector search can make profile discovery more human and intuitive.</p>
<p>In this post, I’ll walk you through how it works.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/rP8v59olGQA">https://youtu.be/rP8v59olGQA</a></div>
<p> </p>
<h2 id="heading-the-great-wall-of-filters"><strong>The Great Wall of Filters</strong></h2>
<p>Most platforms rely on rigid filters. The more filters you add, the more complex the UI and query logic becomes. You quickly end up with a <strong>Great Wall of Filters</strong>, and even then, you can’t search for intangible, unstructured traits like personal interests or personality quirks.</p>
<p>That’s where vibe-based search comes in.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747502994948/2a63399e-67f3-4e92-b3bd-a07d6fbb6786.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-high-level-solution">High-Level Solution</h2>
<p>The idea is simple:</p>
<ul>
<li><p>Keep structured filters for things like eye color or hair style.</p>
</li>
<li><p>Handle unstructured vibe preferences using <strong>vector search</strong>.</p>
</li>
<li><p>Use an AI model to intelligently parse the user’s query and split it into structured filters and vibe-based search terms.</p>
</li>
</ul>
<h2 id="heading-how-vibe-match-works">How Vibe Match Works?</h2>
<h4 id="heading-1-data-preparation">1. Data Preparation</h4>
<ul>
<li><p>Donor profiles have both structured attributes (e.g. hair color) and unstructured bios/interests.</p>
</li>
<li><p>I preprocess the unstructured text (bios, hobbies, passions, goals, strengths) and convert them into <strong>vector embeddings</strong>.</p>
</li>
<li><p>These embeddings are stored in a <strong>vector database</strong>. For this demo, I used <strong>Datastax Astra</strong>, but this would work with Pinecone, Weaviate, or others.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747503518182/c6a19773-8079-4508-b116-33dfa8b84126.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h4 id="heading-2-user-query-handling">2. User Query Handling</h4>
<p>When a user enters a query like:</p>
<blockquote>
<p><em>“donors who love dancing and have brown hair”</em></p>
</blockquote>
<ul>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747504437597/9a9f7044-bee2-4602-91cf-3674d4900286.png" alt class="image--center mx-auto" /></p>
<p>  The query is sent to the backend server.</p>
</li>
<li><p>It’s processed by an <strong>LLM (via OpenAI’s API) using structured output parsing</strong>.</p>
</li>
</ul>
<p>I defined a <strong>Zod schema</strong> to tell the model what structured fields to extract (like eye color, hair type etc.).<br />Currently, I’ve provided support for the following filters, we can extend it to support more.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>hair_type</td><td>hair_color</td><td>hair_texture</td><td>eye_color</td></tr>
</thead>
<tbody>
<tr>
<td>dimples</td><td>siblings</td><td>dominant_hand</td><td>freckles</td></tr>
<tr>
<td>marital_status</td><td>complexion</td><td>education_level</td><td>jewish_ancestory</td></tr>
<tr>
<td>logical_creative</td><td>serious_silly</td><td>introvert_extrovert</td><td>allergies</td></tr>
<tr>
<td>dental_work</td><td>egg_retrieval</td><td>vision_quality</td><td>diet</td></tr>
<tr>
<td>mathematical_ability</td><td>scientific_ability</td><td>singing_ability</td></tr>
</tbody>
</table>
</div><ul>
<li><p>The LLM returns a structured JSON with:</p>
<ul>
<li>Detected filters.</li>
</ul>
</li>
</ul>
<p><strong>Example Response:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"filters"</span>: {
    <span class="hljs-attr">"hair_color"</span>: <span class="hljs-string">"brown"</span>
  },
  <span class="hljs-attr">"vibeQuery"</span>: <span class="hljs-string">"donors who love dancing"</span>
}
</code></pre>
<h4 id="heading-2-vector-search-filtered-results">2. Vector Search + Filtered Results</h4>
<ul>
<li><p>The <code>vibeQuery</code> is converted into a vector embedding.</p>
</li>
<li><p>I run a <strong>Vector search</strong>:</p>
<ul>
<li><p>Apply the structured filters to narrow down profiles.</p>
</li>
<li><p>Use the vibe query embedding to find the most similar donor profiles based on vibe.</p>
</li>
</ul>
</li>
</ul>
<p>This combo delivers results that are both relevant and intuitive with a confidence score.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747504499172/63b75d20-9a4b-485d-816f-f0cf9f04b8b4.png" alt class="image--center mx-auto" /></p>
<p>We can see that these profiles do match our vibe search! She is a dancer and has brown hair.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747504875127/07501120-c5f8-4fde-af77-93c0f651f65d.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747504899826/a71a14a6-ae76-423d-9e0c-847d243b6111.png" alt class="image--center mx-auto" /></p>
<h4 id="heading-similar-donor-suggestions">Similar Donor Suggestions</h4>
<p>Each donor profile already has its own vector embedding.<br />When a user views a donor profile:</p>
<ul>
<li><p>I run a <strong>similarity search using that profile’s embedding</strong>.</p>
</li>
<li><p>The system suggests other donors with a similar vibe, not just those matching filters.</p>
</li>
</ul>
<p>This enhances discoverability and creates a more organic, exploratory experience.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747504991400/2caac6bb-2086-4478-9d6f-b7963b3da45d.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-final-thoughts"><strong>Final Thoughts</strong></h3>
<p>This was a fun concept build to explore how AI and vector search can modernize matching experiences. While this demo was built independently for <strong>Cofertility</strong> as a prototype, I believe this kind of vibe-based discovery can elevate many industries — from fertility tech to dating apps to talent marketplaces.  </p>
<p>👉 <strong>Source Code:</strong> <a target="_blank" href="https://github.com/IamDushu/Cofertility-AI">https://github.com/IamDushu/Cofertility-AI</a></p>
<p><a class="post-section-overview" href="#">  
</a>💬 <strong>I’d love to hear your experience trying it out!</strong><br />If you have feedback, thoughts, or just want to say hi, feel free to reach out at <a target="_blank" href="mailto:hey.dushyanth@gmail.com"><strong>hey.dushyanth@gmail.com</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Understanding Go Channels: Why for range data Can Trip You Up]]></title><description><![CDATA[Go is known for its elegant handling of concurrency, and one of the core tools in its concurrency toolbox is the channel. But even experienced Go developers can stumble upon subtle bugs, especially when working with for-range loops and channels.
In t...]]></description><link>https://blog.dushyanth.in/understanding-go-channels-why-for-range-data-can-trip-you-up</link><guid isPermaLink="true">https://blog.dushyanth.in/understanding-go-channels-why-for-range-data-can-trip-you-up</guid><category><![CDATA[go channels]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[channels in go]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 13 Apr 2025 05:37:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744522557338/b750aaf5-38f8-4996-a6f1-90afb89c7164.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Go is known for its elegant handling of concurrency, and one of the core tools in its concurrency toolbox is the <strong>channel</strong>. But even experienced Go developers can stumble upon subtle bugs, especially when working with <code>for-range</code> loops and channels.</p>
<p>In this post, we’ll dive into a deceptively simple loop:</p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> <span class="hljs-keyword">range</span> data {
    fmt.Println(&lt;-data)
}
</code></pre>
<p>At first glance, this might look fine. But it doesn’t behave the way you might expect. Let’s explore why.</p>
<hr />
<h2 id="heading-the-setup-a-goroutine-and-a-channel">The Setup: A Goroutine and a Channel</h2>
<p>Here’s the full code we’re analyzing:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    data := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">4</span>; i++ {
            data &lt;- <span class="hljs-string">"Hello "</span> + <span class="hljs-keyword">string</span>(<span class="hljs-string">'0'</span>+i)
        }
        <span class="hljs-built_in">close</span>(data)
    }()

    <span class="hljs-keyword">for</span> <span class="hljs-keyword">range</span> data {
        fmt.Println(&lt;-data)
    }

    <span class="hljs-comment">// Correct version (commented out):</span>
    <span class="hljs-comment">// for value := range data {</span>
    <span class="hljs-comment">//     fmt.Println(value)</span>
    <span class="hljs-comment">// }</span>
}
</code></pre>
<p>You might expect this to print:</p>
<pre><code class="lang-go">Hello <span class="hljs-number">0</span>
Hello <span class="hljs-number">1</span>
Hello <span class="hljs-number">2</span>
Hello <span class="hljs-number">3</span>
</code></pre>
<p>But instead, it prints:</p>
<pre><code class="lang-go">Hello <span class="hljs-number">1</span>
Hello <span class="hljs-number">3</span>
</code></pre>
<p>Wait… what?</p>
<hr />
<h2 id="heading-whats-going-on">What’s Going On?</h2>
<p>Let’s break down the two loop variants:</p>
<h3 id="heading-correct-version">✅ Correct Version:</h3>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> value := <span class="hljs-keyword">range</span> data {
    fmt.Println(value)
}
</code></pre>
<ul>
<li><p><code>range data</code> listens on the channel <code>data</code>.</p>
</li>
<li><p>It automatically receives each value sent on the channel, assigns it to <code>value</code>, and runs the loop.</p>
</li>
<li><p>When the channel is closed, the loop exits.</p>
</li>
</ul>
<p><strong>It reads one value per iteration - perfect.</strong></p>
<hr />
<h3 id="heading-the-buggy-version">❌ The Buggy Version:</h3>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> <span class="hljs-keyword">range</span> data {
    fmt.Println(&lt;-data)
}
</code></pre>
<p>This one’s sneaky.</p>
<ul>
<li><p><code>for range data</code> still <strong>reads</strong> a value from the channel each iteration.</p>
</li>
<li><p>But that value isn’t assigned or used - it’s just discarded.</p>
</li>
<li><p>Then, inside the loop, you manually call <code>&lt;-data</code> again — <strong>pulling a second value</strong> from the channel.</p>
</li>
</ul>
<p>🚨 <strong>You're reading two values per iteration.</strong></p>
<p>Let’s simulate what happens:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Loop</td><td><code>for range data</code> (ignored value)</td><td><code>&lt;-data</code> (printed value)</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>"Hello 0"</td><td>"Hello 1"</td></tr>
<tr>
<td>2</td><td>"Hello 2"</td><td>"Hello 3"</td></tr>
<tr>
<td>3</td><td>(channel is closed)</td><td>loop ends</td></tr>
</tbody>
</table>
</div><p>So only <strong>"Hello 1"</strong> and <strong>"Hello 3"</strong> get printed. The others are discarded during the range evaluation.</p>
<hr />
<h2 id="heading-the-takeaway">The Takeaway</h2>
<p>In Go, <code>for range</code> already pulls values from a channel. If you also call <code>&lt;-data</code> inside that loop, you're unintentionally skipping every other value!</p>
<h3 id="heading-do-this">✔️ Do this:</h3>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> value := <span class="hljs-keyword">range</span> data {
    fmt.Println(value)
}
</code></pre>
<h3 id="heading-not-this">❌ Not this:</h3>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> <span class="hljs-keyword">range</span> data {
    fmt.Println(&lt;-data)
}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[🔡 How Unicode Characters Become Bytes in Go: From Code Points to UTF-8]]></title><description><![CDATA[Ever wondered how languages like Telugu, emojis, or even simple letters like 'A' are stored in Go?It all comes down to Unicode and UTF-8 — and Go makes working with them surprisingly clean.
Let’s peel back the layers of abstraction and see what reall...]]></description><link>https://blog.dushyanth.in/how-unicode-characters-become-bytes-in-go-from-code-points-to-utf-8</link><guid isPermaLink="true">https://blog.dushyanth.in/how-unicode-characters-become-bytes-in-go-from-code-points-to-utf-8</guid><category><![CDATA[Go Language]]></category><category><![CDATA[encoding]]></category><category><![CDATA[utf8]]></category><category><![CDATA[unicode]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Thu, 10 Apr 2025 16:49:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744303738220/ebee221c-6c88-457e-9ee7-4e3eabdd8734.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Ever wondered how languages like Telugu, emojis, or even simple letters like 'A' are stored in Go?</strong><br />It all comes down to <strong>Unicode</strong> and <strong>UTF-8</strong> — and Go makes working with them surprisingly clean.</p>
<p>Let’s peel back the layers of abstraction and see what really happens under the hood when you write a character in Go.  </p>
<p><strong>Unicode vs UTF-8 vs Go Types</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Concept</td><td>What It Is</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Unicode</strong></td><td>A universal set of character codes (code points) — one number per symbol</td></tr>
<tr>
<td><strong>UTF-8</strong></td><td>A way to <strong>store</strong> those code points using 1–4 bytes</td></tr>
<tr>
<td><strong>Go</strong></td><td>Uses <code>rune</code> to store a Unicode code point, and <code>[]byte</code> to store its UTF-8 bytes</td></tr>
</tbody>
</table>
</div><h2 id="heading-lets-take-a-character">Let's Take a Character: <code>త</code></h2>
<p>This is a Telugu letter, pronounced <em>“ta”</em>.</p>
<h3 id="heading-step-1-unicode">Step 1: Unicode</h3>
<p>Every character has a unique <strong>code point</strong> in the Unicode spec.</p>
<pre><code class="lang-go">goCopyEditr := <span class="hljs-string">'త'</span>

fmt.Printf(<span class="hljs-string">"Unicode: U+%04X\n"</span>, r) <span class="hljs-comment">// Output: U+0C24</span>
</code></pre>
<p>So <code>'త'</code> has Unicode code point <code>U+0C24</code> = <strong>3108 in decimal</strong>.</p>
<h3 id="heading-step-2-convert-to-utf-8">Step 2: Convert to UTF-8</h3>
<p>The Unicode code point is abstract — we need a way to <strong>store it</strong> in memory. That’s where UTF-8 comes in.</p>
<p>UTF-8 stores <code>U+0C24</code> as:</p>
<ul>
<li><p>Bytes: <code>[224, 176, 164]</code></p>
</li>
<li><p>Hex: <code>[0xE0, 0xB0, 0xA4]</code></p>
</li>
<li><p>Binary:</p>
<pre><code class="lang-go">  <span class="hljs-number">11100000</span> <span class="hljs-number">10110000</span> <span class="hljs-number">10100100</span>
</code></pre>
</li>
</ul>
<p>UTF-8 uses variable-length encoding. Since <code>త</code> is in the <code>U+0800</code>–<code>U+FFFF</code> range, it uses <strong>3 bytes</strong>.</p>
<h3 id="heading-step-3-see-it-in-go">Step 3: See It in Go</h3>
<p>Here's a complete Go function to visualise this transformation:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">printUTF8Encoding</span><span class="hljs-params">(s <span class="hljs-keyword">string</span>)</span></span> {
    fmt.Printf(<span class="hljs-string">"Input: %q\n\n"</span>, s)
    <span class="hljs-keyword">for</span> i, r := <span class="hljs-keyword">range</span> s {
        utf8Bytes := []<span class="hljs-keyword">byte</span>(<span class="hljs-keyword">string</span>(r))
        binaryUnicode := fmt.Sprintf(<span class="hljs-string">"%016b"</span>, r)

        fmt.Printf(<span class="hljs-string">"Character #%d: %q\n"</span>, i+<span class="hljs-number">1</span>, r)
        fmt.Printf(<span class="hljs-string">"→ Unicode:  U+%04X (decimal: %d)\n"</span>, r, r)
        fmt.Printf(<span class="hljs-string">"→ Binary (Unicode): %s\n"</span>, insertEvery4Bits(binaryUnicode))
        fmt.Printf(<span class="hljs-string">"→ UTF-8 Bytes: %v\n"</span>, utf8Bytes)

        fmt.Print(<span class="hljs-string">"→ Hex:       "</span>)
        <span class="hljs-keyword">for</span> _, b := <span class="hljs-keyword">range</span> utf8Bytes {
            fmt.Printf(<span class="hljs-string">"0x%X "</span>, b)
        }

        fmt.Print(<span class="hljs-string">"\n→ Binary:    "</span>)
        <span class="hljs-keyword">for</span> _, b := <span class="hljs-keyword">range</span> utf8Bytes {
            fmt.Printf(<span class="hljs-string">"%08b "</span>, b)
        }

        fmt.Println(<span class="hljs-string">"\n---"</span>)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">insertEvery4Bits</span><span class="hljs-params">(s <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">string</span></span> {
    out := <span class="hljs-string">""</span>
    <span class="hljs-keyword">for</span> i, c := <span class="hljs-keyword">range</span> s {
        <span class="hljs-keyword">if</span> i &gt; <span class="hljs-number">0</span> &amp;&amp; (<span class="hljs-built_in">len</span>(s)-i)%<span class="hljs-number">4</span> == <span class="hljs-number">0</span> {
            out += <span class="hljs-string">" "</span>
        }
        out += <span class="hljs-keyword">string</span>(c)
    }
    <span class="hljs-keyword">return</span> out
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    printUTF8Encoding(<span class="hljs-string">"త"</span>)
}
</code></pre>
<hr />
<h3 id="heading-output">🧪 Output:</h3>
<pre><code class="lang-go">Input: <span class="hljs-string">"త"</span>

Character #<span class="hljs-number">1</span>: <span class="hljs-string">'త'</span>
→ Unicode:  U+<span class="hljs-number">0</span>C24 (decimal: <span class="hljs-number">3108</span>)
→ Binary (Unicode): <span class="hljs-number">0000</span> <span class="hljs-number">1100</span> <span class="hljs-number">0010</span> <span class="hljs-number">0100</span>
→ UTF<span class="hljs-number">-8</span> Bytes: [<span class="hljs-number">224</span> <span class="hljs-number">176</span> <span class="hljs-number">164</span>]
→ Hex:       <span class="hljs-number">0xE0</span> <span class="hljs-number">0xB0</span> <span class="hljs-number">0xA4</span>
→ Binary:    <span class="hljs-number">11100000</span> <span class="hljs-number">10110000</span> <span class="hljs-number">10100100</span>
</code></pre>
<hr />
<h2 id="heading-summary">🔍 Summary</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Layer</td><td>Value</td></tr>
</thead>
<tbody>
<tr>
<td>Unicode</td><td><code>U+0C24</code> (decimal: 3108)</td></tr>
<tr>
<td>UTF-8 Bytes</td><td><code>[224, 176, 164]</code></td></tr>
<tr>
<td>Go <code>rune</code></td><td><code>int32</code> → 3108</td></tr>
<tr>
<td>Go <code>[]byte</code></td><td>UTF-8 bytes</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-try-more">✨ Try More!</h3>
<p>Pass any string into the function: <code>"😊"</code>, <code>"hi"</code>, <code>"తెలుగు"</code>, <code>"你好"</code> — and you'll see how Go handles it.</p>
]]></content:encoded></item><item><title><![CDATA[Building Harbor Health: Behind the App Flow]]></title><description><![CDATA[https://youtu.be/Y_IPAAXDA5s
 
In this blog post, I’ll walk you through how the Harbor Health app works under the hood - from user authentication to booking visits and jumping into real-time video calls. The app is built with React Native + Expo on t...]]></description><link>https://blog.dushyanth.in/harbor</link><guid isPermaLink="true">https://blog.dushyanth.in/harbor</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 30 Mar 2025 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743417904985/e9723422-e6ec-48f3-980c-e07b23ff6a20.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Y_IPAAXDA5s">https://youtu.be/Y_IPAAXDA5s</a></div>
<p> </p>
<p>In this blog post, I’ll walk you through how the Harbor Health app works under the hood - from user authentication to booking visits and jumping into real-time video calls. The app is built with <strong>React Native + Expo</strong> on the frontend and <strong>Go (Gin) + PostgreSQL</strong> on the backend. Let’s break it down.</p>
<h2 id="heading-1-authentication-flow-say-no-to-jwt"><strong>🔐 1. Authentication Flow - say NO to JWT</strong></h2>
<p>Harbor Health uses a modern, <strong>passwordless</strong> authentication system, combining usability with security via <strong>PASETO</strong> tokens and temporary, unsigned JWTs.</p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743486699493/bdbb259b-99fd-4468-9f2a-dcc8eef757f4.png" alt class="image--center mx-auto" /></p>
<p>Step 1: Request Login or Signup</p>
<p>The flow begins when a user submits their email - whether to log in or sign up - via:</p>
<pre><code class="lang-http"><span class="hljs-attribute">POST /api/registration/email</span>
</code></pre>
<p><strong>Payload:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"email"</span>: <span class="hljs-string">"user@example.com"</span>,
  <span class="hljs-attr">"mode"</span>: <span class="hljs-string">"login"</span> <span class="hljs-comment">// or "signup"</span>
}
</code></pre>
<h4 id="heading-backend-logic">Backend logic:</h4>
<ol>
<li><p><strong>Normalize the email</strong> (lowercase, trim, etc.).</p>
</li>
<li><p>Check if a user with that email already exists.</p>
</li>
<li><p><strong>Regardless of existence</strong>, generate:</p>
<ul>
<li><p>An <strong>unsigned JWT</strong> containing metadata like <code>sub</code>, <code>iat</code>, and <code>exp</code>.</p>
</li>
<li><p>A <strong>random 5-digit code</strong>, hashed and stored in DB.</p>
</li>
<li><p>If the account exists, the code and token are valid for verification.</p>
</li>
<li><p>If not, they are immediately marked as expired (but the user never knows).</p>
</li>
</ul>
</li>
<li><p><strong>Send the email</strong> only if the account exists.</p>
</li>
<li><p><strong>No indication is given</strong> to the user whether the account exists or not - preventing user enumeration.</p>
</li>
</ol>
<blockquote>
<p>🧾 We use a simple <strong>unsigned JWT</strong> (i.e., with <code>"alg": "none"</code>) for the verification link/token. It contains only metadata and is not used for authentication.</p>
</blockquote>
<p>Example payload:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"alg"</span>: <span class="hljs-string">"none"</span>,
  <span class="hljs-attr">"typ"</span>: <span class="hljs-string">"JWT"</span>
}
.
{
  <span class="hljs-attr">"sub"</span>: <span class="hljs-string">"user@example.com"</span>,
  <span class="hljs-attr">"iat"</span>: <span class="hljs-number">1729878701</span>,
  <span class="hljs-attr">"nbf"</span>: <span class="hljs-number">1729878701</span>,
  <span class="hljs-attr">"exp"</span>: <span class="hljs-number">1729880501</span>
}
</code></pre>
<hr />
<h3 id="heading-step-2-email-verification">Step 2: Email Verification</h3>
<p>The user receives the email with a code and submits it along with the token:</p>
<pre><code class="lang-http"><span class="hljs-attribute">POST /api/registration/email/verify</span>
</code></pre>
<p><strong>Payload:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"token"</span>: <span class="hljs-string">"&lt;unsigned-jwt-token&gt;"</span>,
  <span class="hljs-attr">"digits"</span>: <span class="hljs-string">"46020"</span>
}
</code></pre>
<h4 id="heading-backend-verification">Backend verification:</h4>
<ol>
<li><p>Look up the token in the database.</p>
</li>
<li><p>Validate the JWT structure and ensure it's not expired.</p>
</li>
<li><p>Hash the provided code and compare it with the stored one.</p>
</li>
<li><p>If the code is incorrect:</p>
<ul>
<li><p>Increment an attempt counter.</p>
</li>
<li><p>Invalidate the token after 5 failed attempts.</p>
</li>
</ul>
</li>
<li><p>If correct:</p>
<ul>
<li><p>If the user doesn't exist yet, create the user but set <code>onboarded = false</code>.</p>
</li>
<li><p>Generate <strong>PASETO</strong> access and refresh tokens.</p>
</li>
<li><p>Return the session, user info, and a <strong>Stream token</strong> for real-time features.</p>
</li>
</ul>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743420275967/75b4db42-4cfd-423d-8e15-78f8465f181b.png" alt /></p>
<h2 id="heading-using-sqlc-vs-gorm-in-backend">Using sqlc vs gorm in Backend</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768824215912/1c1e0b4c-3ea2-4b35-9534-2f7868a69fb8.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-frontend-behavior-context-driven-auth-flow">🖼️ Frontend Behavior: Context-Driven Auth Flow.</h2>
<p>If the user has entered the correct OTP and is a new user (i.e) Who hasn’t created a member account yet; then the user is automatically redirected to a Member Form as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743422159302/74ccd3b5-06c9-4b68-ba5b-1389841e6424.png" alt class="image--center mx-auto" /></p>
<p>To handle form inputs efficiently, we use <strong>React Hook Form</strong> in combination with <strong>Zod</strong> for schema validation. This setup provides a clean and declarative way to build forms while keeping performance in check. Zod schemas define the structure and validation rules for each form, which are then integrated into React Hook Form using the <code>zodResolver</code>. This approach ensures that all form inputs are type-safe, validated on submission (or as-you-type), and tightly coupled with the backend’s expectations - minimizing bugs and making the user experience smooth and predictable.</p>
<h2 id="heading-app-flow-booking-visits-amp-starting-calls">📱 App Flow: Booking Visits &amp; Starting Calls</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743487235995/2b495a21-48e8-4190-b557-3b797eed09ae.png" alt class="image--center mx-auto" /></p>
<p>After logging in, users land on the <strong>Home Screen</strong>, which serves as the central hub of the app. From here, they can:</p>
<ul>
<li><p>📅 <strong>Book a Visit</strong> :- Choose between an <strong>in-office</strong> or <strong>remote</strong> appointment with a provider, selecting a time that works for them.</p>
</li>
<li><p>🚨 <strong>Request an Urgent Video Chat</strong> :- Immediately initiate a real-time video call with an available provider. This is where <strong>Stream</strong> comes into play.</p>
</li>
<li><p>📍 <strong>Find Office Locations.</strong></p>
</li>
</ul>
<p>For urgent calls, the app creates a <strong>Stream video room</strong> and notifies the provider in real time. If accepted, both participants are connected to the same room using the <strong>Stream Video SDK</strong>, enabling a secure, low-latency WebRTC video call. The SDK also handles participant presence, call state, and UI components - giving us a production-ready video solution with full flexibility.</p>
<p>This unified experience - from finding a clinic, to booking a visit, to jumping into a call - makes the Harbor Health app feel seamless, responsive, and human.</p>
<h3 id="heading-booking-a-visit-multi-step-flow-with-zustand-amp-ux-polish">📅 Booking a Visit: Multi-Step Flow with Zustand &amp; UX Polish</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743488932455/7790e1d9-760e-4bce-bbcf-ad4e84560d43.png" alt class="image--center mx-auto" /></p>
<p>The <strong>visit booking flow</strong> is designed to guide the member step-by-step while keeping the interface focused and intuitive.</p>
<h3 id="heading-heres-how-it-works">Here’s how it works:</h3>
<ol>
<li><p><strong>Visit Intent</strong>:<br /> The user starts by entering a brief description of what they want to cover in the visit - symptoms, concerns, or questions for the provider.</p>
</li>
<li><p><strong>Location Selection</strong>:<br /> Next, they choose between nearby office locations.</p>
</li>
<li><p><strong>Provider &amp; Slot Selection</strong>:<br /> Based on availability, the user is shown a list of providers and their available time slots.</p>
</li>
<li><p><strong>Confirmation Screen</strong>:<br /> Finally, the user reviews their selection and confirms the appointment.</p>
</li>
</ol>
<h3 id="heading-under-the-hood-ui-challenges-amp-zustand-for-state-management">🛠️ Under the Hood: UI Challenges &amp; Zustand for State Management</h3>
<p>One design quirk I encountered was with the <strong>confirmation screen</strong>. This screen needed to appear <strong>above the tab layout</strong>, without showing the tab bar at the bottom - which meant it couldn’t live within the main tab navigator tree.</p>
<p>That posed a problem: we needed to share state (like selected slot, provider, and visit info) <strong>across multiple screens</strong>, but <strong>without using props or context</strong> - since the confirmation screen lived outside the context tree.</p>
<p>To solve this, I used <strong>Zustand</strong> - a lightweight, scalable global state library - to persist the visit booking state throughout the flow. It worked beautifully, letting us avoid prop drilling and keeping logic clean and localized.</p>
<h3 id="heading-smooth-ux-with-shimmer-effects">💫 Smooth UX with Shimmer Effects</h3>
<p>While loading providers and slots, we also implemented <strong>shimmer loading placeholders</strong> using a React Native shimmer library. This added a touch of polish, making the app feel fast and responsive even when data was still fetching.</p>
<h3 id="heading-backend-logic-slot-locking-amp-transactional-integrity">🧩 Backend Logic: Slot Locking &amp; Transactional Integrity</h3>
<p>Once a user selects a slot and confirms the booking, we ensure that the same time slot cannot be double-booked.</p>
<h4 id="heading-heres-how-we-handle-it-on-the-backend">Here’s how we handle it on the backend:</h4>
<ul>
<li><p>When a booking is confirmed, the backend:</p>
<ol>
<li><p>Validates that the slot is still available.</p>
</li>
<li><p>Marks the slot as <strong>reserved</strong> or removes it from the availability pool.</p>
</li>
<li><p>Uses a <strong>database transaction</strong> to wrap the entire booking logic - including slot validation, creation of the booking record, and updates to related tables.</p>
</li>
</ol>
</li>
</ul>
<blockquote>
<p>✅ This ensures <strong>atomicity</strong> - either the whole booking succeeds, or none of it does - preventing race conditions and data inconsistencies.</p>
</blockquote>
<ul>
<li>Once booked, that slot is no longer returned in future availability queries.</li>
</ul>
<p>This approach helps us maintain <strong>consistency</strong> even under high concurrency, avoids duplicate appointments, and keeps the system safe from overlapping bookings.</p>
<h3 id="heading-urgent-video-chat">📱 Urgent Video Chat</h3>
<p>One of the key flows I wanted to explore was how Harbor Health could support <strong>urgent or time-sensitive consultations</strong> - for example, when a member needs immediate attention from a provider.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743488554259/682857aa-5f2b-432a-8fb4-9f091aab233e.png" alt class="image--center mx-auto" /></p>
<p>In the MVP, I implemented an <strong>"urgent call" mechanism</strong> that allows a member to initiate a real-time video call with a provider. Here's how it works:</p>
<ul>
<li><p><strong>Initiation:</strong> A member taps “Urgent Video Call” from the app, which instantly creates a call room via Stream’s video SDK.</p>
</li>
<li><p><strong>Push Notification:</strong> The provider receives a push notification and in-app alert, with clear labeling to indicate urgency.</p>
</li>
<li><p><strong>Join Flow:</strong> Once the provider accepts, both users are routed to the same video room. The call screen handles edge cases like double joins or stale state using internal <code>hasAnswered</code> flags and call state listeners.</p>
</li>
<li><p><strong>Lightweight Experience:</strong> The goal was to make the experience as frictionless as possible - no extra screens, no unnecessary loading, just an immediate connection.</p>
</li>
</ul>
<p>This setup opens up possibilities for <strong>triage-like experiences</strong>, <strong>crisis counseling</strong>, or simply faster access to care in moments when timing matters.</p>
<h3 id="heading-prescription-renewals">💊 Prescription Renewals.</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743489462990/9347ee62-467d-46ba-8a73-e1d6d66e5df3.png" alt class="image--center mx-auto" /></p>
<p>The app includes a simple flow for managing and renewing prescriptions. Users can view their active prescriptions, select one for renewal, choose a pharmacy, and submit the request - all in just a few taps.</p>
<p>It's designed for quick, mobile-first interactions, and sets the foundation for future features like pharmacy integration and provider approvals.</p>
<h2 id="heading-locations-map-nearby-clinics-amp-mobile-tracking">📍 Locations Map: Nearby Clinics &amp; Mobile Tracking</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743423944706/ccdf53ae-ecb4-4095-b38d-6c005311d01a.png" alt class="image--center mx-auto" /></p>
<p>In the <strong>Locations</strong> section of the app, users can view all available clinic locations on an interactive map. This helps them find the nearest physical location when booking an in-office visit.</p>
<p>But we went one step further.</p>
<h3 id="heading-mobile-clinic-tracking">🚐 Mobile Clinic Tracking</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743575338538/dbc22a25-5643-4b2d-bcec-4ea6c710514d.png" alt class="image--center mx-auto" /></p>
<p>In addition to static clinic pins, the map also displays the <strong>live location of our mobile clinic</strong> - allowing users to see exactly where it is and when it might be near them.</p>
<ul>
<li><p>📌 Each location is shown as a marker on the map with labels (e.g. "Downtown Clinic" or "Mobile Unit").</p>
</li>
<li><p>📡 The mobile clinic’s location is updated dynamically, giving users real-time context on where care is available.</p>
</li>
<li><p>🔍 Users can tap on any location to get more info.</p>
</li>
</ul>
<h3 id="heading-under-the-hood">🛠️ Under the Hood</h3>
<ul>
<li><p>We use <strong>React Native Maps</strong> for rendering the map view.</p>
</li>
<li><p>Location data is fetched from the backend and displayed as markers.</p>
</li>
<li><p>The mobile clinic’s location is synced periodically or in real time depending on system configuration.</p>
</li>
<li><p>We integrated a <strong>bottom sheet</strong> that slides up from the bottom of the screen, showing a scrollable list of all available locations - fully synced with the map view.</p>
<ul>
<li>As users browse the list, the map automatically highlights the corresponding location.</li>
</ul>
</li>
</ul>
<p>This map feature creates a more transparent and convenient user experience - whether the user prefers to walk into a clinic or catch the mobile unit while it’s nearby.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743489688714/ff2055b0-c333-4c00-9f6c-1083ec3d3675.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-backend-deployment-amp-monitoring">Backend Deployment &amp; Monitoring.</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743574762898/e6a44a7f-cdb7-4cbc-bcaa-b675a2dfc909.png" alt class="image--center mx-auto" /></p>
<p>The Go backend was containerized using a <strong>Docker image</strong> and deployed to <strong>Railway</strong>, making it easy to manage builds, environment variables, and scaling.</p>
<p>For basic monitoring, I set up <strong>UptimeRobot</strong> to ping the health check endpoint - ensuring the service stays live and alerting on downtime.</p>
<p>💬 <strong>I’d love to hear your experience trying it out!</strong><br />If you have feedback, thoughts, or just want to say hi, feel free to reach out at <strong>hey.dushyanth@gmail.com</strong></p>
]]></content:encoded></item><item><title><![CDATA[Mastering State Management with Zustand and Immer: A Guide to Efficient State Updates]]></title><description><![CDATA[State management is a crucial part of any modern JavaScript application. Whether you're building a simple app or a complex one, keeping track of state and efficiently updating it is a top priority. This is where libraries like Zustand and Immer come ...]]></description><link>https://blog.dushyanth.in/mastering-state-management-with-zustand-and-immer-a-guide-to-efficient-state-updates</link><guid isPermaLink="true">https://blog.dushyanth.in/mastering-state-management-with-zustand-and-immer-a-guide-to-efficient-state-updates</guid><category><![CDATA[zustand]]></category><category><![CDATA[immer]]></category><category><![CDATA[React]]></category><category><![CDATA[data management]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Mon, 24 Feb 2025 10:08:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740391356275/38b2f516-6347-402a-8ac4-e9fd6ab1bac4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>State management is a crucial part of any modern JavaScript application. Whether you're building a simple app or a complex one, keeping track of state and efficiently updating it is a top priority. This is where libraries like <strong>Zustand</strong> and <strong>Immer</strong> come in. When combined, they offer a powerful solution for managing state in React (and other frameworks) while keeping your code clean and concise.</p>
<p>In this post, we’ll dive into how to use <strong>Zustand</strong> in combination with <strong>Immer</strong> to handle state updates, especially when working with deeply nested state or immutable updates.</p>
<h2 id="heading-what-is-zustand"><strong>What is Zustand?</strong></h2>
<p>Zustand is a small, fast state management library for React. It is very lightweight and has a minimalistic API, making it a great choice for small to medium-sized applications. Zustand makes state management simple by allowing you to create stores (state containers) that can be accessed and updated easily across your components.</p>
<h2 id="heading-what-is-immer"><strong>What is Immer?</strong></h2>
<p>Immer is a library that helps with immutable state updates. In JavaScript, state updates often require creating a new copy of the state object to avoid mutating it directly. This can be tedious, especially when the state is deeply nested. Immer allows you to <strong>mutate</strong> the state directly (just like working with mutable objects), while ensuring that the changes are applied immutably behind the scenes.</p>
<h3 id="heading-the-power-of-zustand-immer"><strong>The Power of Zustand + Immer</strong></h3>
<p>When combined, <strong>Zustand</strong> and <strong>Immer</strong> offer an elegant solution for managing complex state. Immer’s ability to handle immutable state and Zustand’s simplicity make for a great pairing, especially when working with deeply nested objects or arrays.</p>
<h3 id="heading-getting-started-with-zustand-immer"><strong>Getting Started with Zustand + Immer</strong></h3>
<p>Before we dive into best practices, let's set up Zustand with Immer. Here’s how you can create a Zustand store using Immer:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> create <span class="hljs-keyword">from</span> <span class="hljs-string">'zustand'</span>;
<span class="hljs-keyword">import</span> { immer } <span class="hljs-keyword">from</span> <span class="hljs-string">'zustand/middleware/immer'</span>;

<span class="hljs-keyword">const</span> useStore = create(
  immer(<span class="hljs-function">(<span class="hljs-params">set</span>) =&gt;</span> ({
    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    <span class="hljs-attr">increment</span>: <span class="hljs-function">() =&gt;</span> {
      set(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> {
        state.count++;  <span class="hljs-comment">// Direct mutation of the draft state</span>
      });
    },
  }))
);
</code></pre>
<p>In this simple store, we have a <code>count</code> state, and we use the <code>increment</code> method to update it. Notice how we <strong>mutate</strong> <code>state.count</code> directly inside the <code>set()</code> function. Thanks to Immer, the state update is immutable, and we don’t need to return a new object.</p>
<hr />
<h3 id="heading-directly-mutating-nested-objects-in-immer"><strong>Directly Mutating Nested Objects in Immer</strong></h3>
<p>One of the most powerful features of Immer is its ability to handle deeply nested objects without requiring us to manually copy or spread them. Let’s take an example where we need to update a nested property in an array of objects.</p>
<h4 id="heading-scenario-updating-a-set-in-a-workout">Scenario: Updating a Set in a Workout</h4>
<p>Imagine we have a workout app with workouts, and each workout has a series of sets. We want to update the reps and weight of a specific exercise set.</p>
<p>Here’s an example of how you might use Zustand with Immer to update a nested <code>ExerciseSet</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> useStore = create(
  immer(<span class="hljs-function">(<span class="hljs-params">set</span>) =&gt;</span> ({
    <span class="hljs-attr">currentWorkout</span>: {
      <span class="hljs-attr">exercises</span>: [
        { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">sets</span>: [{ <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">reps</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">weight</span>: <span class="hljs-number">100</span> }] },
        { <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">sets</span>: [{ <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">reps</span>: <span class="hljs-number">8</span>, <span class="hljs-attr">weight</span>: <span class="hljs-number">120</span> }] },
      ],
    },
    <span class="hljs-attr">updateSet</span>: <span class="hljs-function">(<span class="hljs-params">setId, updatedFields</span>) =&gt;</span> {
      set(<span class="hljs-function">(<span class="hljs-params">{ currentWorkout }</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> setToUpdate = currentWorkout.exercises
          .flatMap(<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> e.sets)
          .find(<span class="hljs-function">(<span class="hljs-params">s</span>) =&gt;</span> s.id === setId);

        <span class="hljs-keyword">if</span> (!setToUpdate) {
          <span class="hljs-keyword">return</span>;
        }

        <span class="hljs-comment">//Direct mutation: update the set's properties</span>
        <span class="hljs-keyword">if</span> (updatedFields.reps !== <span class="hljs-literal">undefined</span>) {
          setToUpdate.reps = updatedFields.reps;
        }

        <span class="hljs-keyword">if</span> (updatedFields.weight !== <span class="hljs-literal">undefined</span>) {
          setToUpdate.weight = updatedFields.weight;
        }
      });
    },
  }))
);
</code></pre>
<h3 id="heading-why-direct-mutation-works-with-immer"><strong>Why Direct Mutation Works with Immer</strong></h3>
<p>Here’s the key idea: <strong>Immer provides a mutable draft</strong> of the state that you can directly modify. Normally, in state management libraries like Redux or Zustand, state is immutable, and any mutation requires creating a new copy of the object (to preserve immutability). However, with Immer, you can <strong>mutate</strong> the draft directly, and Immer will handle the creation of the new immutable state for you behind the scenes.</p>
<h4 id="heading-key-points">Key Points:</h4>
<ol>
<li><p><strong>Mutability of the draft</strong>: Inside <code>set()</code>, you can <strong>mutate the draft state</strong> directly.</p>
</li>
<li><p><strong>Automatic immutability</strong>: Immer ensures that the state remains immutable, even though you mutate it directly.</p>
</li>
<li><p><strong>No need to return a new state</strong>: Unlike traditional state management, you don’t need to manually return a new state object after mutation. Immer takes care of that for you.</p>
</li>
</ol>
<hr />
<h3 id="heading-avoid-reassigning-state-in-immer"><strong>Avoid Reassigning State in Immer</strong></h3>
<p>A common mistake when working with Immer is reassigning state or nested objects within the draft, which can break Immer's internal mechanism for handling updates. Let’s look at a typical error you might see:</p>
<h4 id="heading-incorrect-code-reassigning-the-draft">Incorrect Code (Reassigning the Draft):</h4>
<pre><code class="lang-javascript">updateSet: <span class="hljs-function">(<span class="hljs-params">setId, updatedFields</span>) =&gt;</span> {
  set(<span class="hljs-function">(<span class="hljs-params">{ currentWorkout }</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> setToUpdate = currentWorkout.exercises
      .flatMap(<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> e.sets)
      .find(<span class="hljs-function">(<span class="hljs-params">s</span>) =&gt;</span> s.id === setId);

    <span class="hljs-keyword">if</span> (!setToUpdate) {
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Incorrect! Reassigning the draft will break Immer's state tracking</span>
    setToUpdate = updateSet(current(setToUpdate), updatedFields);
  });
};
</code></pre>
<h4 id="heading-correct-approach">Correct Approach:</h4>
<p>Instead of reassigning the draft object, <strong>mutate the properties directly</strong>:</p>
<pre><code class="lang-javascript">updateSet: <span class="hljs-function">(<span class="hljs-params">setId, updatedFields</span>) =&gt;</span> {
  set(<span class="hljs-function">(<span class="hljs-params">{ currentWorkout }</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> setToUpdate = currentWorkout.exercises
      .flatMap(<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> e.sets)
      .find(<span class="hljs-function">(<span class="hljs-params">s</span>) =&gt;</span> s.id === setId);

    <span class="hljs-keyword">if</span> (!setToUpdate) {
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Correct! Mutate the properties directly on the draft</span>
    <span class="hljs-keyword">if</span> (updatedFields.reps !== <span class="hljs-literal">undefined</span>) {
      setToUpdate.reps = updatedFields.reps;
    }

    <span class="hljs-keyword">if</span> (updatedFields.weight !== <span class="hljs-literal">undefined</span>) {
      setToUpdate.weight = updatedFields.weight;
    }
  });
};
</code></pre>
<h3 id="heading-why-this-works"><strong>Why This Works:</strong></h3>
<ul>
<li><p><strong>Direct mutation</strong>: We directly modify <code>setToUpdate.reps</code> and <code>setToUpdate.weight</code> on the draft, rather than assigning a new object to <code>setToUpdate</code>.</p>
</li>
<li><p><strong>Immer manages the immutability</strong>: Immer tracks the mutation and ensures the new state is created immutably when needed.</p>
</li>
</ul>
<hr />
<h3 id="heading-keep-aware-of-this-pitfall"><strong>Keep Aware of this pitfall!</strong></h3>
<ol>
<li><strong>Mutate directly on the draft</strong>: You can modify the draft state directly. Avoid reassigning variables or returning a new state object manually.</li>
</ol>
<hr />
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>By combining <strong>Zustand</strong> and <strong>Immer</strong>, we can simplify state management in our React apps while ensuring that the state remains immutable and easily updatable. Immer makes it easy to mutate deeply nested state directly without breaking immutability, while Zustand provides a simple, performant store to manage that state. Together, they provide a seamless experience for handling complex state updates efficiently.</p>
<p>Hopefully, this guide has given you a better understanding of how to use Zustand with Immer for managing state in your React applications. Happy coding! ✌️</p>
]]></content:encoded></item><item><title><![CDATA[Create Expo App (self note)]]></title><description><![CDATA[This is a self note for installing React Native Expo app with app router for my projects using pnpm.
Project Installation:

pnpm dlx create-expo-app@latest Fitness --template (or)  npx create-expo-app@latest Fitness --template

Choose a template: › B...]]></description><link>https://blog.dushyanth.in/create-expo-app-self-note</link><guid isPermaLink="true">https://blog.dushyanth.in/create-expo-app-self-note</guid><category><![CDATA[Expo]]></category><category><![CDATA[React Native]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Fri, 21 Feb 2025 11:27:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740135556326/27a4c393-f358-4571-b58b-99dd9d7245c6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a self note for installing React Native Expo app with app router for my projects using pnpm.</p>
<h3 id="heading-project-installation">Project Installation:</h3>
<ul>
<li><p><strong>pnpm dlx create-expo-app@latest Fitness --template</strong> (or)<br />  npx create-expo-app@latest Fitness --template</p>
</li>
<li><p><strong>Choose a template: › Blank (TypeScript)</strong></p>
</li>
<li><p><strong>pnpm start</strong> to start the project.</p>
</li>
</ul>
<h3 id="heading-app-router">App router:</h3>
<p>Reference: <a target="_blank" href="https://docs.expo.dev/router/installation/">https://docs.expo.dev/router/installation/</a></p>
<ul>
<li><p>create <strong>src &gt; app</strong> folder structure for the router.</p>
</li>
<li><p>Add <strong>“paths”</strong> to <strong>tsconfig.json,</strong> useful while importing.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740135139792/f08b61d8-97f1-4e22-bde1-71ae20f6b299.png" alt class="image--center mx-auto" /></p>
<ol>
<li><strong>Install dependencies</strong></li>
</ol>
<pre><code class="lang-bash">pnpm dlx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
</code></pre>
<ol start="2">
<li><strong>Setup entry point in package.json</strong></li>
</ol>
<pre><code class="lang-bash">{
  <span class="hljs-string">"main"</span>: <span class="hljs-string">"expo-router/entry"</span>,
}
</code></pre>
<ol start="3">
<li><strong>Modify project config in app.json;</strong> include “<strong>scheme”</strong> for deep-linking.</li>
</ol>
<pre><code class="lang-bash">{
  <span class="hljs-string">"scheme"</span>: <span class="hljs-string">"your-app-scheme"</span>
}
</code></pre>
<p><strong>If you are developing your app for web, install the following dependencies:</strong></p>
<pre><code class="lang-bash">pnpm dlx expo install react-native-web react-dom
</code></pre>
<p><strong>Then include “bundler” in app.json for “web”</strong></p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"web"</span>: {
    <span class="hljs-string">"bundler"</span>: <span class="hljs-string">"metro"</span>
  }
}
</code></pre>
<p><strong>Now Start the app</strong></p>
<pre><code class="lang-bash">pnpm start -- --clear
</code></pre>
<p><strong>Create an index.tsx file inside app folder and you are ready to roll! 🎉</strong></p>
]]></content:encoded></item><item><title><![CDATA[Handling Refs in React 19: Simplifying Ref Forwarding and Usage]]></title><description><![CDATA[Refs in React have always been a powerful feature, allowing developers to directly access DOM elements or component instances. However, working with refs, especially when passing them to child components, has historically required some boilerplate co...]]></description><link>https://blog.dushyanth.in/handling-refs-in-react-19</link><guid isPermaLink="true">https://blog.dushyanth.in/handling-refs-in-react-19</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Thu, 06 Feb 2025 17:56:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738864522856/0978b740-ca34-4477-a23d-6b0e8dce82bb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Refs in React have always been a powerful feature, allowing developers to directly access DOM elements or component instances. However, working with refs, especially when passing them to child components, has historically required some boilerplate code, such as using <code>React.forwardRef</code>. With <strong>React 19</strong>, the process of handling refs has become more intuitive and streamlined. In this blog, we’ll explore how to work with refs in React 19, including the new features that make ref management easier than ever.</p>
<hr />
<h2 id="heading-what-are-refs-in-react">What Are Refs in React?</h2>
<p>Refs (short for references) are a way to access DOM nodes or React components directly. They are commonly used for:</p>
<ul>
<li><p>Managing focus, text selection, or media playback.</p>
</li>
<li><p>Triggering imperative animations.</p>
</li>
<li><p>Integrating with third-party DOM libraries.</p>
</li>
</ul>
<p>In React, refs are created using the <code>useRef</code> hook (for functional components) or the <code>createRef</code> method (for class components).</p>
<hr />
<h2 id="heading-the-traditional-way-using-forwardref">The Traditional Way: Using <code>forwardRef</code></h2>
<p>Before React 19, if you wanted to pass a <code>ref</code> from a parent component to a child component, you had to use <code>React.forwardRef</code>. This was necessary because <code>ref</code> is not a regular prop—it’s treated specially by React.</p>
<h3 id="heading-example-with-forwardref">Example with <code>forwardRef</code>:</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useRef, forwardRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">// Child component using forwardRef</span>
<span class="hljs-keyword">const</span> ChildComponent = forwardRef(<span class="hljs-function">(<span class="hljs-params">props, ref</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span>&gt;</span>Child Component<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
});

<span class="hljs-comment">// Parent component</span>
<span class="hljs-keyword">const</span> ParentComponent = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> childRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(childRef.current); <span class="hljs-comment">// Access the child's DOM element</span>
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{childRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span>Log Ref<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ParentComponent;
</code></pre>
<h3 id="heading-why-forwardref-was-necessary">Why <code>forwardRef</code> Was Necessary</h3>
<p>React treats <code>ref</code> differently from other props to ensure that it doesn’t get passed down unintentionally. <code>forwardRef</code> was introduced to explicitly forward refs to child components.</p>
<hr />
<h2 id="heading-whats-new-in-react-19">What’s New in React 19?</h2>
<p>React 19 introduces a significant improvement: <strong>you can now pass</strong> <code>ref</code> directly as a prop to a child component without needing <code>forwardRef</code>. This simplifies the code and makes it more intuitive.</p>
<h3 id="heading-example-in-react-19">Example in React 19:</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">// Child component (no need for forwardRef)</span>
<span class="hljs-keyword">const</span> ChildComponent = <span class="hljs-function">(<span class="hljs-params">{ ref }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span>&gt;</span>Child Component<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
};

<span class="hljs-comment">// Parent component</span>
<span class="hljs-keyword">const</span> ParentComponent = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> childRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(childRef.current); <span class="hljs-comment">// Access the child's DOM element</span>
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{childRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span>Log Ref<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ParentComponent;
</code></pre>
<h3 id="heading-benefits-of-the-new-approach">Benefits of the New Approach</h3>
<ol>
<li><p><strong>Less Boilerplate</strong>: No need to wrap your component with <code>forwardRef</code>.</p>
</li>
<li><p><strong>More Intuitive</strong>: Passing <code>ref</code> as a prop feels more natural and aligns with how other props are handled.</p>
</li>
<li><p><strong>Improved Readability</strong>: The code is cleaner and easier to understand.</p>
</li>
</ol>
<hr />
<h2 id="heading-when-to-use-forwardref-in-react-19">When to Use <code>forwardRef</code> in React 19</h2>
<p>While React 19 allows you to pass <code>ref</code> directly as a prop, <code>forwardRef</code> is still supported and can be useful in certain scenarios:</p>
<ol>
<li><p><strong>Backward Compatibility</strong>: If you’re working on a codebase that needs to support older versions of React, you should continue using <code>forwardRef</code>.</p>
</li>
<li><p><strong>Explicit Ref Forwarding</strong>: If you want to make it clear that a component is designed to forward refs, <code>forwardRef</code> can serve as a signal to other developers.</p>
</li>
</ol>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>React 19 makes working with refs easier and more intuitive by allowing you to pass <code>ref</code> directly as a prop to child components. This eliminates the need for <code>forwardRef</code> in most cases, reducing boilerplate and improving code readability. However, <code>forwardRef</code> is still available for backward compatibility and explicit ref forwarding.  </p>
<p>Thanks to the React Team for making this change.</p>
<p>Happy coding! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Generate OTP's in GO]]></title><description><![CDATA[package main

import (
    "crypto/rand"
    "fmt"
    "math/big"
)

func generateSecureOTP() (int, error) {
    // Generate a random number in [1000, 9999]
    n, err := rand.Int(rand.Reader, big.NewInt(9000))
    if err != nil {
        return 0, e...]]></description><link>https://blog.dushyanth.in/generate-otps-in-go</link><guid isPermaLink="true">https://blog.dushyanth.in/generate-otps-in-go</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 04 Aug 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730289858783/f15abe5a-f0c9-491e-b5eb-3e630e8ac16e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"crypto/rand"</span>
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"math/big"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateSecureOTP</span><span class="hljs-params">()</span> <span class="hljs-params">(<span class="hljs-keyword">int</span>, error)</span></span> {
    <span class="hljs-comment">// Generate a random number in [1000, 9999]</span>
    n, err := rand.Int(rand.Reader, big.NewInt(<span class="hljs-number">9000</span>))
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>, err
    }
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">int</span>(n.Int64()) + <span class="hljs-number">1000</span>, <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    otp, err := generateSecureOTP()
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error generating OTP:"</span>, err)
        <span class="hljs-keyword">return</span>
    }
    fmt.Printf(<span class="hljs-string">"Generated Secure OTP: %04d\n"</span>, otp)
}
</code></pre>
<h3 id="heading-explanation-of-the-code">Explanation of the Code</h3>
<ol>
<li><p><a target="_blank" href="http://rand.Int"><code>rand.Int</code></a><code>(rand.Reader, big.NewInt(9000))</code>:</p>
<ul>
<li>Generates a random number in the range <code>[0, 8999]</code>. Using <code>9000</code> ensures the number can go up to <code>8999</code>.</li>
</ul>
</li>
<li><p><code>int(</code><a target="_blank" href="http://n.Int"><code>n.Int</code></a><code>64()) + 1000</code>:</p>
<ul>
<li>Adds <code>1000</code> to shift the range from <code>[0, 8999]</code> to <code>[1000, 9999]</code>, resulting in a secure 4-digit OTP.</li>
</ul>
</li>
</ol>
<h3 id="heading-using-mathrand">Using <code>math/rand</code></h3>
<p>One simple way to generate a 6-digit OTP is by using the <code>math/rand</code> package, which provides basic random number generation. However, for true randomness (e.g., in production), it’s usually recommended to use <code>crypto/rand</code>, as it provides cryptographically secure random numbers.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"math/rand"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">generateOTP</span><span class="hljs-params">()</span> <span class="hljs-title">int</span></span> {
    rand.Seed(time.Now().UnixNano()) <span class="hljs-comment">// Seed with current time</span>
    <span class="hljs-keyword">return</span> <span class="hljs-number">1000</span> + rand.Intn(<span class="hljs-number">9000</span>) <span class="hljs-comment">// Generate a random number in [1000, 9999]</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    otp := generateOTP()
    fmt.Printf(<span class="hljs-string">"Generated OTP: %04d\n"</span>, otp)
}
</code></pre>
<p>Note: Starting with <strong>Go 1.20</strong>, <code>rand.Seed()</code> has been deprecated for cryptographic purposes due to its predictability and the availability of better, more secure options. Instead, for non-cryptographic random numbers, you should now create a new instance of <code>math/rand</code> using <a target="_blank" href="http://rand.New"><code>rand.New</code></a><code>()</code> with a source that’s properly seeded, or switch entirely to <code>crypto/rand</code> for security-sensitive applications.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.dushyanth.in/randseed-deprecated-way-forward">https://blog.dushyanth.in/randseed-deprecated-way-forward</a></div>
<p> </p>
<p>If you generate OTPs using <code>math/rand</code>, an attacker could potentially guess the sequence if they know the seed, especially if it’s based on something predictable like the current timestamp. However, <code>crypto/rand</code> is resistant to this kind of attack because it pulls from sources that are practically unpredictable.</p>
<p>THE END</p>
]]></content:encoded></item><item><title><![CDATA[rand.Seed() deprecated: way forward.]]></title><description><![CDATA[The rand.Seed() function has been deprecated since Go version 1.20:

Deprecated: As of Go 1.20 there is no reason to call Seed with a random value. Programs that call Seed with a known value to get a specific sequence of results should use New(NewSou...]]></description><link>https://blog.dushyanth.in/randseed-deprecated-way-forward</link><guid isPermaLink="true">https://blog.dushyanth.in/randseed-deprecated-way-forward</guid><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 21 Jul 2024 15:22:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727089083980/e9d11b10-b189-4c9d-b867-c9c153f17816.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <code>rand.Seed()</code> function has been deprecated since Go version 1.20:</p>
<blockquote>
<p>Deprecated: As of Go 1.20 there is no reason to call Seed with a random value. Programs that call Seed with a known value to get a specific sequence of results should use New(NewSource(seed)) to obtain a local random generator.</p>
</blockquote>
<p>Let's look at the example below:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> util 

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"math/rand"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {
    rand.Seed(time.Now().UnixNano())
}

<span class="hljs-comment">// RandomInt generates a random integer between min and max</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">RandomInt</span><span class="hljs-params">(min, max <span class="hljs-keyword">int64</span>)</span> <span class="hljs-title">int64</span></span> {
    <span class="hljs-keyword">return</span> min + rand.Int63n(max-min+<span class="hljs-number">1</span>)
}
</code></pre>
<p>In the above example; The init() function will be called automatically when the package is first used. In this function, we set the seed value for the random generator by calling <code>rand.Seed()</code><br />Normally the seed value is often set to the current time. As rand.Seed() expects an <code>int64</code> as input, we convert it to unix nano before passing it to the function. (UnixNano a Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC. i.e int64)  </p>
<p>But now that rand.Seed() has been deprecated (since Go version 1.20); Let's look at the below example on how we can implement the same.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> util

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"math/rand"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-keyword">var</span> randomSource *rand.Rand

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {
    randomSource = rand.New(rand.NewSource(time.Now().UnixNano()))
}

<span class="hljs-comment">// RandomInt generates a random integer between min and max</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">RandomInt</span><span class="hljs-params">(min, max <span class="hljs-keyword">int64</span>)</span> <span class="hljs-title">int64</span></span> {
    <span class="hljs-keyword">return</span> min + randomSource.Int63n(max-min+<span class="hljs-number">1</span>)
}
</code></pre>
<p><code>var randomSource *rand.Rand</code> This line declares a package-level variable named <code>randomSource</code> of type <code>*rand.Rand</code>. This variable will hold an instance of the <code>rand.Rand</code> type, which is used for generating random numbers.  </p>
<p>Here, Inside the init():<br /><code>rand.New(...)</code>: Creates a new <code>rand.Rand</code> instance initialised with the source generated by <code>rand.NewSource(...)</code>. This <code>rand.Rand</code> instance is then assigned to the <code>randomSource</code> variable.  </p>
<p>And that's how you work with random numbers!</p>
]]></content:encoded></item><item><title><![CDATA[The Curious Case of Go's Error Formatting: A Deep Dive into Type Methods and String Representation]]></title><description><![CDATA[In the world of Go programming, error handling is a crucial aspect that every developer must master. Today, we're going to explore an intriguing corner case that highlights the nuances of Go's type system, method resolution, and string formatting. Th...]]></description><link>https://blog.dushyanth.in/the-curious-case-of-gos-error-formatting-a-deep-dive-into-type-methods-and-string-representation</link><guid isPermaLink="true">https://blog.dushyanth.in/the-curious-case-of-gos-error-formatting-a-deep-dive-into-type-methods-and-string-representation</guid><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Mon, 01 Jul 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727096683132/57282cc9-c4af-4512-b5cf-2436751faa24.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of Go programming, error handling is a crucial aspect that every developer must master. Today, we're going to explore an intriguing corner case that highlights the nuances of Go's type system, method resolution, and string formatting. This journey began with a seemingly simple custom error type and led us down a rabbit hole of method calls and compiler behaviors.</p>
<h2 id="heading-setting-the-stage">Setting the Stage</h2>
<p>Let's start with a common scenario: implementing a custom error type for a square root function that doesn't accept negative numbers. You can look at the referred code from the <a target="_blank" href="https://go.dev/tour/methods/20">go tour</a>.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> ErrNegativeSqrt <span class="hljs-keyword">float64</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e ErrNegativeSqrt)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"cannot Sqrt negative number: %v"</span>, e)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e ErrNegativeSqrt)</span> <span class="hljs-title">String</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"%v"</span>, <span class="hljs-keyword">float64</span>(e))
}
</code></pre>
<p>At first glance, this looks perfectly reasonable. We have an <code>Error()</code> method to satisfy the <code>error</code> interface, and a <code>String()</code> method for custom string representation. But here's where things get interesting.  </p>
<p>The Compiler's Warning</p>
<p>When compiling this code, you might encounter a surprising warning:</p>
<pre><code class="lang-go">fmt.Sprintf format %v with arg e causes recursive (play.ErrNegativeSqrt).Error method call
</code></pre>
<p>Wait, what? A recursive <code>Error()</code> method call? But we have a <code>String()</code> method defined, shouldn't that be used instead?</p>
<h2 id="heading-unraveling-the-mystery">Unraveling the Mystery</h2>
<p>To understand what's happening, we need to delve into Go's method resolution rules for string formatting.</p>
<p>When using <code>fmt.Sprintf</code> (or any of the <code>fmt</code> package's formatting functions) with the <code>%v</code> verb, Go follows this order of precedence:</p>
<ol>
<li><p>If the type implements <code>fmt.Formatter</code>, use that.</p>
</li>
<li><p>If the type implements <code>error</code>, use <code>Error()</code>.</p>
</li>
<li><p>If the type implements <code>String()</code>, use that.</p>
</li>
<li><p>If none of the above apply, use a default formatting.</p>
</li>
</ol>
<p>In our case, <code>ErrNegativeSqrt</code> implements both <code>error</code> (via <code>Error()</code>) and <code>Stringer</code> (via <code>String()</code>). According to the rules, <code>Error()</code> should take precedence over <code>String()</code> when using <code>%v</code>.</p>
<h2 id="heading-the-plot-thickens">The Plot Thickens</h2>
<p>But here's the twist: in practice, this code often works just fine! The <code>String()</code> method is indeed called, preventing the recursive loop that the compiler warning suggests.</p>
<p>So why the warning? It appears that the Go compiler is being extra cautious. It sees a potential for recursion (even if it doesn't actually occur at runtime) and flags it as a warning.</p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<p>This scenario teaches us several valuable lessons about Go:</p>
<ol>
<li><p><strong>Method Resolution is Complex</strong>: Go's rules for method resolution, especially in formatting contexts, are more nuanced than they might first appear.</p>
</li>
<li><p><strong>Compiler Warnings Are Conservative</strong>: The Go compiler may warn about potential issues even if they don't manifest in practice. These warnings are valuable prompts for code review.</p>
</li>
<li><p><strong>Explicit is Better than Implicit</strong>: To avoid confusion, it's often better to be explicit in our code. We could rewrite our <code>Error()</code> method like this:</p>
</li>
</ol>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e ErrNegativeSqrt)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"cannot Sqrt negative number: %s"</span>, e.String())
}
</code></pre>
<p>This makes our intentions clear and sidesteps any ambiguity.</p>
<ol>
<li><strong>Understanding the Underlying Mechanisms</strong>: This case underscores the importance of understanding not just the syntax of Go, but also its underlying mechanisms and design philosophies.</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Go's simplicity is one of its greatest strengths, but as we've seen, there are depths to explore beneath that simple surface. By diving into edge cases like this one, we not only become better Go programmers but also gain insights into the intricacies of language design and compiler behavior.</p>
<p>The next time you encounter a surprising compiler warning or unexpected behavior in Go, remember this case. It might just be an opportunity to learn something fascinating about the language you thought you knew so well.</p>
<p>Happy coding, Gophers!</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Database Drivers in Go: The Role of lib/pq and pgx in PostgreSQL Connections]]></title><description><![CDATA[In Go (or any other programming language), a database driver like lib/pq or pgx acts as a bridge between your Go application and a PostgreSQL database. Let’s break down what this means and why it’s necessary.
What Is a Database Driver?
A database dri...]]></description><link>https://blog.dushyanth.in/understanding-database-drivers-in-go-the-role-of-libpq-and-pgx-in-postgresql-connections</link><guid isPermaLink="true">https://blog.dushyanth.in/understanding-database-drivers-in-go-the-role-of-libpq-and-pgx-in-postgresql-connections</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Fri, 10 May 2024 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729247662699/bc087c5b-1c97-4c23-876c-92441aa825cf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Go (or any other programming language), a <strong>database driver</strong> like <code>lib/pq</code> or <code>pgx</code> acts as a <strong>bridge</strong> between your Go application and a PostgreSQL database. Let’s break down what this means and why it’s necessary.</p>
<h3 id="heading-what-is-a-database-driver">What Is a Database Driver?</h3>
<p>A database driver is a piece of software (a library) that knows how to <strong>communicate with a specific type of database</strong>. It implements the <strong>protocols and rules</strong> needed to:</p>
<ol>
<li><p><strong>Establish a connection</strong> to the database.</p>
</li>
<li><p><strong>Send SQL queries</strong> to the database.</p>
</li>
<li><p><strong>Receive and interpret results</strong> from the database.</p>
</li>
<li><p>Handle things like <strong>data serialization</strong> (turning Go types into SQL-compatible types and vice versa).</p>
</li>
</ol>
<p>For PostgreSQL, the drivers <code>lib/pq</code> and <code>pgx</code> do all of these things. Without a driver, your Go application wouldn’t know how to talk to the PostgreSQL database directly.</p>
<h3 id="heading-why-do-we-need-a-driver">Why Do We Need a Driver?</h3>
<p>Here’s why using a driver is essential:</p>
<ol>
<li><p><strong>Database-Specific Communication Protocols</strong>:</p>
<ul>
<li><p>PostgreSQL has its own <strong>communication protocol</strong> for how it expects queries, connections, and data to be sent and received.</p>
</li>
<li><p>The driver implements this protocol so that you don’t have to deal with it directly. You can just write Go code, and the driver will handle the rest.</p>
</li>
</ul>
</li>
<li><p><strong>Data Serialization and Deserialization</strong>:</p>
<ul>
<li><p>The driver takes care of converting Go types (like <code>string</code>, <code>int</code>, <code>float</code>, <code>structs</code>, etc.) into SQL-compatible types (like <code>VARCHAR</code>, <code>INTEGER</code>, <code>DECIMAL</code>, etc.) when sending queries.</p>
</li>
<li><p>Similarly, when the database sends back data, the driver converts it into Go types that your application can work with.</p>
</li>
</ul>
</li>
<li><p><strong>Connection Management</strong>:</p>
<ul>
<li>Database drivers manage the <strong>low-level details</strong> of connecting to the database, including opening connections, maintaining a pool of connections, and handling issues like timeouts or network failures.</li>
</ul>
</li>
<li><p><strong>Simplifies Coding</strong>:</p>
<ul>
<li>Without a driver, you’d have to write a lot of low-level code to handle networking, data conversion, and more. The driver abstracts all that complexity so that you can focus on writing SQL queries and business logic.</li>
</ul>
</li>
</ol>
<h3 id="heading-libpq-vs-pgx-whats-the-difference"><code>lib/pq</code> vs <code>pgx</code>: What’s the Difference?</h3>
<p>Both <code>lib/pq</code> and <code>pgx</code> are popular drivers for connecting to PostgreSQL from Go, but they have some differences:</p>
<ol>
<li><p><code>lib/pq</code>:</p>
<ul>
<li><p>It’s a <strong>pure Go driver</strong> that implements the PostgreSQL protocol.</p>
</li>
<li><p>It was one of the earlier drivers available for Go and is <strong>stable</strong> and <strong>well-tested</strong>.</p>
</li>
<li><p>However, it is no longer actively maintained. It still works fine for most use cases, but it lacks newer features and improvements.</p>
</li>
</ul>
</li>
<li><p><code>pgx</code>:</p>
<ul>
<li><p><code>pgx</code> is newer and is <strong>actively maintained</strong>. It has a lot more features compared to <code>lib/pq</code>.</p>
</li>
<li><p>It can be used in two ways: as a <strong>standalone driver</strong> (similar to <code>lib/pq</code>) or as a <strong>full-fledged PostgreSQL client</strong> with features like connection pooling, support for <code>COPY</code> operations, and native types.</p>
</li>
<li><p>It tends to be <strong>faster</strong> and more <strong>performant</strong> than <code>lib/pq</code> because it has optimizations and a better understanding of PostgreSQL’s internals.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-example-how-it-works">Example: How It Works</h3>
<p>When you write Go code like this:</p>
<pre><code class="lang-go">goCopy codepackage main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"database/sql"</span>
    _ <span class="hljs-string">"github.com/lib/pq"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    connStr := <span class="hljs-string">"user=username dbname=mydb sslmode=disable"</span>
    db, err := sql.Open(<span class="hljs-string">"postgres"</span>, connStr)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        <span class="hljs-built_in">panic</span>(err)
    }
    <span class="hljs-keyword">defer</span> db.Close()

    <span class="hljs-comment">// Run queries here</span>
}
</code></pre>
<ul>
<li><p>The line <code>import _ "</code><a target="_blank" href="http://github.com/lib/pq"><code>github.com/lib/pq</code></a><code>"</code> tells Go to <strong>load the</strong> <code>lib/pq</code> driver so it can handle PostgreSQL connections.</p>
</li>
<li><p>When you call <a target="_blank" href="http://sql.Open"><code>sql.Open</code></a><code>("postgres", connStr)</code>, the Go standard library’s <code>database/sql</code> package knows how to <strong>delegate the connection management</strong> to <code>lib/pq</code>, because <code>lib/pq</code> has registered itself as a driver for the <code>postgres</code> database.</p>
</li>
<li><p>From there on, the driver handles all the <strong>low-level communication</strong> between your application and the PostgreSQL server.</p>
</li>
</ul>
<h3 id="heading-final-words">Final words</h3>
<p>In essence, a database driver is crucial because it <strong>abstracts away</strong> the complex, low-level details of talking to a database. It enables you to write Go code that interacts with the database easily and efficiently, without needing to worry about the underlying protocols and data conversions.</p>
]]></content:encoded></item><item><title><![CDATA[VARCHAR vs VARCHAR(6)]]></title><description><![CDATA[In PostgreSQL, varchar and varchar(n) are both used to define variable-length character string data types, but they have different implications regarding storage, constraints, and performance.
1. Here's a detailed breakdown of the differences:

varch...]]></description><link>https://blog.dushyanth.in/varchar-vs-varchar6</link><guid isPermaLink="true">https://blog.dushyanth.in/varchar-vs-varchar6</guid><category><![CDATA[psql]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 14 Apr 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730294481824/54e73661-6938-4ed7-8848-e4f3b3d87229.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In PostgreSQL, <code>varchar</code> and <code>varchar(n)</code> are both used to define variable-length character string data types, but they have different implications regarding storage, constraints, and performance.</p>
<h3 id="heading-1-heres-a-detailed-breakdown-of-the-differences">1. Here's a detailed breakdown of the differences:</h3>
<ul>
<li><p><code>varchar</code>: This defines a variable-length character string with no specified maximum length. It can store strings of any length, up to the maximum limit imposed by PostgreSQL, which is about 1 GB.</p>
</li>
<li><p><code>varchar(n)</code>: This defines a variable-length character string with a specified maximum length of <code>n</code> characters. If you attempt to store a string longer than <code>n</code>, PostgreSQL will raise an error.</p>
</li>
</ul>
<h3 id="heading-2-storage">2. <strong>Storage</strong>:</h3>
<ul>
<li>Both <code>varchar</code> and <code>varchar(n)</code> store data in a variable-length format, which means they use only the amount of storage necessary to hold the actual string, plus a small amount of overhead (1 or 4 bytes depending on the string length).</li>
</ul>
<h3 id="heading-3-length-constraints">3. <strong>Length Constraints</strong>:</h3>
<ul>
<li><p><code>varchar</code>: There are no constraints on the length of the strings that can be stored. You can store strings of any length, up to the maximum supported by PostgreSQL.</p>
</li>
<li><p><code>varchar(n)</code>: There is a constraint on the length. For example, if you define a column as <code>varchar(6)</code>, you can only store strings with up to 6 characters. Attempting to insert a longer string will result in an error.</p>
</li>
</ul>
<h3 id="heading-4-performance">4. <strong>Performance</strong>:</h3>
<ul>
<li>In general, there is no significant performance difference between <code>varchar</code> and <code>varchar(n)</code> for most use cases. However, using <code>varchar(n)</code> can help enforce data integrity by ensuring that strings do not exceed a certain length, which can prevent issues downstream in your application logic.</li>
</ul>
<h3 id="heading-5-indexing">5. <strong>Indexing</strong>:</h3>
<ul>
<li>Both <code>varchar</code> and <code>varchar(n)</code> types can be indexed. However, if you use <code>varchar(n)</code>, PostgreSQL can optimize storage and performance slightly better in some cases because it knows the maximum length of the data it has to deal with.</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Interface: Pointers vs Values in Go]]></title><description><![CDATA[Interfaces
An interface type is defined as a set of method signatures. A value of interface type can hold any value that implements those methods. Take a look at the below example taken from Go tour.
package main

import (
    "fmt"
    "math"
)

typ...]]></description><link>https://blog.dushyanth.in/interface-pointers-vs-values-in-go</link><guid isPermaLink="true">https://blog.dushyanth.in/interface-pointers-vs-values-in-go</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 31 Mar 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727087982513/fc20d287-827d-46fa-9167-4f3702c5c023.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-interfaces">Interfaces</h3>
<p>An interface type is defined as a set of method signatures. A value of interface type can hold any value that implements those methods. Take a look at the below example taken from <a target="_blank" href="https://go.dev/tour/methods/9">Go tour</a>.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"math"</span>
)

<span class="hljs-keyword">type</span> Abser <span class="hljs-keyword">interface</span> {
    Abs() <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> a Abser
    f := MyFloat(-math.Sqrt2)
    v := Vertex{<span class="hljs-number">3</span>, <span class="hljs-number">4</span>}

    a = f  <span class="hljs-comment">// a MyFloat implements Abser</span>
    a = &amp;v <span class="hljs-comment">// a *Vertex implements Abser</span>

    <span class="hljs-comment">// In the following line, v is a Vertex (not *Vertex)</span>
    <span class="hljs-comment">// and does NOT implement Abser.</span>
    a = v

    fmt.Println(a.Abs())
}

<span class="hljs-keyword">type</span> MyFloat <span class="hljs-keyword">float64</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(f MyFloat)</span> <span class="hljs-title">Abs</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">if</span> f &lt; <span class="hljs-number">0</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">float64</span>(-f)
    }
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">float64</span>(f)
}

<span class="hljs-keyword">type</span> Vertex <span class="hljs-keyword">struct</span> {
    X, Y <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(v *Vertex)</span> <span class="hljs-title">Abs</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Sqrt(v.X*v.X + v.Y*v.Y)
}
</code></pre>
<p><strong><mark>Note: There is an error in the example code on line 22. Vertex (the value type) doesn't implement Abser because the Abs method is defined only on *Vertex (the pointer type).</mark></strong></p>
<p>But if i write <code>func (v Vertex) abs()</code> then also <code>a = &amp;v</code> works! why?  </p>
<p>In Go, when you define a method with a receiver type (like <code>v *Vertex</code> or <code>v Vertex</code>), the receiver can be a <strong>pointer</strong> or a <strong>value</strong> type. This distinction is important because it determines what can call the method.</p>
<h3 id="heading-the-original-case-func-v-vertex-abs">The original case: <code>func (v *Vertex) Abs()</code></h3>
<p>In our original code, the <code>Abs()</code> method is defined with a <strong>pointer receiver</strong>:</p>
<pre><code class="lang-go">
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(v *Vertex)</span> <span class="hljs-title">Abs</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Sqrt(v.X*v.X + v.Y*v.Y)
}
</code></pre>
<p>This means the method can only be called on a <code>*Vertex</code> (a pointer to a <code>Vertex</code>), not a <code>Vertex</code> itself.</p>
<ul>
<li>When you do <code>a = &amp;v</code>, you're assigning a pointer to <code>v</code> (<code>*Vertex</code>), which works fine because the method <code>Abs()</code> is defined on <code>*Vertex</code>, and so <code>&amp;v</code> implements <code>Abser</code>.</li>
</ul>
<p>However, when you do <code>a = v</code> (without the <code>&amp;</code>), <code>v</code> is of type <code>Vertex</code>, not <code>*Vertex</code>. Since the method is defined on <code>*Vertex</code>, <code>v</code> does <strong>not</strong> implement the <code>Abser</code> interface, hence the error.</p>
<h3 id="heading-what-happens-if-you-change-the-method-to-v-vertex-abs">What happens if you change the method to <code>(v Vertex) Abs()</code>?</h3>
<p>If you change the method signature to use a <strong>value receiver</strong>:</p>
<pre><code class="lang-go">
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(v Vertex)</span> <span class="hljs-title">Abs</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Sqrt(v.X*v.X + v.Y*v.Y)
}
</code></pre>
<p>Now the method is defined on the <code>Vertex</code> type (the value type), so it can be called on both <strong>values</strong> of type <code>Vertex</code> and <strong>pointers</strong> of type <code>*Vertex</code>. This is because Go will automatically <strong>dereference</strong> the pointer for you.</p>
<ul>
<li><p>If you have a value <code>v</code> of type <code>Vertex</code>, calling <code>v.Abs()</code> works.</p>
</li>
<li><p>If you have a pointer <code>&amp;v</code> of type <code>*Vertex</code>, calling <code>(&amp;v).Abs()</code> works too because Go automatically dereferences the pointer behind the scenes.</p>
</li>
</ul>
<h3 id="heading-why-does-a-ampv-work-with-a-value-receiver">Why does <code>a = &amp;v</code> work with a value receiver?</h3>
<p>When the method is defined with a value receiver like this:</p>
<pre><code class="lang-go">
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(v Vertex)</span> <span class="hljs-title">Abs</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Sqrt(v.X*v.X + v.Y*v.Y)
}
</code></pre>
<p>It can be called on a pointer (<code>*Vertex</code>) as well. The reason is that Go will implicitly <strong>dereference</strong> the pointer when needed. So, even though the method expects a value (<code>Vertex</code>), you can still pass a pointer (<code>*Vertex</code>) because Go will automatically turn <code>*v</code> into <code>v</code> by dereferencing.</p>
<p>This implicit dereferencing works because a value receiver is less restrictive: the method doesn't modify the original struct (since it's a copy), so Go allows calling it on a pointer too, as it's safe!</p>
]]></content:encoded></item><item><title><![CDATA[Breaking the Loop: Understanding and Fixing Infinite Recursion in Go's Error Method]]></title><description><![CDATA[In the Go programming language, the error interface is a cornerstone for handling errors effectively. However, when implementing the Error() method for custom error types, a common pitfall can lead to infinite recursion, crashing your program. This h...]]></description><link>https://blog.dushyanth.in/breaking-the-loop-understanding-and-fixing-infinite-recursion-in-gos-error-method</link><guid isPermaLink="true">https://blog.dushyanth.in/breaking-the-loop-understanding-and-fixing-infinite-recursion-in-gos-error-method</guid><category><![CDATA[Error method]]></category><category><![CDATA[error]]></category><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Tue, 13 Feb 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735449920190/36e84cff-0759-466f-b6ba-b847da7a3ed5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the Go programming language, the <code>error</code> interface is a cornerstone for handling errors effectively. However, when implementing the <code>Error()</code> method for custom error types, a common pitfall can lead to infinite recursion, crashing your program. This happens when <code>fmt.Sprint</code> is called inside the <code>Error()</code> method. Let’s explore why this happens and how to avoid it.</p>
<p>Consider the following example of a custom error type in Go:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> MyError <span class="hljs-keyword">float64</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e MyError)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-comment">// Potentially dangerous code</span>
    <span class="hljs-keyword">return</span> fmt.Sprint(e)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> e error = MyError(<span class="hljs-number">3.14</span>)
    fmt.Println(e.Error()) <span class="hljs-comment">// Infinite loop!</span>
}
</code></pre>
<p>At first glance, this implementation might seem harmless. However, running the program results in an infinite loop and a stack overflow.</p>
<p>Why does this happen? The <code>fmt.Sprint</code> function has special behavior for types that implement the <code>error</code> interface. It calls the <code>Error()</code> method of the type to produce a string representation.</p>
<p>Here’s the sequence of events:</p>
<ol>
<li><p>The <code>Error()</code> method calls <code>fmt.Sprint(e)</code>.</p>
</li>
<li><p><code>fmt.Sprint(e)</code> recognizes that <code>e</code> implements the <code>error</code> interface and calls <code>e.Error()</code>.</p>
</li>
<li><p>This leads back to step 1, creating an infinite recursion.</p>
</li>
</ol>
<p>This recursion will continue until the program runs out of stack space and crashes.</p>
<h3 id="heading-the-solution-converting-the-type">The Solution: Converting the Type</h3>
<p>To prevent this infinite loop, we need to break the chain of recursion. One way to achieve this is by converting the value to a non-<code>error</code> type before calling <code>fmt.Sprint</code>. For example, you can convert <code>e</code> to a <code>float64</code>:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> MyError <span class="hljs-keyword">float64</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(e MyError)</span> <span class="hljs-title">Error</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-comment">// Convert `e` to float64 to avoid recursion</span>
    <span class="hljs-keyword">return</span> fmt.Sprint(<span class="hljs-keyword">float64</span>(e))
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> e error = MyError(<span class="hljs-number">3.14</span>)
    fmt.Println(e.Error()) <span class="hljs-comment">// Prints "3.14"</span>
}
</code></pre>
<p>By explicitly converting <code>e</code> to <code>float64</code>, <code>fmt.Sprint</code> no longer treats it as an <code>error</code> and simply formats it as a number. This avoids calling the <code>Error()</code> method and resolves the infinite loop</p>
<h3 id="heading-why-does-this-work">Why Does This Work?</h3>
<p>The Go runtime uses type assertions to determine how to handle values passed to <code>fmt.Sprint</code>. When the value is of type <code>error</code>, <code>fmt.Sprint</code> calls its <code>Error()</code> method. By converting the value to another type, such as <code>float64</code>, you effectively tell <code>fmt.Sprint</code> to treat it as a plain number rather than an <code>error</code>.</p>
]]></content:encoded></item><item><title><![CDATA["use strict" in JS]]></title><description><![CDATA["use strict";

var firstName = "Daniel";

function greet() {
  console.log(this.firstName);
}

greet.firstName = "Dushyanth";

greet.greeting = function () {
  console.log(this.firstName);
  function fe() {
    console.log("inside fe " + this.firstNa...]]></description><link>https://blog.dushyanth.in/use-strict-in-js</link><guid isPermaLink="true">https://blog.dushyanth.in/use-strict-in-js</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 31 Dec 2023 18:30:00 GMT</pubDate><content:encoded><![CDATA[<pre><code class="lang-javascript"><span class="hljs-meta">"use strict"</span>;

<span class="hljs-keyword">var</span> firstName = <span class="hljs-string">"Daniel"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.firstName);
}

greet.firstName = <span class="hljs-string">"Dushyanth"</span>;

greet.greeting = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.firstName);
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fe</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"inside fe "</span> + <span class="hljs-built_in">this</span>.firstName);
  }
  fe();
  <span class="hljs-comment">// fe.bind(this)();</span>
};

greet.greeting();

greet();
</code></pre>
<p>Curious case of “use strict”</p>
]]></content:encoded></item><item><title><![CDATA[System Data :(]]></title><description><![CDATA[Several ways to clear system data on Mac OS.
1: Clear system cache: Go to Finder > Go > Go to Folder, then type in "~/Library/Caches" and hit enter. Select all the folders inside the Caches folder and delete them.
2: Clear system logs: Go to Finder >...]]></description><link>https://blog.dushyanth.in/system-data</link><guid isPermaLink="true">https://blog.dushyanth.in/system-data</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Sun, 31 Dec 2023 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p>Several ways to clear system data on Mac OS.</p>
<p>1: Clear system cache: Go to Finder &gt; Go &gt; Go to Folder, then type in "~/Library/Caches" and hit enter. Select all the folders inside the Caches folder and delete them.</p>
<p>2: Clear system logs: Go to Finder &gt; Go &gt; Go to Folder, then type in "/var/log" and hit enter. Select all the files inside the Log folder and delete them.</p>
<p>3: Remove unused language files: Go to Finder &gt; Go &gt; Go to Folder, then type in "/Library/Languages" and hit enter. Delete all the language folders you don't need.</p>
<p>4: Uninstall unused apps: Go to the Applications folder and delete the apps you don't use.</p>
<p>5: Clean up system files: Use a system cleaning tool like CleanMyMac X to scan and remove unnecessary system files.</p>
<p>Docker files</p>
<pre><code class="lang-bash">docker system prune -a --volumes
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Upgrade GO (self-note)]]></title><description><![CDATA[Remove the existing go directory and download the latest go pkg from https://go.dev/dl/  

Run the downloaded installer! And it’s DONE 👍]]></description><link>https://blog.dushyanth.in/upgrade-go-self-note</link><guid isPermaLink="true">https://blog.dushyanth.in/upgrade-go-self-note</guid><dc:creator><![CDATA[Dushyanth]]></dc:creator><pubDate>Wed, 08 Nov 2023 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742058594923/8a044fb0-80f7-4529-87cc-fef28670a7d7.png" alt class="image--center mx-auto" /></p>
<p>Remove the existing go directory and download the latest go pkg from <a target="_blank" href="https://go.dev/dl/">https://go.dev/dl/</a>  </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742058674762/0a9482a9-b9ef-4810-b841-ccfa33c4d0e0.png" alt class="image--center mx-auto" /></p>
<p>Run the downloaded installer! And it’s DONE 👍</p>
]]></content:encoded></item></channel></rss>