<?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[Manik Agnish]]></title><description><![CDATA[Manik Agnish]]></description><link>https://blog.manikagnish.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 06 May 2026 11:25:12 GMT</lastBuildDate><atom:link href="https://blog.manikagnish.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Extending Expo UI with SwiftUI: Building a Native swipeActions Modifier]]></title><description><![CDATA[@expo/ui/swift-ui lets you compose SwiftUI views and modifiers from JavaScript. HStack, VStack, List, font, foregroundStyle, onTapGesture, refreshable. It is a sizeable chunk of SwiftUI, but not all o]]></description><link>https://blog.manikagnish.com/extending-expo-ui-with-swiftui-building-a-native-swipeactions-modifier</link><guid isPermaLink="true">https://blog.manikagnish.com/extending-expo-ui-with-swiftui-building-a-native-swipeactions-modifier</guid><category><![CDATA[React Native]]></category><category><![CDATA[Expo]]></category><category><![CDATA[SwiftUI]]></category><category><![CDATA[iOS]]></category><category><![CDATA[expo-modules]]></category><category><![CDATA[expo-ui]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sun, 03 May 2026 14:17:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/63d282973bb03008dbb2ab3b/522a399b-bfc5-46b8-8468-7d7e53607d66.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>@expo/ui/swift-ui</code> lets you compose SwiftUI views and modifiers from JavaScript. <code>HStack</code>, <code>VStack</code>, <code>List</code>, <code>font</code>, <code>foregroundStyle</code>, <code>onTapGesture</code>, <code>refreshable</code>. It is a sizeable chunk of SwiftUI, but not all of it. One day you will reach for something that is not there.</p>
<p>For me, that something was <code>swipeActions</code>, the swipe-from-the-edge buttons you see in iOS Mail. My app already rendered each row inside a SwiftUI <code>List</code>, so wiring up Edit / Skip / Delete swipe actions should have been one line of SwiftUI. Except <code>@expo/ui</code> did not expose it.</p>
<p>This post walks through building it as a local Expo module. The result is around 80 lines of Swift, around 30 lines of TypeScript, and one <code>npm install</code> to wire up. If you have never written Swift before, that is fine. I will explain the Swift-specific bits as we go.</p>
<h2>View or modifier? The choice is forced</h2>
<p>Before any code, a decision: do you build this as a <strong>native view</strong> or a <strong>native modifier</strong>?</p>
<p>A native view is what <code>npx create-expo-module --local</code> creates by default. You expose a SwiftUI view to JS, and JS renders it like any other component.</p>
<p>A native modifier is what Expo UI uses for things like <code>font(...)</code> or <code>onTapGesture(...)</code>. They do not render anything on their own, they style or extend an existing view. Think of them as the SwiftUI equivalent of styled-components mixins, except they can also attach behaviour like gestures and lifecycle callbacks.</p>
<p>For <code>swipeActions</code>, the choice is forced by SwiftUI itself. <code>.swipeActions(edge:allowsFullSwipe:content:)</code> only works when SwiftUI sees it attached to a row inside a <code>List</code>. If you wrap the row in a custom view, SwiftUI no longer sees a row inside a list, it sees a generic view containing your wrapper containing the row, and <code>.swipeActions</code> becomes a no-op. So, modifier it is.</p>
<h2>Creating the module</h2>
<pre><code class="language-sh">npx create-expo-module@latest --local swipe-actions
</code></pre>
<p>This creates <code>modules/swipe-actions/</code> with a sample WebView component, Android files, and a web fallback. For a SwiftUI-only modifier you can throw most of it away. Here is the final structure I ended up with:</p>
<pre><code class="language-plaintext">modules/swipe-actions/
├── expo-module.config.json
├── package.json
├── index.ts
└── ios/
    ├── SwipeActions.podspec
    ├── SwipeActionRecord.swift
    ├── SwipeActionsModifier.swift
    └── SwipeActionsModule.swift
</code></pre>
<p>The config narrows to iOS:</p>
<pre><code class="language-json">{
  "platforms": ["apple"],
  "apple": { "modules": ["SwipeActionsModule"] }
}
</code></pre>
<p>And the <code>package.json</code> is just a name plus main:</p>
<pre><code class="language-json">{
  "name": "swipe-actions",
  "version": "1.0.0",
  "main": "index.ts",
  "types": "index.ts",
  "private": true
}
</code></pre>
<p>The podspec needs one line beyond the default, a dependency on <code>ExpoUI</code>, which is what gives us access to the modifier registry:</p>
<pre><code class="language-ruby">s.dependency 'ExpoModulesCore'
s.dependency 'ExpoUI'
</code></pre>
<h2>The Swift side, in three small files</h2>
<p>We will go bottom-up. A "record" that describes one swipe action, a modifier that consumes those records, and a module that registers the modifier so JS can use it.</p>
<h3>A quick Swift primer for RN devs</h3>
<p>A few Swift concepts come up in the next sections. If you already know Swift, skip this.</p>
<ul>
<li><p><code>struct</code> and <code>class</code> are like JS classes, but <code>struct</code> is a value type (copied when passed around) and <code>class</code> is a reference type. SwiftUI uses structs almost everywhere because views are cheap to recreate.</p>
</li>
<li><p><code>protocol</code> is Swift's word for interface. When a type "conforms to" a protocol, it is promising to provide certain methods or properties.</p>
</li>
<li><p><code>?</code> after a type means "optional", essentially the same as <code>T | null</code> in TypeScript. <code>String?</code> is a string or nil.</p>
</li>
<li><p><code>@PropertyWrapper</code> (anything starting with <code>@</code>) is a Swift annotation that adds behaviour to a property, similar to a decorator.</p>
</li>
<li><p><code>some View</code> is a return type that means "some specific type that conforms to <code>View</code>, the compiler will figure out which one." You will see it on every SwiftUI view's <code>body</code>.</p>
</li>
</ul>
<p>That is enough to read everything below.</p>
<h3>A record per action</h3>
<p>Each swipe action has an id, a label, an optional icon, an optional tint colour, and an optional role. In Expo's SwiftUI extension, anything you decode from JS params follows the <code>Record</code> protocol and uses <code>@Field</code> to mark which properties come from the JS side:</p>
<pre><code class="language-swift">// SwipeActionRecord.swift
import ExpoModulesCore
import SwiftUI

final class SwipeActionRecord: Record {
  @Field var id: String = ""
  @Field var label: String = ""
  @Field var systemImage: String? = nil
  @Field var tint: Color? = nil
  @Field var role: String? = nil
}
</code></pre>
<p>Two things to notice. First, <code>@Field var tint: Color? = nil</code>. <code>ExpoModulesCore</code> decodes hex strings like <code>"#FF3B30"</code> from JS straight into a SwiftUI <code>Color</code>. No manual parsing on either side. Second, <code>role</code> is a string rather than a Swift enum, because the JS side sends <code>"destructive"</code> or <code>"cancel"</code> and decoding into custom Swift enums needs extra setup that is not worth it for two values.</p>
<p><code>systemImage</code> refers to SF Symbols, Apple's built-in icon library. Names like <code>"trash"</code>, <code>"pencil"</code>, and <code>"forward.fill"</code> map to icons that ship with iOS, so you do not need to bundle anything.</p>
<h3>The modifier</h3>
<p>This is the heart of it. A type that conforms to both SwiftUI's <code>ViewModifier</code> protocol (so SwiftUI can apply it) and Expo's <code>Record</code> protocol (so it can be decoded from JS params):</p>
<pre><code class="language-swift">// SwipeActionsModifier.swift
import ExpoModulesCore
import SwiftUI

struct SwipeActionsModifier: ViewModifier, Record {
  @Field var leading: [SwipeActionRecord] = []
  @Field var trailing: [SwipeActionRecord] = []
  @Field var allowsFullSwipe: Bool = false

  var eventDispatcher: EventDispatcher?

  init() {}

  init(from params: Dict, appContext: AppContext, eventDispatcher: EventDispatcher) throws {
    try self = .init(from: params, appContext: appContext)
    self.eventDispatcher = eventDispatcher
  }

  func body(content: Content) -&gt; some View {
    content
      .swipeActions(edge: .trailing, allowsFullSwipe: allowsFullSwipe) {
        ForEach(trailing, id: \.id) { action in
          actionButton(action)
        }
      }
      .swipeActions(edge: .leading, allowsFullSwipe: allowsFullSwipe) {
        ForEach(leading, id: \.id) { action in
          actionButton(action)
        }
      }
  }

  @ViewBuilder
  private func actionButton(_ action: SwipeActionRecord) -&gt; some View {
    let role: ButtonRole? = {
      switch action.role {
      case "destructive": return .destructive
      case "cancel":      return .cancel
      default:            return nil
      }
    }()
    Button(role: role) {
      eventDispatcher?(["swipeActions": ["id": action.id]])
    } label: {
      if let icon = action.systemImage {
        Label(action.label, systemImage: icon)
      } else {
        Text(action.label)
      }
    }
    .tint(action.tint)
  }
}
</code></pre>
<p>There is a lot happening here, so let's walk through it.</p>
<p>The two <code>init</code> methods exist because <code>Record</code> requires a no-argument <code>init()</code> for the decoding machinery. The second <code>init</code> is the one Expo actually calls when wiring this up, and it takes the decoded params plus an <code>EventDispatcher</code>, then forwards the params to the standard <code>Record</code> init and stashes the dispatcher.</p>
<p>The <code>eventDispatcher</code> is <strong>not</strong> a <code>@Field</code>. It is a regular stored property. This trips people up because most other things on a Record are <code>@Field</code>s. The dispatcher does not come from JSON params, it is injected by the registry at registration time, which is why it gets its own init parameter.</p>
<p><code>func body(content: Content) -&gt; some View</code> is the method every <code>ViewModifier</code> implements. <code>content</code> is the view this modifier is being applied to (in our case, the <code>List</code> row). We return a new view that takes that content and stacks two <code>.swipeActions</code> calls onto it, one for each edge.</p>
<p><code>ForEach(trailing, id: \.id)</code> is SwiftUI's loop. The <code>\.id</code> syntax is a "key path", Swift's way of saying "use the <code>id</code> property of each element as the React-style key." Inside the closure, <code>$0</code> is shorthand for the current element (Swift's equivalent of an arrow function's first arg).</p>
<p><code>actionButton</code> builds a single button. The <code>@ViewBuilder</code> annotation lets us use <code>if/else</code> inside to conditionally include a <code>Label</code> (icon plus text) or a plain <code>Text</code>. When the button is tapped, we call <code>eventDispatcher</code> with a dictionary. That dictionary travels back to JS as an event payload.</p>
<p>One subtle but important detail: the key in <code>["swipeActions": ["id": action.id]]</code> must match the modifier's type identifier (the <code>\(type</code> field on the JS side, which we will see in a moment). Expo UI registers event listeners in a map keyed by <code>\)type</code>, so if you dispatch under any other name the event silently disappears into nothing. If your event handler is not firing, this is the first thing to check.</p>
<h3>Registering the modifier</h3>
<pre><code class="language-swift">// SwipeActionsModule.swift
import ExpoModulesCore
import ExpoUI

public class SwipeActionsModule: Module {
  public func definition() -&gt; ModuleDefinition {
    Name("SwipeActions")

    OnCreate {
      ViewModifierRegistry.register("swipeActions") { params, appContext, eventDispatcher in
        try SwipeActionsModifier(
          from: params,
          appContext: appContext,
          eventDispatcher: eventDispatcher
        )
      }
    }

    OnDestroy {
      ViewModifierRegistry.unregister("swipeActions")
    }
  }
}
</code></pre>
<p><code>Module</code> is the Expo base class that every native module extends. <code>definition()</code> is where you describe what the module exposes: its name, lifecycle hooks, methods, views, and so on.</p>
<p><code>OnCreate</code> and <code>OnDestroy</code> are lifecycle hooks. Registering inside <code>OnCreate</code> rather than at the top level is not optional, the docs call this out specifically to avoid a threading race where the registry is read before your modifier is added.</p>
<p>The third parameter of the registration closure (<code>eventDispatcher</code>) is what gets threaded into the modifier's secondary init. That is the missing link from the previous section.</p>
<h2>The JavaScript side</h2>
<p>The TS layer is small. It does two things: convert a friendly per-action <code>onPress</code> callback API into a structure that can be serialised across to native, and dispatch incoming events back to the right callback by id.</p>
<pre><code class="language-ts">// index.ts
import { createModifierWithEventListener } from "@expo/ui/swift-ui/modifiers";

export type SwipeActionRole = "destructive" | "cancel";

export interface SwipeActionConfig {
  id: string;
  label: string;
  systemImage?: string;
  tint?: string;
  role?: SwipeActionRole;
  onPress: () =&gt; void;
}

export interface SwipeActionsParams {
  leading?: SwipeActionConfig[];
  trailing?: SwipeActionConfig[];
  allowsFullSwipe?: boolean;
}

export function swipeActions(params: SwipeActionsParams) {
  const handlers = new Map&lt;string, () =&gt; void&gt;();
  for (const a of params.leading ?? []) handlers.set(a.id, a.onPress);
  for (const a of params.trailing ?? []) handlers.set(a.id, a.onPress);

  const stripPress = ({ onPress, ...rest }: SwipeActionConfig) =&gt; rest;

  return createModifierWithEventListener(
    "swipeActions",
    ({ id }: { id: string }) =&gt; handlers.get(id)?.(),
    {
      leading: (params.leading ?? []).map(stripPress),
      trailing: (params.trailing ?? []).map(stripPress),
      allowsFullSwipe: params.allowsFullSwipe ?? false,
    }
  );
}
</code></pre>
<p><code>createModifierWithEventListener</code> is the helper Expo UI uses internally for <code>onTapGesture</code>, <code>onAppear</code>, <code>refreshable</code>, and friends. It returns a config object with a <code>\(type</code> (which must match the string we registered on the Swift side) and an <code>eventListener</code>. When the host view renders, it scans its modifiers for event listeners and registers them by <code>\)type</code>.</p>
<p>The <code>stripPress</code> step is necessary because functions cannot cross the JS-to-native boundary as props. We pull the callbacks into a JS-side <code>Map</code> keyed by id, send only the serialisable fields across, and let the single event listener dispatch to the right callback when the native side fires <code>["swipeActions": ["id": "delete"]]</code>.</p>
<h2>Wiring it into a screen</h2>
<p>From the JS side, you apply it like any other modifier. Drop it into the <code>modifiers</code> array on a row inside a <code>List</code>:</p>
<pre><code class="language-tsx">import { swipeActions } from "swipe-actions";
import { List, HStack } from "@expo/ui/swift-ui";

&lt;List&gt;
  &lt;HStack
    alignment="center"
    modifiers={[
      swipeActions({
        leading: [
          {
            id: "archive",
            label: "Archive",
            systemImage: "archivebox",
            tint: "teal",
            onPress: handleArchive,
          },
        ],
        trailing: [
          {
            id: "delete",
            label: "Delete",
            systemImage: "trash",
            tint: "#FF3B30",
            role: "destructive",
            onPress: handleDelete,
          },
          {
            id: "edit",
            label: "Edit",
            systemImage: "pencil",
            tint: "#0A84FF",
            onPress: handleEdit,
          },
        ],
        allowsFullSwipe: false,
      }),
    ]}
  &gt;
    {/* content */}
  &lt;/HStack&gt;
&lt;/List&gt;
</code></pre>
<p>For TS resolution, add the local module to your root <code>package.json</code>:</p>
<pre><code class="language-json">"swipe-actions": "file:./modules/swipe-actions"
</code></pre>
<p><code>npm install</code> symlinks it under <code>node_modules/</code>.</p>
<p><code>cd ios &amp;&amp; pod install</code> (or <code>npx expo run:ios</code>) autolinks the native side. Done.</p>
<h2>Wrapping up</h2>
<p>The full source is small enough to read in one sitting, around 110 lines across four files. The hardest part was not writing it, it was figuring out which 110 lines to write. If you are extending Expo UI with your own modifiers, the pattern is the same every time: a <code>Record</code> for params, a <code>ViewModifier</code> that consumes them, an <code>EventDispatcher</code> injected via a secondary init, and a <code>Module</code> that registers the whole thing in <code>OnCreate</code>. Once you’ve built one, the next time is much easier since you’re just repeating the same pattern.</p>
]]></content:encoded></item><item><title><![CDATA[Scrum 101: Everything you need to know to run a successful team]]></title><description><![CDATA[We have all been there. The project kicks off with high energy and vague requirements. We spend months building what we think the client wants, only to reveal it at the finish line and realise we built the wrong thing. This approach is often called W...]]></description><link>https://blog.manikagnish.com/mastering-the-scrum-framework-for-high-performance-teams</link><guid isPermaLink="true">https://blog.manikagnish.com/mastering-the-scrum-framework-for-high-performance-teams</guid><category><![CDATA[agile]]></category><category><![CDATA[Scrum]]></category><category><![CDATA[project management]]></category><category><![CDATA[SaaS]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Mon, 08 Dec 2025 16:53:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765212583539/6c75f925-1410-41c3-a9bd-16074962e5f2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We have all been there. The project kicks off with high energy and vague requirements. We spend months building what we think the client wants, only to reveal it at the finish line and realise we built the wrong thing. This approach is often called Waterfall, but in reality, it is simply a high-stakes gamble. In the modern world of software development, where market needs shift overnight, gambling on a six-month plan is a recipe for disaster.</p>
<p>This is where Scrum changes the narrative. It is not just a set of meetings or a to-do list; it is a framework designed to bring order to chaos. If you want to move from frantically putting out fires to delivering consistent value, you need to understand not just <em>what</em> Scrum is, but <em>why</em> it works.</p>
<h3 id="heading-the-foundation-of-empirical-control">The Foundation of Empirical Control</h3>
<p>To understand Scrum, you have to let go of the idea that you can predict the future. Traditional project management assumes we know everything at the start. Scrum assumes we know very little. It is founded on <strong>Empiricism</strong>, which means making decisions based on what is actually happening, not what we hope will happen.</p>
<p>This approach relies on three non-negotiable pillars.</p>
<ul>
<li><p><strong>Transparency</strong> requires that significant aspects of the process must be visible to those responsible for the outcome. There is no hiding bad news.</p>
</li>
<li><p><strong>Inspection</strong> involves frequently checking the Scrum artefacts and progress towards a Goal to detect undesirable variances.</p>
</li>
<li><p><strong>Adaptation</strong> is the ability to adjust the process or material immediately if the inspection reveals issues.</p>
</li>
</ul>
<p>These pillars are supported by five core values: Commitment, Focus, Openness, Respect, and Courage. Without these values, the pillars crumble, and Scrum becomes a hollow shell.</p>
<h3 id="heading-the-team-structure">The Team Structure</h3>
<p>You cannot play a professional sport with a random crowd of people. You need a dedicated, optimised squad. In Scrum, the team structure is designed for flexibility and speed. We follow the "Two Pizza Rule" famously coined by Jeff Bezos. If you cannot feed the entire team with two pizzas, the group is too large. Ideally, a Scrum Team is 10 people or fewer.</p>
<p>Within this small group, we strip away the traditional hierarchy. There are no managers here, only three distinct roles that balance each other out.</p>
<p><strong>The Product Owner</strong> is the visionary. They are responsible for maximising the value of the product. They manage the Product Backlog and clearly communicate the <em>what</em> and the <em>why</em>. They are the single voice of the stakeholder.</p>
<p><strong>The Scrum Master</strong> is the servant-leader. They are not a project manager who assigns tasks. Instead, they coach the team, remove impediments that block progress, and ensure the Scrum framework is understood and enacted.</p>
<p><strong>The Developers</strong> are the professionals who do the work. They are self-organising and cross-functional. They alone decide <em>how</em> to turn the Product Owner’s vision into a working Increment.</p>
<h3 id="heading-scrum-events">Scrum Events</h3>
<p>The heartbeat of Scrum is the Sprint, a fixed time-box of one month or less, which acts as a container for four other formal events designed to ensure inspection and adaptation.</p>
<p>Here is exactly how each event works.</p>
<p><strong>1. The Sprint</strong></p>
<ul>
<li><p><strong>Time-box:</strong> One month or less (usually 2 weeks).</p>
</li>
<li><p><strong>The Concept:</strong> This is the container for all other events. Once a Sprint begins, its duration is fixed and cannot be shortened or lengthened. It is a period of focus.</p>
</li>
</ul>
<p><strong>2. Sprint Planning</strong></p>
<ul>
<li><p><strong>Time-box:</strong> Maximum 8 hours for a one-month Sprint (usually 4 hours for a 2-week Sprint).</p>
</li>
<li><p><strong>How it works:</strong> This event lays out the work to be performed for the Sprint. It addresses three specific topics:</p>
<ul>
<li><p><strong>Topic One: The Why (Sprint Goal).</strong> The Product Owner proposes how the product could increase its value in the current Sprint. The whole Scrum Team then collaborates to define a Sprint Goal that communicates <em>why</em> the Sprint is valuable to stakeholders.</p>
</li>
<li><p><strong>Topic Two: The What.</strong> The Developers select items from the Product Backlog to include in the current Sprint. This is where we must look at two critical metrics:</p>
<ul>
<li><p><strong>Velocity:</strong> This is the team's historical speed. It is a measure of how much work (usually in story points) the team successfully completed in previous Sprints. It tells us how fast we <em>usually</em> run.</p>
</li>
<li><p><strong>Capacity:</strong> This is how much time we <em>actually</em> have available right now. We calculate this by taking the total available hours of the team and subtracting holidays, meetings, and time off. It tells us how much fuel is in the tank for this specific trip.</p>
</li>
</ul>
</li>
<li><p><strong>Topic Three: The How.</strong> For each selected item, the Developers plan the work necessary to create an Increment that meets the Definition of Done. This often involves breaking stories down into tasks of one day or less.</p>
</li>
</ul>
</li>
</ul>
<p><strong>3. The Daily Scrum</strong></p>
<ul>
<li><p><strong>Time-box:</strong> 15 minutes. Strictly.</p>
</li>
<li><p><strong>How it works:</strong> This is an internal meeting for the Developers. It is <strong>not</strong> a status report to the Scrum Master or management. The purpose is to inspect progress toward the Sprint Goal and adapt the Sprint Backlog as necessary.</p>
<ul>
<li><p><strong>The Format:</strong> Many teams use three simple questions:</p>
<ol>
<li><p>What did I do yesterday that helped the Team meet the Sprint Goal?</p>
</li>
<li><p>What will I do today to help the Team meet the Sprint Goal?</p>
</li>
<li><p>Do I see any impediment that prevents me or the Team from meeting the Sprint Goal?</p>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<p><strong>4. Sprint Review</strong></p>
<ul>
<li><p><strong>Time-box:</strong> Maximum 4 hours for a one-month Sprint.</p>
</li>
<li><p><strong>How it works:</strong> This is held at the end of the Sprint to inspect the Increment and adapt the Product Backlog.</p>
<ul>
<li><p><strong>The Demo:</strong> The Scrum Team presents the results of their work to key stakeholders. This is not a PowerPoint presentation; it is a demo of working software.</p>
</li>
<li><p><strong>The Feedback:</strong> The group discusses what was done, what was not done, and what to do next. The Product Backlog may be adjusted to meet new opportunities.</p>
</li>
</ul>
</li>
</ul>
<p><strong>5. Sprint Retrospective</strong></p>
<ul>
<li><p><strong>Time-box:</strong> Maximum 3 hours for a one-month Sprint.</p>
</li>
<li><p><strong>How it works:</strong> This occurs after the Sprint Review and prior to the next Sprint Planning. While the Review inspects the <em>product</em>, the Retrospective inspects the <em>process</em>. The team discusses:</p>
<ul>
<li><p>What went well?</p>
</li>
<li><p>What went wrong?</p>
</li>
<li><p>What can we improve in the next Sprint?</p>
</li>
<li><p><strong>The Outcome:</strong> The team must identify at least one concrete improvement to implement in the upcoming Sprint.</p>
</li>
</ul>
</li>
</ul>
<p>Now, I can see some of you rolling your eyes. You are reading this list and thinking, "Great, more meetings. Just what I needed."</p>
<p>But here is the truth: The goal of Scrum is actually to <strong>reduce</strong> the number of meetings you have to attend. By condensing all the planning, syncing, and reviewing into these five predictable, time-boxed events, we eliminate the need for all those random, unstructured "quick syncs" and status updates that interrupt your flow. The strategy is to get the talking done efficiently so that for the rest of the time, the Developers can focus on the only thing that matters: actually building the product.</p>
<h3 id="heading-scrum-artefacts">Scrum Artefacts</h3>
<p>In a complex environment, ambiguity is the enemy. To fight this, Scrum uses three specific artefacts to ensure everyone is looking at the same thing. If these artefacts are not transparent, decisions will be flawed and risk will increase.</p>
<p><strong>1. The Product Backlog</strong></p>
<ul>
<li><p><strong>What it is:</strong> An ordered list of everything that is known to be needed in the product. It is the single source of truth for requirements.</p>
</li>
<li><p><strong>Refinement:</strong> This is an ongoing activity where the Product Owner and Developers add details, estimates, and order to items. We need to get items to a "Ready" state, meaning they are clear enough to be selected in a Sprint Planning meeting.</p>
</li>
<li><p><strong>Monitoring Progress:</strong> The Product Owner tracks remaining work using a <strong>Release Burndown Chart</strong>. This visualises the trend of work remaining across the entire project timeline, helping to forecast a likely completion date.</p>
</li>
</ul>
<p><strong>2. The Sprint Backlog</strong></p>
<ul>
<li><p><strong>What it is:</strong> The set of Product Backlog items selected for the Sprint, plus the plan for delivering them. It is a highly visible, real-time picture of the work that the Developers plan to accomplish during the Sprint.</p>
</li>
<li><p><strong>Ownership:</strong> The Sprint Backlog belongs solely to the Developers.</p>
</li>
<li><p><strong>Monitoring Progress:</strong> The Developers use a <strong>Sprint Burndown Chart</strong>. This tracks the total work remaining in the Sprint on a daily basis. If the line is not trending down, the team knows immediately that they need to adapt their plan.</p>
</li>
</ul>
<p><strong>3. The Increment and the Definition of Done</strong></p>
<ul>
<li><p><strong>What it is:</strong> The Increment is the sum of all the Product Backlog items completed during a Sprint and the value of the increments of all previous Sprints.</p>
</li>
<li><p><strong>The Definition of Done (DoD):</strong> This is the most critical concept for quality. It is a formal description of the state of the Increment when it meets the quality measures required for the product. It is a shared contract. If a Product Backlog item does not meet the DoD, it cannot be released or even presented at the Sprint Review. It returns to the Product Backlog.</p>
</li>
</ul>
<p><strong>Example: A Team-Wide Definition of Done</strong></p>
<ul>
<li><p>Code is written, peer-reviewed, and merged to the main branch.</p>
</li>
<li><p>Unit tests are written and passing.</p>
</li>
<li><p>Feature is deployed to the test environment.</p>
</li>
<li><p>No critical or high-severity bugs are open.</p>
</li>
<li><p>User documentation has been updated.</p>
</li>
</ul>
<p><strong>DoD vs. Acceptance Criteria</strong> It is vital to distinguish the DoD from Acceptance Criteria.</p>
<ul>
<li><p><strong>Acceptance Criteria</strong> are specific to a single ticket (e.g., "As a user, when I click 'Reset Password', I receive an email within 2 minutes").</p>
</li>
<li><p><strong>DoD</strong> applies to <em>every</em> ticket (e.g., "The code must be reviewed").</p>
</li>
</ul>
<p>The DoD ensures that we are not just building features, but building a high-quality, maintainable product. Transparency is only achieved when "Done" means the same thing to everyone.</p>
<h3 id="heading-avoiding-common-implementation-traps">Avoiding Common Implementation Traps</h3>
<p>Even with the best intentions, teams often drift back into old habits. Recognising these common anti-patterns is the final step in mastering Scrum.</p>
<p>One frequent mistake is treating the Scrum Master as a team boss or secretary. When the team relies on the Scrum Master to assign work or organise every detail, they lose their self-organisation. The Scrum Master is a coach, not a commander.</p>
<p>Another trap is allowing work to bleed over from one Sprint to the next. This usually happens when stories are too large or the team is overly optimistic. It destroys the value of the Sprint as a hard deadline. The fix is to break stories down into smaller, manageable chunks that can definitely be finished within the time-box.</p>
<p>Finally, the most dangerous mistake is skipping the Retrospective. Teams often feel they are "too busy" to stop and talk about their process. This is short-sighted. The Retrospective is the engine of improvement. Without it, you will never get faster, and you will never fix the systemic issues slowing you down.</p>
<h3 id="heading-the-final-truth-scrum-reveals-it-does-not-fix">The Final Truth: Scrum Reveals, It Does Not Fix</h3>
<p>Scrum is often described as "simple to understand, difficult to master". That is the understatement of the century. Many teams fail because they treat Scrum like a magic wand, expecting it to instantly solve their deadlines and bug counts. But Scrum is not a solution; it is a mirror. When you start running Sprints correctly, the framework will ruthlessly expose every crack in your process. You will see clearly where your requirements are vague, where your testing is slow, and where your team lacks focus. That transparency can be uncomfortable. But if you have the courage to stare into that mirror and adapt rather than ignore what you see, you will stop just "doing Agile" and start actually delivering value.</p>
]]></content:encoded></item><item><title><![CDATA[Hoisting and scoping: A deep dive into your interviewer's favourite question.]]></title><description><![CDATA[If you have ever given a javascript interview chances are you have been asked about hoisting and variable scoping. You may know the definition but in order to solve those tricky "guess the output" questions you need to have a deep knowledge about how...]]></description><link>https://blog.manikagnish.com/hoisting-and-scoping-a-deep-dive-into-your-interviewers-favourite-question</link><guid isPermaLink="true">https://blog.manikagnish.com/hoisting-and-scoping-a-deep-dive-into-your-interviewers-favourite-question</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[interview]]></category><category><![CDATA[Hoisting]]></category><category><![CDATA[scoping]]></category><category><![CDATA[Deep Dive]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sat, 24 May 2025 23:23:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748128814837/464de03e-d317-40aa-aa90-a9a1aaf08ade.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have ever given a javascript interview chances are you have been asked about hoisting and variable scoping. You may know the definition but in order to solve those tricky "guess the output" questions you need to have a deep knowledge about how javascript works under the hood. Which is precisely what I am going to cover in this article. So put on your reading glasses, put away your phone and get ready to dive deep, unless of course you are reading this on your phone... don't put away your phone it that case ✌️. But if you are here just for the interview questions then skip to the end and go to town! Anyways let's begin.</p>
<h3 id="heading-declaring-a-variable-in-javascript">Declaring a variable in javascript</h3>
<p>Just in case you don't already know there are three ways of declaring a variable in javascript know to mankind (bots too these days 🤖): var, let and const.</p>
<p><strong>var</strong></p>
<p>Ah, <code>var</code>, a relic of JavaScript's earlier days, presumably crafted by developers hammering away on Windows XP using Notepad as their trusty sidekick. It's notorious for turning straightforward code into a head-scratching puzzle.</p>
<p>Variables declared with <code>var</code> can be both re-assigned and re-declared, setting the stage for some truly perplexing bugs. 😬</p>
<p><strong>let</strong></p>
<p>The cooler, younger sibling introduced in ES6. Variables declared with <code>let</code> can be reassigned but not re-declared within the same scope. It's not necessary to initialise them at the point of declaration.</p>
<p><strong>const</strong></p>
<p>Also debuting in ES6, <code>const</code> is for constants. Reassigning them will throw an error. You must initialise <code>const</code> variables when you declare them.</p>
<h3 id="heading-variable-scope"><strong>Variable Scope</strong></h3>
<p>Scope defines where variables can be accessed within your code. If you declare a variable inside a function, it's only accessible within that function, not outside. Scope comes in three flavours: global, function, and block.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">daScope</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> fullName = <span class="hljs-string">"Eren Yeager"</span>;
  <span class="hljs-built_in">console</span>.log(fullName); <span class="hljs-comment">// Outputs: Eren Yeager</span>

  <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-keyword">const</span> titan = <span class="hljs-string">"mix veg"</span>;
    <span class="hljs-built_in">console</span>.log(titan); <span class="hljs-comment">// Outputs: mix veg</span>
  }

  <span class="hljs-built_in">console</span>.log(titan); <span class="hljs-comment">// Error: titan is not defined</span>
}

daScope();
</code></pre>
<p>This code neatly illustrates block scoping. However, <code>var</code> plays by its own rules, it's function-scoped, so it can be accessed anywhere within the function.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">daScope</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> fullName = <span class="hljs-string">"Eren Yeager"</span>;
  <span class="hljs-built_in">console</span>.log(fullName); <span class="hljs-comment">// Outputs: Eren Yeager</span>

  <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-keyword">var</span> titan = <span class="hljs-string">"mix veg"</span>;
    <span class="hljs-built_in">console</span>.log(titan); <span class="hljs-comment">// Outputs: mix veg</span>
  }

  <span class="hljs-built_in">console</span>.log(titan); <span class="hljs-comment">// Outputs: mix veg, no error!</span>
}

daScope();
</code></pre>
<p>Think that’s quirky? Check out this scenario:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greetingCreator</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> greeting = <span class="hljs-string">"Hello"</span>;

    <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
        <span class="hljs-keyword">var</span> greeting = <span class="hljs-string">"Hi"</span>;  <span class="hljs-comment">// This redeclares and reassigns `greeting` 🤯  </span>
        <span class="hljs-built_in">console</span>.log(greeting); <span class="hljs-comment">// Output: "Hi"</span>
    }

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

    displayGreeting(); <span class="hljs-comment">// Output: "Hi"</span>
}

greetingCreator();
</code></pre>
<p>Both outputs are "Hi", demonstrating that <code>var</code> does not recognise block scope, but only function scope. The <code>greeting</code> inside the <code>if</code> block affects the same <code>greeting</code> declared at the function's start.</p>
<h3 id="heading-variable-shadowing"><strong>Variable Shadowing</strong></h3>
<p>To avoid the chaos of <code>var</code>, we use <code>let</code>, which enables variable shadowing. Here, if a variable declared in a nested scope has the same name as one in an outer scope, it shadows the outer variable without affecting it.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greetingCreator</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> greeting = <span class="hljs-string">"Hello"</span>;

    <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
        <span class="hljs-keyword">let</span> greeting = <span class="hljs-string">"Hi"</span>; <span class="hljs-comment">// A new, shadowed `greeting`</span>
        <span class="hljs-built_in">console</span>.log(greeting); <span class="hljs-comment">// Output: "Hi"</span>
    }

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

    displayGreeting(); <span class="hljs-comment">// Output: "Hello"</span>
}

greetingCreator();
</code></pre>
<p><strong>Illegal Shadowing</strong></p>
<p>And then there’s illegal shadowing, brought to you by <code>var</code>, of course:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greetingCreator</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> greeting1 = <span class="hljs-string">"Konichiwa"</span>;
    <span class="hljs-keyword">let</span> greeting2 = <span class="hljs-string">"Hello"</span>;

    <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
        <span class="hljs-keyword">let</span> greeting1 = <span class="hljs-string">"Hajime Mashite"</span>; <span class="hljs-comment">// This is fine</span>
        <span class="hljs-built_in">console</span>.log(greeting1); <span class="hljs-comment">// Output: "Hajime Mashite"</span>

        <span class="hljs-keyword">var</span> greeting2 = <span class="hljs-string">"Hi"</span>; <span class="hljs-comment">// Error: Identifier 'greeting2' has already been declared </span>
        <span class="hljs-built_in">console</span>.log(greeting2);  
    }

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

    displayGreeting();  
}

greetingCreator();
</code></pre>
<h3 id="heading-javascript-execution-context">Javascript Execution Context</h3>
<p>JavaScript's execution context is one of the most fundamental concepts to grasp to understand how code executes, particularly how scopes, hoisting, closures, and asynchronous callbacks work. Let's take a detailed look at how JavaScript handles execution context through a step-by-step example.</p>
<p>Consider this JavaScript code snippet:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;
<span class="hljs-keyword">let</span> y = <span class="hljs-number">20</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> z = x * y;
    <span class="hljs-built_in">console</span>.log(z);
    <span class="hljs-keyword">return</span> z;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">display</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> a = <span class="hljs-number">5</span>;
    <span class="hljs-built_in">console</span>.log(a);
    multiply();
}

display();
<span class="hljs-built_in">console</span>.log(x);
</code></pre>
<p>Here’s how JavaScript processes this code:</p>
<p>When the script loads, JavaScript creates a Global Execution Context. This global context performs two main actions during the creation phase:</p>
<ul>
<li><p><strong>Variable Environment Creation</strong>: Here, all the variable and function declarations are hoisted. Variables declared with <code>var</code> are initialised to <code>undefined</code>, and functions are hoisted with their definitions. Variables declared with <code>let</code> and <code>const</code> remain uninitialised at this point and are in a temporal dead zone.</p>
</li>
<li><p><strong>Scope Chain Establishment</strong>: Sets up the scope chain, which determines the variable access throughout the code.</p>
</li>
<li><p><strong>This Value Determination</strong>: For global execution context, <code>this</code> refers to the global object (<code>window</code> in browsers, <code>global</code> in Node.js).</p>
</li>
</ul>
<p>After hoisting, the environment looks something like:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Global Execution Context (GEC) starts</span>

<span class="hljs-comment">// Hoisted during the creation phase of GEC</span>
<span class="hljs-keyword">var</span> x = <span class="hljs-literal">undefined</span>; <span class="hljs-comment">// 'var' variables are initialized as undefined</span>
<span class="hljs-keyword">let</span> y;             <span class="hljs-comment">// 'let' and 'const' are in Temporal Dead Zone (TDZ) and not initialized</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">/* function body is fully hoisted */</span> }
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">display</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">/* function body is fully hoisted */</span> }

<span class="hljs-comment">// Execution phase of GEC begins</span>
x = <span class="hljs-number">10</span>; <span class="hljs-comment">// 'x' is now assigned a value</span>
y = <span class="hljs-number">20</span>; <span class="hljs-comment">// 'y' is assigned a value and comes out of TDZ</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">display</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// New Function Execution Context for display</span>
    <span class="hljs-keyword">let</span> a = <span class="hljs-number">5</span>; <span class="hljs-comment">// Local 'let' declaration, only exists within display</span>
    <span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// Logs 5</span>
    multiply();     <span class="hljs-comment">// Calls multiply, creating a new context for multiply</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// New Function Execution Context for multiply</span>
    <span class="hljs-keyword">var</span> z = x * y;  <span class="hljs-comment">// 'var' declared and calculated using global x and y</span>
    <span class="hljs-built_in">console</span>.log(z); <span class="hljs-comment">// Logs 200</span>
    <span class="hljs-keyword">return</span> z;       <span class="hljs-comment">// Returns 200, multiply context will be popped off the stack after return</span>
}

display();          <span class="hljs-comment">// Calls display, logs 5, then 200 from multiply</span>
<span class="hljs-built_in">console</span>.log(x);     <span class="hljs-comment">// Back in GEC, logs 10</span>

<span class="hljs-comment">// Both multiply and display Function Execution Contexts have been popped off</span>
<span class="hljs-comment">// Back in the GEC until script ends, at which point GEC is also remove</span>
</code></pre>
<ul>
<li><p><strong>Global Execution Context Setup</strong>: At the start, JavaScript engine hoists function declarations and <code>var</code> variables in the global scope.</p>
</li>
<li><p><strong>Function Calls &amp; Scope</strong>: When <code>display</code> and <code>multiply</code> functions are called, they each create their own execution contexts.</p>
<ul>
<li><p><code>display</code> Function Context: Contains its own local variables (e.g., <code>a</code>) and accesses functions and variables from the global scope.</p>
</li>
<li><p><code>multiply</code> Function Context: Accesses global variables (<code>x</code> and <code>y</code>) and has its own local variable (<code>z</code>).</p>
</li>
</ul>
</li>
<li><p><strong>Execution Flow</strong>: After <code>display</code> calls <code>multiply</code>, <code>multiply</code> computes a result and finishes, popping its context off the stack. Then <code>display</code> finishes, returning control to the global context.</p>
</li>
<li><p><strong>End of Execution</strong>: After all function contexts resolve, and the script completes, the global context is finally popped off the execution stack.</p>
</li>
</ul>
<h3 id="heading-hoisting">Hoisting</h3>
<p><strong>Hoisting</strong> is JavaScript's behaviour of moving variable and function declarations to the top of their scope during the compilation phase, before any code is executed. This means that declarations are processed before any line of code runs, giving the illusion that they are "hoisted" to the top.</p>
<p>Imagine you walk into a classroom and see the teacher’s notes already written on the board. You didn’t see her write them, but somehow they were there before the class even started. That’s hoisting in JavaScript — the interpreter sneakily moves declarations to the top of their scope before any code is run.</p>
<p>But there’s a twist.</p>
<p>Hoisting doesn’t actually move your code physically. What it does is register certain declarations, just the declarations, not the initialisations, during the compilation phase, before your code runs. So when execution begins, JavaScript already knows about the existence of variables and functions, it just might not know their values yet.</p>
<p>Let’s break it down.</p>
<h4 id="heading-var-hoisting"><code>var</code> Hoisting</h4>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(hoistedVar); <span class="hljs-comment">// undefined</span>
<span class="hljs-keyword">var</span> hoistedVar = <span class="hljs-number">42</span>;
</code></pre>
<p>You might expect this to throw an error, but nope, it prints <code>undefined</code>. Why? Because <code>var hoistedVar</code> is hoisted to the top like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> hoistedVar;       <span class="hljs-comment">// Declaration is hoisted</span>
<span class="hljs-built_in">console</span>.log(hoistedVar); <span class="hljs-comment">// undefined (default value for hoisted `var`)</span>
hoistedVar = <span class="hljs-number">42</span>;      <span class="hljs-comment">// Initialization stays where it is</span>
</code></pre>
<p>That’s classic <code>var</code> behaviour. Its declarations are hoisted and automatically initialised with <code>undefined</code>.</p>
<h4 id="heading-function-hoisting">Function Hoisting</h4>
<pre><code class="lang-javascript">greet(); <span class="hljs-comment">// "Hello!"</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-string">"Hello!"</span>);
}
</code></pre>
<p>This works beautifully because function declarations are fully hoisted, both the name and the body. Think of it like JavaScript giving your functions a VIP backstage pass. They’re not just invited early, they come fully dressed and ready to perform.</p>
<p>But here's a curveball:</p>
<pre><code class="lang-javascript">greet(); <span class="hljs-comment">// TypeError: greet is not a function</span>

<span class="hljs-keyword">var</span> greet = <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-string">"Hi!"</span>);
};
</code></pre>
<p>Even though <code>greet</code> is declared with <code>var</code>, it’s hoisted as a variable, not as a function. So what gets hoisted?</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> greet;     <span class="hljs-comment">// Only the declaration is hoisted</span>
greet();       <span class="hljs-comment">// greet is undefined at this point → TypeError</span>
greet = <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-string">"Hi!"</span>);
};
</code></pre>
<p>This is why function declarations and function expressions behave differently when it comes to hoisting.</p>
<p>Now enter <code>let</code> and <code>const</code>...</p>
<p>You might think <code>let</code> and <code>const</code> are also hoisted. Technically, they are. But not in the way you'd hope.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// ❌ ReferenceError</span>
<span class="hljs-keyword">let</span> a = <span class="hljs-number">10</span>;
</code></pre>
<p>Even though the <code>let a</code> declaration is hoisted, it's not accessible until the line where it's declared. The period between the start of the scope and the actual declaration is known as the <strong>Temporal Dead Zone (TDZ)</strong>.</p>
<p>Variables in the TDZ cannot be accessed, not even to check if they exist.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
  <span class="hljs-built_in">console</span>.log(name); <span class="hljs-comment">// ❌ ReferenceError</span>
  <span class="hljs-keyword">let</span> name = <span class="hljs-string">"Zoro"</span>;
}
</code></pre>
<p>Try to sneak a peek at <code>name</code> before its declaration, and JavaScript slaps you with:</p>
<p><strong>ReferenceError. But... why?</strong></p>
<p>Well, welcome to the Temporal Dead Zone.</p>
<h3 id="heading-temporal-dead-zone-tdz">Temporal Dead Zone (TDZ)</h3>
<p>Sounds scary, right? Like a place in a sci-fi movie where time and logic cease to exist. And honestly, that’s not far off.</p>
<p>The <strong>Temporal Dead Zone</strong> is the time between a variable being hoisted and being initialised, where accessing it will throw an error.</p>
<p>Here’s the deal:</p>
<ul>
<li><p><code>let</code> and <code>const</code> <strong>are hoisted</strong>, but unlike <code>var</code>, they are <strong>not initialised with</strong> <code>undefined</code>.</p>
</li>
<li><p>Until the line where they are declared is actually executed, they're in the <strong>TDZ,</strong> a forbidden zone.</p>
</li>
<li><p>If you try to access them in that zone, JavaScript throws a <strong>ReferenceError</strong>, basically saying:<br />  <em>“Hold your horses! You can’t use this yet.”</em></p>
</li>
</ul>
<p>Let’s break it down:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHi</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(name); <span class="hljs-comment">// 🚨 ReferenceError</span>
  <span class="hljs-keyword">let</span> name = <span class="hljs-string">"Zoro"</span>;
}
sayHi();
</code></pre>
<p>Why does this error happen?</p>
<p>Even though <code>name</code> is hoisted to the top of the function’s scope, it’s in the <strong>TDZ</strong> from the beginning of the scope until the line <code>let name = "Zoro";</code> is actually run.</p>
<p>Now compare this to <code>var</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sayHi</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(name); <span class="hljs-comment">// undefined</span>
  <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Zoro"</span>;
}
sayHi();
</code></pre>
<p>This time you get <code>undefined</code>, because <code>var</code> is hoisted and initialised with <code>undefined</code>. Not smarter, just sneakier.</p>
<h3 id="heading-the-tdz-is-actually-a-good-thing">The TDZ is Actually a Good Thing</h3>
<p>Yes, I said it. The TDZ is your friend. It exists to <strong>prevent weird bugs</strong> and <strong>enforce better coding practices</strong>. If a variable is in the TDZ, it means:<br /><em>“This thing has not been safely initialised yet, don't touch it.”</em></p>
<p>Without the TDZ, it would be a lot easier to write confusing or broken code. So, while it may feel like JavaScript is being overly strict, it’s actually trying to help you out.</p>
<h3 id="heading-hoisting-interview-questions">Hoisting interview questions</h3>
<h3 id="heading-1-why-doesnt-this-function-run-as-expected">1. <strong>Why doesn’t this function run as expected?</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(foo());
<span class="hljs-keyword">var</span> foo = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">"done"</span>;
};
</code></pre>
<p><strong>Output:</strong><br /><code>TypeError: foo is not a function</code></p>
<p><strong>What’s wrong here?</strong><br />The <code>var foo</code> is hoisted, but its value is set to <code>undefined</code> at the top. So when <code>foo()</code> is called, it's actually calling <code>undefined()</code>.</p>
<p><strong>How to fix it?</strong><br />Use a function declaration instead of a function expression if you need to call the function before it's defined:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">"done"</span>;
}
<span class="hljs-built_in">console</span>.log(foo());
</code></pre>
<p>Or, move the function expression below the <code>console.log</code> if you're using modern patterns like <code>const</code> or <code>let</code>.</p>
<h3 id="heading-2-whats-happening-here-with-let-and-shadowing">2. <strong>What’s happening here with</strong> <code>let</code> and shadowing?</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> a = <span class="hljs-number">10</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(a);
  <span class="hljs-keyword">let</span> a = <span class="hljs-number">20</span>;
}
test();
</code></pre>
<p><strong>Output:</strong><br /><code>ReferenceError</code></p>
<p><strong>What’s wrong here?</strong><br />At first glance, you might think <code>a</code> will be <code>10</code>. But inside the function, <code>let a</code> creates a new <code>a</code> in the block scope, and it’s in the <strong>Temporal Dead Zone</strong> when <code>console.log(a)</code> runs.</p>
<p><strong>How to fix it?</strong><br />If you want to access the outer <code>a</code>, don't redeclare it with <code>let</code> inside the function:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> a = <span class="hljs-number">10</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 10</span>
}
test();
</code></pre>
<p>If you need a new <code>a</code>, define it after you've logged the outer one:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 10</span>
  <span class="hljs-keyword">let</span> aNew = <span class="hljs-number">20</span>;
}
</code></pre>
<h3 id="heading-3-whats-going-on-with-these-var-declarations">3. <strong>What’s going on with these</strong> <code>var</code> declarations?</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> count = <span class="hljs-number">5</span>;

(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-literal">false</span>) {
    <span class="hljs-keyword">var</span> count = <span class="hljs-number">10</span>;
  }
  <span class="hljs-built_in">console</span>.log(count);
})();
</code></pre>
<p><strong>Output:</strong><br /><code>undefined</code></p>
<p><strong>What’s wrong here?</strong><br />You might expect <code>count</code> to be <code>5</code>, but the inner <code>var count</code> is hoisted to the top of the IIFE and initialised as <code>undefined</code>, even though the <code>if</code> block never runs.</p>
<p>So inside the function, <code>count</code> is <code>undefined</code> due to hoisting, not <code>5</code> from the outer scope.</p>
<p><strong>How to fix it?</strong><br />Use <code>let</code> or <code>const</code> to keep block scoping:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> count = <span class="hljs-number">5</span>;

(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-literal">false</span>) {
    <span class="hljs-keyword">let</span> count = <span class="hljs-number">10</span>;
  }
  <span class="hljs-built_in">console</span>.log(count); <span class="hljs-comment">// 5</span>
})();
</code></pre>
<p>Or rename variables to avoid this subtle collision.</p>
<h3 id="heading-4-why-is-this-loop-printing-unexpected-values">4. <strong>Why is this loop printing unexpected values?</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++) {
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(i), <span class="hljs-number">100</span>);
}
</code></pre>
<p><strong>Output:</strong><br /><code>3</code><br /><code>3</code><br /><code>3</code></p>
<p><strong>What’s wrong here?</strong><br />The <code>var i</code> is function-scoped, not block-scoped. So all three callbacks share the same <code>i</code> and print its final value after the loop ends.</p>
<p><strong>How to fix it?</strong></p>
<p>Use <code>let</code> for block scoping:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++) {
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(i), <span class="hljs-number">100</span>);
}
</code></pre>
<p>Or use an IIFE to capture the current <code>i</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++) {
  (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">j</span>) </span>{
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(j), <span class="hljs-number">100</span>);
  })(i);
}
</code></pre>
<h3 id="heading-5-why-does-this-throw-when-you-access-foo-inside-bar">5. <strong>Why does this throw when you access</strong> <code>foo</code> inside <code>bar</code>?</h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"outer foo"</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(foo);
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"inner foo"</span>);
  }
}
bar();
</code></pre>
<p><strong>Output:</strong><br /><code>[Function: foo]</code></p>
<p>Wait... it doesn’t throw?</p>
<p>Actually no, <strong>but here's the twist</strong>, this often catches people off-guard.</p>
<p><strong>What’s really happening?</strong><br />The function <code>foo</code> inside <code>bar</code> is hoisted to the top of <code>bar</code>'s scope. So when <code>console.log(foo)</code> runs, it’s actually logging the function itself, not calling the outer <code>foo</code>.</p>
<p><strong>Follow-up:</strong><br />Change <code>console.log(foo)</code> to <code>foo()</code> what happens?</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) </span>{
  foo(); <span class="hljs-comment">// this calls the inner foo, not the outer one</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"inner foo"</span>);
  }
}
bar();
</code></pre>
<p>The output is <code>"inner foo"</code> because the inner declaration overshadows the outer one.</p>
<p><strong>Fix (if you want the outer one):</strong><br />Rename the inner function or avoid redeclaring functions with the same name.</p>
<h3 id="heading-6-why-does-this-function-behave-differently-based-on-where-its-declared">6. <strong>Why does this function behave differently based on where it’s declared?</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-meta">"use strict"</span>;

<span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">test</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"block"</span>);
  }
}
test();
</code></pre>
<p><strong>Output:</strong><br />In some environments: <code>ReferenceError</code></p>
<p><strong>Why is this tricky?</strong><br />Function declarations inside blocks are a grey area in JavaScript. In strict mode, function declarations are not block-scoped in older engines, and behaviour can vary between browsers.</p>
<p>In modern JavaScript, this should throw a ReferenceError, because <code>test</code> is scoped only inside the <code>if</code> block.</p>
<p><strong>How to fix it?</strong><br />Use function expressions or <code>const</code> if declaring inside a block:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {
  <span class="hljs-keyword">const</span> test = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"block"</span>);
  test();
}
</code></pre>
<p>Or, declare it outside the block if it needs wider visibility.</p>
<h3 id="heading-thats-a-wrap">That’s a Wrap</h3>
<p>I know you are having a blast but the show must end here, I have to feed my pet (virtual pet 🫠). On the bright side you can now tackle any hoisting and scoping related interview questions like a pro. Next time we meet, I’ll let you in on another JavaScript mystery. Spoiler alert: <strong>PROMISES</strong>!</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Object-Oriented Programming in JavaScript]]></title><description><![CDATA[Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design applications and programs. JavaScript, traditionally known for its prototype-based model, has evolved to incorporate class-based object-oriented programming fea...]]></description><link>https://blog.manikagnish.com/understanding-object-oriented-programming-in-javascript</link><guid isPermaLink="true">https://blog.manikagnish.com/understanding-object-oriented-programming-in-javascript</guid><category><![CDATA[OOPS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[fundamentals]]></category><category><![CDATA[classes]]></category><category><![CDATA[ES6]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Fri, 15 Mar 2024 16:53:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710521397147/9e810f19-7b31-4dbb-adde-3bc98e57590f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design applications and programs. JavaScript, traditionally known for its prototype-based model, has evolved to incorporate class-based object-oriented programming features, making it more accessible for developers coming from different programming backgrounds. In this blog, we will explore the core concepts of OOP in JavaScript: Objects, Classes, Abstraction, Encapsulation, Inheritance, and Polymorphism.</p>
<h3 id="heading-understanding-objects"><strong>Understanding Objects</strong></h3>
<p>Objects in JavaScript can be seen as collections of properties and methods. You can think of an object as a box that contains items, where each item has a name (a key) and a value. These values can be data or functions (methods).</p>
<h4 id="heading-creating-objects">Creating Objects</h4>
<ul>
<li><strong>Object Literals:</strong> This is the simplest way to create an object in JavaScript. You simply list its properties and methods inside curly braces <code>{}</code>.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> person = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Kira"</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>,
  <span class="hljs-attr">greet</span>: <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-string">"Hello, my name is "</span> + <span class="hljs-built_in">this</span>.name);
  }
};

person.greet(); <span class="hljs-comment">// Output: Hello, my name is Kira</span>
</code></pre>
<ul>
<li><strong>Constructor Functions:</strong> You can create objects using constructor functions, which are regular functions that are used to create objects with the <code>new</code> keyword. This pattern is similar to class instantiation in other languages.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
  <span class="hljs-built_in">this</span>.greet = <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-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };
}

<span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">'Kira'</span>, <span class="hljs-number">30</span>);
person.greet(); <span class="hljs-comment">// Output: Hello, my name is Kira</span>
</code></pre>
<p>Imagine constructor functions as a blueprint for a building. Every time you want to build a new house (object), you use the same blueprint but can customise the size, color, etc.</p>
<h3 id="heading-classes-modern-blueprint-for-creating-objects"><strong>Classes: Modern Blueprint for Creating Objects</strong></h3>
<p>Introduced in ES6, classes in JavaScript are a syntactic sugar over the prototype-based OO pattern. They provide a clearer and more concise way to create objects and handle inheritance. Classes are to JavaScript what blueprints are to architects, a plan to build objects.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }

  greet() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }
}

<span class="hljs-keyword">const</span> alice = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Kira"</span>, <span class="hljs-number">28</span>);
alice.greet(); <span class="hljs-comment">// Output: Hello, my name is Kira</span>
</code></pre>
<p>Think of a class as a cookie cutter and objects as the cookies made with it. Each cookie (object) will have the same shape (properties) and features (methods), but you can make as many as you want from the same cutter (class).</p>
<h3 id="heading-abstraction-simplifying-complexity"><strong>Abstraction: Simplifying Complexity</strong></h3>
<p>Abstraction is like the dashboard of your car. When you drive, you don't need to understand the complex mechanisms behind the brake system, the engine's inner workings, or how fuel gets injected. You just use the brake pedal, the gas pedal, and the steering wheel. Abstraction in programming hides the complex reality while exposing only the necessary parts.</p>
<p>In JavaScript, while we don't have interfaces or abstract classes like in other languages, we achieve abstraction by limiting access to certain components and exposing only what's necessary through the class's methods.</p>
<p>Let's consider a real-world analogy: a TV remote. You have buttons like power, volume, and channel change. Internally, the remote does a lot of work (sending infrared signals, for example), but you don't need to know that. You just use the buttons.</p>
<p>Translating this to JavaScript, let's imagine we're creating a class for a MusicPlayer. The complexity of how the music is loaded and played is hidden from the user, who interacts with simple methods like <code>play</code>, <code>pause</code>, or <code>skipTrack</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MusicPlayer</span> </span>{
  #currentTrack;
  #playlist;

  <span class="hljs-keyword">constructor</span>(playlist) {
    <span class="hljs-built_in">this</span>.#playlist = playlist;
    <span class="hljs-built_in">this</span>.#currentTrack = <span class="hljs-number">0</span>;
  }

  play() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Playing: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.#playlist[<span class="hljs-built_in">this</span>.#currentTrack].name}</span>`</span>);
    <span class="hljs-comment">// Code to play the music</span>
  }

  pause() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Music paused."</span>);
    <span class="hljs-comment">// Code to pause the music</span>
  }

  skipTrack() {
    <span class="hljs-built_in">this</span>.#currentTrack = (<span class="hljs-built_in">this</span>.#currentTrack + <span class="hljs-number">1</span>) % <span class="hljs-built_in">this</span>.#playlist.length;
    <span class="hljs-built_in">this</span>.play();
  }

  <span class="hljs-comment">// More methods to interact with the music player</span>
}

<span class="hljs-comment">// The user interacts with the MusicPlayer through its public methods,</span>
<span class="hljs-comment">// without needing to understand its internal workings.</span>
<span class="hljs-keyword">const</span> myPlaylist = [{ <span class="hljs-attr">name</span>: <span class="hljs-string">"Song 1"</span> }, { <span class="hljs-attr">name</span>: <span class="hljs-string">"Song 2"</span> }];
<span class="hljs-keyword">const</span> myMusicPlayer = <span class="hljs-keyword">new</span> MusicPlayer(myPlaylist);
myMusicPlayer.play(); <span class="hljs-comment">// Outputs: Playing: Song 1</span>
myMusicPlayer.skipTrack(); <span class="hljs-comment">// Outputs: Playing: Song 2</span>
</code></pre>
<p>In this example, the <code>#currentTrack</code> and <code>#playlist</code> properties are kept private within the <code>MusicPlayer</code> class (with the help of <code>#</code> prefix), preventing external access. This encapsulation is a key aspect of abstraction, where the user of the <code>MusicPlayer</code> does not need to know or understand how tracks are managed or how the play functionality is implemented. They only need to interact with the public methods provided, such as <code>play</code>, <code>pause</code>, and <code>skipTrack</code>.</p>
<p>Through abstraction, we simplify the usage of complex systems, making them more accessible and user-friendly. This concept, while more abstract (pun intended) in JavaScript, is crucial for creating clean, maintainable, and easy-to-use code.</p>
<h3 id="heading-encapsulation-keeping-secrets"><strong>Encapsulation: Keeping Secrets</strong></h3>
<p>Encapsulation in OOP is like owning a house with a garden. You are free to do whatever you want inside your property without letting anyone else know about it. You might have a dog that can freely roam within the fences, but it's not visible or accessible from the outside. In programming, encapsulation means keeping some of the object's properties and methods private, so they can't be accessed from outside the object. This is where JavaScript uses the <code>#</code> prefix to denote private properties or methods.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BankAccount</span> </span>{
  #balance;

  <span class="hljs-keyword">constructor</span>(initialBalance) {
    <span class="hljs-built_in">this</span>.#balance = initialBalance;
  }

  deposit(amount) {
    <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span>) {
      <span class="hljs-built_in">this</span>.#balance += amount;
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Deposit successful"</span>);
    }
  }

  getBalance() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.#balance;
  }
}
</code></pre>
<h3 id="heading-inheritance-standing-on-the-shoulders-of-giants"><strong>Inheritance: Standing on the Shoulders of Giants</strong></h3>
<p>Inheritance allows a class to inherit properties and methods from another class. Imagine you're writing a fantasy novel. You create a general class called <code>Character</code> with properties like <code>name</code>, <code>strength</code>, and <code>magic</code>. Then, you decide to create specific character types like <code>Warrior</code> and <code>Mage</code>. Instead of writing completely new classes from scratch, you let <code>Warrior</code> and <code>Mage</code> inherit the properties and methods from <code>Character</code> and add their unique attributes or methods.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Character</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, strength, magic) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.strength = strength;
    <span class="hljs-built_in">this</span>.magic = magic;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Warrior</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Character</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, strength, magic, weapon) {
    <span class="hljs-built_in">super</span>(name, strength, magic);
    <span class="hljs-built_in">this</span>.weapon = weapon;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Mage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Character</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, strength, magic, spell) {
    <span class="hljs-built_in">super</span>(name, strength, magic);
    <span class="hljs-built_in">this</span>.spell = spell;
  }
}
</code></pre>
<h3 id="heading-polymorphism-many-forms-one-interface"><strong>Polymorphism: Many Forms, One Interface</strong></h3>
<p>Polymorphism allows objects of different classes to be treated as objects of a common superclass. It's like having a universal remote control that can operate your TV, DVD player, and stereo system. Each device has its specifics, but the remote sends commands in a way each device understands. In programming, polymorphism lets us design objects that share certain properties or methods but implement them differently.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Some generic sound"</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Bark"</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Meow"</span>);
  }
}

<span class="hljs-keyword">const</span> myDog = <span class="hljs-keyword">new</span> Dog();
<span class="hljs-keyword">const</span> myCat = <span class="hljs-keyword">new</span> Cat();

<span class="hljs-comment">// Though myDog and myCat are instances of different classes,</span>
<span class="hljs-comment">// we interact with them through the common interface of makeSound().</span>
myDog.makeSound(); <span class="hljs-comment">// Bark</span>
myCat.makeSound(); <span class="hljs-comment">// Meow</span>
</code></pre>
<h3 id="heading-summary">Summary:</h3>
<ul>
<li><p><strong>Objects</strong>: Entities storing data and functionality, akin to containers holding various items, in JavaScript represented by key-value pairs.</p>
</li>
<li><p><strong>Classes</strong>: Blueprint for creating objects with predefined properties and methods, resembling cookie cutters generating cookies of uniform shape and features.</p>
</li>
<li><p><strong>Abstraction</strong>: Hiding complex implementation details and revealing only necessary functionalities, akin to using a TV remote without needing to understand its internal workings.</p>
</li>
<li><p><strong>Encapsulation</strong>: Bundling data and methods within a class while restricting access to certain components, similar to owning a house with a private garden, hidden from external view.</p>
</li>
<li><p><strong>Inheritance</strong>: Mechanism allowing a class to inherit properties and methods from another class, comparable to building on top of existing structures, inheriting their qualities.</p>
</li>
<li><p><strong>Polymorphism</strong>: Ability for objects of different classes to be treated as instances of their parent class, akin to a universal remote control operating various devices, each responding to commands differently.</p>
</li>
</ul>
<p>In summary, JavaScript's approach to OOP allows you to structure your code in a way that is both powerful and flexible, enabling you to build complex applications more efficiently. Through understanding and applying these concepts, you're equipped to dive deeper into the language and explore its capabilities further. Remember, the key to mastering these concepts is practice and real-world application. Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Javascript testing quick start guide]]></title><description><![CDATA[Testing is a crucial aspect of software development, and JavaScript is no exception. As web applications become more complex, testing ensures that our code works as expected, catches bugs early in the development process, and facilitates refactoring ...]]></description><link>https://blog.manikagnish.com/javascript-testing-quick-start-guide</link><guid isPermaLink="true">https://blog.manikagnish.com/javascript-testing-quick-start-guide</guid><category><![CDATA[Testing]]></category><category><![CDATA[vitest]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Wed, 13 Mar 2024 17:41:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710351494079/b91d1d60-499c-4166-a5f3-18d00b73244e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Testing is a crucial aspect of software development, and JavaScript is no exception. As web applications become more complex, testing ensures that our code works as expected, catches bugs early in the development process, and facilitates refactoring and improving code quality.</p>
<h3 id="heading-benefits-of-testing">Benefits of Testing</h3>
<ol>
<li><p><strong>Early Bug Detection</strong>: Testing helps identify bugs and issues early in the development cycle, preventing them from propagating further and causing more significant problems down the line.</p>
</li>
<li><p><strong>Refactoring Facilitation</strong>: When refactoring code, tests provide a safety net, ensuring that the existing functionality remains intact while making changes.</p>
</li>
<li><p><strong>Improved Code Quality</strong>: Writing tests forces developers to consider various edge cases and error conditions, leading to more robust and reliable code.</p>
</li>
<li><p><strong>Documentation</strong>: Tests serve as a form of documentation, illustrating how functions and components should behave, making it easier for new team members or future developers to understand the codebase.</p>
</li>
</ol>
<h3 id="heading-when-to-start-testing">When to Start Testing</h3>
<p>The timing of when to start writing tests is crucial. If a project is still in the early iteration phase with potential breaking changes to requirements, it may not be the best time to invest heavily in testing. However, once the product becomes more stable and the scope for breaking changes decreases, it's an ideal time to start writing tests, especially for critical modules.</p>
<h3 id="heading-types-of-tests">Types of Tests</h3>
<p>There are several types of tests commonly used in JavaScript development:</p>
<ol>
<li><p><strong>Unit Tests</strong>: Unit tests verify the correctness of individual units, such as functions, classes, or small modules, in isolation.</p>
</li>
<li><p><strong>Integration Tests</strong>: Integration tests focus on verifying how different units or components of an application work together as a whole.</p>
</li>
<li><p><strong>End-to-End Tests</strong>: End-to-End (E2E) tests simulate user interactions with the entire system, testing the application from start to finish.</p>
</li>
</ol>
<h3 id="heading-aaa-pattern"><strong>AAA Pattern</strong></h3>
<p>The AAA (Arrange, Act, Assert) pattern is a structured approach to writing unit tests that helps in making them more readable, maintainable, and consistent. Here's what each step involves:</p>
<ol>
<li><p><strong>Arrange</strong>: In this step, you set up the test environment, including any necessary data or configuration required for the test to run. This could involve instantiating objects, defining variables, or setting up mock dependencies.</p>
</li>
<li><p><strong>Act</strong>: This step involves executing the code under test, typically by calling a function or method with the arranged inputs.</p>
</li>
<li><p><strong>Assert</strong>: In the final step, you verify that the actual output or behaviour matches your expected outcome. This is where you use assertion functions like <code>expect</code> from testing libraries to check if the results are correct.</p>
</li>
</ol>
<h3 id="heading-vitest"><strong>Vitest</strong></h3>
<p>Vitest is a popular testing library for JavaScript, and it provides several functions to help you write and organise your tests effectively.</p>
<ul>
<li><p><code>describe(name, fn)</code>: This function is used to group related tests together. The <code>name</code> parameter is a string that describes the group, and the <code>fn</code> parameter is a callback function containing the tests.</p>
</li>
<li><p><code>it(name, fn)</code> or <code>test(name, fn)</code>: These functions are used to define individual test cases. The <code>name</code> parameter is a string that describes the test case, and the <code>fn</code> parameter is a callback function containing the test logic.</p>
</li>
<li><p><code>expect(value)</code>: This function is used to start an assertion. It returns an object that provides various matcher functions to assert different conditions.</p>
</li>
<li><p><code>toBe(value)</code>: This matcher is used to check if the actual value is strictly equal (===) to the expected value.</p>
</li>
<li><p><code>toBeUndefined()</code>: This matcher checks if the actual value is undefined.</p>
</li>
<li><p><code>toBeNull()</code>: This matcher checks if the actual value is null.</p>
</li>
<li><p><code>toBeTruthy()</code>: This matcher checks if the actual value is truthy (evaluates to true).</p>
</li>
<li><p><code>toBeFalsy()</code>: This matcher checks if the actual value is falsy (evaluates to false).</p>
</li>
</ul>
<p>Here's an example that demonstrates the use of these functions:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { sum } <span class="hljs-keyword">from</span> <span class="hljs-string">'./sum'</span>;

describe(<span class="hljs-string">'sum'</span>, <span class="hljs-function">() =&gt;</span> {
  it(<span class="hljs-string">'should add two positive numbers'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Arrange</span>
    <span class="hljs-keyword">const</span> a = <span class="hljs-number">2</span>;
    <span class="hljs-keyword">const</span> b = <span class="hljs-number">3</span>;

    <span class="hljs-comment">// Act</span>
    <span class="hljs-keyword">const</span> result = sum(a, b);

    <span class="hljs-comment">// Assert</span>
    expect(result).toBe(<span class="hljs-number">5</span>);
  });

  it(<span class="hljs-string">'should return 0 if both arguments are 0'</span>, <span class="hljs-function">() =&gt;</span> {
    expect(sum(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>)).toBe(<span class="hljs-number">0</span>);
  });

  it(<span class="hljs-string">'should return the same value if one argument is 0'</span>, <span class="hljs-function">() =&gt;</span> {
    expect(sum(<span class="hljs-number">5</span>, <span class="hljs-number">0</span>)).toBe(<span class="hljs-number">5</span>);
    expect(sum(<span class="hljs-number">0</span>, <span class="hljs-number">7</span>)).toBe(<span class="hljs-number">7</span>);
  });
});
</code></pre>
<h3 id="heading-test-driven-development-tdd">Test-Driven Development (TDD)</h3>
<p>Test-Driven Development (TDD) is an approach where tests are written before the application code. The three steps in TDD are:</p>
<ol>
<li><p>Write a failing test.</p>
</li>
<li><p>Write just enough code to make the test pass.</p>
</li>
<li><p>Refactor the code if necessary, ensuring that the tests still pass.</p>
</li>
</ol>
<p>Let's go through a more real-world example of the TDD process for a simple shopping cart functionality.</p>
<ol>
<li><strong>Write the first failing test</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { ShoppingCart } <span class="hljs-keyword">from</span> <span class="hljs-string">'./ShoppingCart'</span>;

describe(<span class="hljs-string">'ShoppingCart'</span>, <span class="hljs-function">() =&gt;</span> {
  it(<span class="hljs-string">'should initialize with an empty cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();

    expect(cart.items).toEqual([]);
    expect(cart.totalPrice).toBe(<span class="hljs-number">0</span>);
  });
});
</code></pre>
<p>Run the test: It will fail because the <code>ShoppingCart</code> class doesn't exist yet.</p>
<ol start="2">
<li><strong>Write the minimal code to make the test pass</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShoppingCart</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.items = [];
    <span class="hljs-built_in">this</span>.totalPrice = <span class="hljs-number">0</span>;
  }
}
</code></pre>
<p>Run the test: It should now pass.</p>
<ol start="3">
<li><strong>Write another failing test</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { ShoppingCart } <span class="hljs-keyword">from</span> <span class="hljs-string">'./ShoppingCart'</span>;

describe(<span class="hljs-string">'ShoppingCart'</span>, <span class="hljs-function">() =&gt;</span> {
  it(<span class="hljs-string">'should initialize with an empty cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();

    expect(cart.items).toEqual([]);
    expect(cart.totalPrice).toBe(<span class="hljs-number">0</span>);
  });

  it(<span class="hljs-string">'should add an item to the cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();
    <span class="hljs-keyword">const</span> item = { <span class="hljs-attr">name</span>: <span class="hljs-string">'Book'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">10</span> };

    cart.addItem(item);

    expect(cart.items).toContainEqual(item);
    expect(cart.totalPrice).toBe(<span class="hljs-number">10</span>);
  });
});
</code></pre>
<p>Run the tests: The second test should fail because we haven't implemented the <code>addItem</code> method yet.</p>
<ol start="4">
<li><strong>Write the code to make the new test pass</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShoppingCart</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.items = [];
    <span class="hljs-built_in">this</span>.totalPrice = <span class="hljs-number">0</span>;
  }

  addItem(item) {
    <span class="hljs-built_in">this</span>.items.push(item);
    <span class="hljs-built_in">this</span>.totalPrice += item.price;
  }
}
</code></pre>
<p>Run the tests: Both tests should now pass.</p>
<ol start="5">
<li><strong>Write another failing test</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { ShoppingCart } <span class="hljs-keyword">from</span> <span class="hljs-string">'./ShoppingCart'</span>;

describe(<span class="hljs-string">'ShoppingCart'</span>, <span class="hljs-function">() =&gt;</span> {
  it(<span class="hljs-string">'should initialize with an empty cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();

    expect(cart.items).toEqual([]);
    expect(cart.totalPrice).toBe(<span class="hljs-number">0</span>);
  });

  it(<span class="hljs-string">'should add an item to the cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();
    <span class="hljs-keyword">const</span> item = { <span class="hljs-attr">name</span>: <span class="hljs-string">'Book'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">10</span> };

    cart.addItem(item);

    expect(cart.items).toContainEqual(item);
    expect(cart.totalPrice).toBe(<span class="hljs-number">10</span>);
  });

  it(<span class="hljs-string">'should remove an item from the cart'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> cart = <span class="hljs-keyword">new</span> ShoppingCart();
    <span class="hljs-keyword">const</span> item = { <span class="hljs-attr">name</span>: <span class="hljs-string">'Book'</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">10</span> };

    cart.addItem(item);
    cart.removeItem(item);

    expect(cart.items).toEqual([]);
    expect(cart.totalPrice).toBe(<span class="hljs-number">0</span>);
  });
});
</code></pre>
<p>Run the tests: The third test should fail because we haven't implemented the <code>removeItem</code> method yet.</p>
<ol start="6">
<li><strong>Write the code to make the new test pass</strong>:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShoppingCart</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.items = [];
    <span class="hljs-built_in">this</span>.totalPrice = <span class="hljs-number">0</span>;
  }

  addItem(item) {
    <span class="hljs-built_in">this</span>.items.push(item);
    <span class="hljs-built_in">this</span>.totalPrice += item.price;
  }

  removeItem(item) {
    <span class="hljs-keyword">const</span> index = <span class="hljs-built_in">this</span>.items.indexOf(item);
    <span class="hljs-keyword">if</span> (index !== <span class="hljs-number">-1</span>) {
      <span class="hljs-built_in">this</span>.items.splice(index, <span class="hljs-number">1</span>);
      <span class="hljs-built_in">this</span>.totalPrice -= item.price;
    }
  }
}
</code></pre>
<p>Run the tests: All three tests should now pass.</p>
<p>You can continue this cycle by writing tests for additional requirements, such as handling duplicate items, applying discounts, or implementing checkout functionality. The TDD approach ensures that you write testable code from the beginning and that your codebase remains well-covered by tests as it grows in complexity.</p>
<p>Here are a few more examples of tests you could write for the shopping cart:</p>
<ul>
<li><p>Test adding multiple items to the cart and verifying the correct total price</p>
</li>
<li><p>Test removing an item that doesn't exist in the cart (edge case)</p>
</li>
<li><p>Test adding and removing the same item multiple times</p>
</li>
<li><p>Test applying a discount code and verifying the discounted total price</p>
</li>
<li><p>Test checking out the cart and resetting the cart state</p>
</li>
</ul>
<p>By following the TDD approach and continuously writing tests before implementing new features or refactoring existing code, you can ensure that your codebase remains robust, maintainable, and easy to extend or modify in the future.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Testing is an essential practice in JavaScript development, providing numerous benefits such as early bug detection, facilitation of refactoring, improved code quality, and documentation. By understanding when to start testing, the qualities of a good test, and the different types of tests available, developers can write more robust and reliable code. Tools like Vitest and the TDD approach can further enhance the testing process and contribute to a more efficient and high-quality software development lifecycle.</p>
]]></content:encoded></item><item><title><![CDATA[JavaScript's 'this' Keyword Made Simple]]></title><description><![CDATA[Greetings, coding enthusiasts! If you've ever found yourself lost in the jungle of JavaScript, pondering over the enigmatic "this" keyword, you're not alone. In this blog, I'm here to be your guide on this thrilling journey through the world of 'this...]]></description><link>https://blog.manikagnish.com/javascripts-this-keyword-made-simple</link><guid isPermaLink="true">https://blog.manikagnish.com/javascripts-this-keyword-made-simple</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sun, 04 Feb 2024 09:27:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706948358740/2152476d-bfc6-4026-878d-610008f464cf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Greetings, coding enthusiasts! If you've ever found yourself lost in the jungle of JavaScript, pondering over the enigmatic "this" keyword, you're not alone. In this blog, I'm here to be your guide on this thrilling journey through the world of 'this'. I'll use a cafe analogy to make this exploration accessible even to beginners.</p>
<p><strong>Understanding "this" - The Magic Pointer:</strong></p>
<p>The 'this' keyword in JavaScript is like a magic pointer that helps your code understand what it's currently working with. It dynamically represents the specific object or value where a function is being used, allowing you to interact with different parts of your code.</p>
<p>Imagine you're a barista in a cafe, and you have various tasks like brewing coffee or cleaning. 'this' is like a helpful finger pointing to the coffee cup or milk frother, guiding you on what you should focus on at any given moment.</p>
<p>For example, when you're making a latte, 'this' points to the milk frother so you can froth the milk correctly. If you switch to cleaning, 'this' now points to the cleaning cloth, helping you wipe the counter without any confusion. 'this' is your way of saying, 'Look, I'm talking about this particular thing right now.</p>
<p><strong>Now let's discuss different cases where you might encounter 'this':</strong></p>
<p>Imagine you're the manager of a bustling cafe, where different staff members play specific roles. In JavaScript, "this" is akin to assigning roles to various functions and determining who is doing what.</p>
<ol>
<li><p><strong>Cafe Overview (Global Context):</strong></p>
<p> Envision your entire JavaScript program as a bustling cafe. In this lively setting, "this" in the global context is like making announcements to the entire cafe:</p>
<pre><code class="lang-javascript"> <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>); <span class="hljs-comment">// Output: [object Window]</span>
</code></pre>
</li>
<li><p>Roles of the Barista (Functions):</p>
<p> Think of functions as different roles within your cafe. The "this" in a function acts like a barista with a specific job, and their role can change based on the scenario.</p>
<ul>
<li><p><strong>Taking Orders (Regular Function):</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">takeOrder</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>);
  }

  takeOrder(); <span class="hljs-comment">// Output: [object Window]</span>
</code></pre>
<p>  Regular function, "this" still interacts with the entire cafe.</p>
</li>
<li><p>Brewing coffee (Method inside an object):</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> coffeeShop = {
    <span class="hljs-attr">brewCoffee</span>: <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>);
    },
    <span class="hljs-attr">brewLatte</span>: <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>);
    },
  };

  coffeeShop.brewCoffee(); <span class="hljs-comment">// Output: [object Object] (referring to coffeeShop)</span>
  coffeeShop.brewLatte();  <span class="hljs-comment">// Output: [object Window]</span>
</code></pre>
<ul>
<li><p><code>brewCoffee</code> (Regular Function): Just like our regular barista, 'this' within <code>brewCoffee</code> refers to the object (<code>coffeeShop</code>) it is a part of. The output is <code>[object Object]</code>, indicating it's addressing the specific team within the cafe.</p>
</li>
<li><p><code>brewLatte</code> <strong>(Arrow Function):</strong> Arrow functions behave differently. They don't have their own 'this' context and instead inherit it from their enclosing scope. In this case, since 'this' inside <code>brewLatte</code> is in the global context (not within a function or object), it refers to the global object (<code>[object Window]</code> in a browser environment).</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>        So, while <code>brewCoffee</code> addresses the cafe team specifically, <code>brewLatte</code> takes on a freelancing role, addressing the global context. Arrow functions are often used in scenarios where you want to maintain the 'this' value from the surrounding scope.</p>
<ol>
<li><p>New <strong>Employee Orientation (Constructor):</strong></p>
<p> Imagine you need to onboard a new employee for a special role. A constructor, using "this," is like creating a new role within the cafe:</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Employee</span>(<span class="hljs-params">name</span>) </span>{
   <span class="hljs-built_in">this</span>.name = name;
 }

 <span class="hljs-keyword">const</span> newBarista = <span class="hljs-keyword">new</span> Employee(<span class="hljs-string">'Light Yagami'</span>);
 <span class="hljs-built_in">console</span>.log(newBarista.name); <span class="hljs-comment">// Output: Light Yagami</span>
</code></pre>
<p> With "this," you're introducing a new barista, Light Yagami, to play a specific role.</p>
</li>
</ol>
<p>Real-world scenarios - Orders and deliveries:</p>
<p>Now, let's spice things up with a real-world scenario involving orders and deliveries.</p>
<p>T<strong>aking and Fulfilling Orders:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Order</span>(<span class="hljs-params">orderDetails</span>) </span>{
  <span class="hljs-built_in">this</span>.details = orderDetails;
  <span class="hljs-built_in">this</span>.takeOrder = <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-string">`Taking order for <span class="hljs-subst">${<span class="hljs-built_in">this</span>.details}</span>`</span>);
  };
  <span class="hljs-built_in">this</span>.fulfillOrder = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Fulfilling order for <span class="hljs-subst">${<span class="hljs-built_in">this</span>.details}</span>`</span>);
    }, <span class="hljs-number">1000</span>);
  };
}

<span class="hljs-keyword">const</span> customerOrder = <span class="hljs-keyword">new</span> Order(<span class="hljs-string">'Cappuccino'</span>);
customerOrder.takeOrder(); <span class="hljs-comment">// Output: Taking order for Cappuccino</span>
customerOrder.fulfillOrder(); <span class="hljs-comment">// Output: Fulfilling order for Cappuccino</span>
</code></pre>
<p><strong>Event Handling in the Cafe:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> deliveryService = {
  <span class="hljs-attr">handleDelivery</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'deliveryButton'</span>).addEventListener(<span class="hljs-string">'click'</span>, <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-string">`Delivering to <span class="hljs-subst">${deliveryService.address}</span>`</span>);
    });
  },
  <span class="hljs-attr">address</span>: <span class="hljs-string">'123 Cafe Street'</span>,
};

deliveryService.handleDelivery();
</code></pre>
<p>In this example, "this" in the event handler refers to the deliveryService, showcasing how "this" can play a role in real-world scenarios.</p>
<p><strong>Conclusion:</strong></p>
<p>Let's see all the roles of "this" in a concise coding showcase:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Global context</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>); <span class="hljs-comment">// Output: [object Window]</span>

<span class="hljs-comment">// Regular function scene</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">takeOrder</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>); <span class="hljs-comment">// Output: [object Window]</span>
}
takeOrder();

<span class="hljs-comment">// Method scene (Inside an object)</span>
<span class="hljs-keyword">const</span> coffeeShop = {
  <span class="hljs-attr">brewCoffee</span>: <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>); <span class="hljs-comment">// Output: [object Object] (referring to coffeeShop)</span>
  },
  <span class="hljs-attr">brewLatte</span>: <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>); <span class="hljs-comment">// Output: [object Window]</span>
  },
  <span class="hljs-attr">handleEvent</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'orderButton'</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Processing order for <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
    });
  },
};
coffeeShop.brewCoffee();
coffeeShop.brewLatte();  <span class="hljs-comment">// Output: [object Window]</span>

<span class="hljs-comment">// Creating new roles (Constructor)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Employee</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
}

<span class="hljs-keyword">const</span> newBarista = <span class="hljs-keyword">new</span> Employee(<span class="hljs-string">'Light Yagami'</span>);
<span class="hljs-built_in">console</span>.log(newBarista.name); <span class="hljs-comment">// Output: Light Yagami</span>
</code></pre>
<p>There you have it! You've successfully navigated the "this" maze in JavaScript, exploring roles and functions in both coding exercises and real-world examples. Keep coding and managing your roles with confidence! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Demystifying Git Stash: Code Juggling Essentials]]></title><description><![CDATA[In the world of version control, Git is a developer's best friend, and within Git's arsenal lies a somewhat unsung hero – Git stash. If you've ever found yourself in the midst of coding chaos, needing to switch gears quickly without committing half-f...]]></description><link>https://blog.manikagnish.com/demystifying-git-stash-code-juggling-essentials</link><guid isPermaLink="true">https://blog.manikagnish.com/demystifying-git-stash-code-juggling-essentials</guid><category><![CDATA[Git]]></category><category><![CDATA[development]]></category><category><![CDATA[version control]]></category><category><![CDATA[project management]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sun, 31 Dec 2023 09:32:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704012220048/805e9041-ab0d-417b-bf22-157c43d65573.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of version control, Git is a developer's best friend, and within Git's arsenal lies a somewhat unsung hero – Git stash. If you've ever found yourself in the midst of coding chaos, needing to switch gears quickly without committing half-finished work, Git stash is your lifesaver. In this blog, we'll unravel the mysteries of Git stash, exploring its commands, understanding its importance, and showcasing real-world scenarios where it shines.</p>
<h2 id="heading-quick-commands-reference"><strong>Quick Commands Reference:</strong></h2>
<ol>
<li><p><strong>git stash:</strong> Stash your changes.</p>
</li>
<li><p><strong>git stash list:</strong> List all stashes.</p>
</li>
<li><p><strong>git stash show:</strong> Show changes in the most recent stash.</p>
</li>
<li><p><strong>git stash pop:</strong> Apply and remove the most recent stash.</p>
</li>
<li><p><strong>git stash apply:</strong> Apply the most recent stash (keep it in the stash list).</p>
</li>
<li><p><strong>git stash apply stash@{revision}:</strong> Apply a particular stash.</p>
</li>
<li><p><strong>git stash -u:</strong> To stash both tracked and untracked files.</p>
</li>
<li><p><strong>git stash clear:</strong> Delete all stashes.</p>
</li>
<li><p><strong>git stash drop stash@{revision}:</strong> Delete a particular stash.</p>
</li>
<li><p><strong>git stash branch &lt;branch_name&gt;:</strong> Create a new branch from the last stash.</p>
</li>
<li><p><strong>git stash branch &lt;branch_name&gt; stash@{revision}:</strong> Create a branch from a specific stash.</p>
</li>
</ol>
<h2 id="heading-why-git-stash"><strong>Why Git Stash?</strong></h2>
<h3 id="heading-unfinished-work-and-context-switching"><strong>Unfinished Work and Context Switching:</strong></h3>
<p>Imagine you're knee-deep in coding a new feature on the <code>master</code> branch when an urgent bug report comes in. Git stash allows you to stash your ongoing changes, switch to a different branch, fix the bug, and seamlessly return to your feature development.</p>
<h3 id="heading-branch-switching-and-clean-working-directory"><strong>Branch Switching and Clean Working Directory:</strong></h3>
<p>Git stash shines when you need to move between branches swiftly. Instead of committing changes that aren't ready, stash provides a clean slate for branch hopping. It ensures a tidy working directory, making it easier to focus on the task at hand.</p>
<h3 id="heading-emergency-fixes-and-safe-experimentation"><strong>Emergency Fixes and Safe Experimentation:</strong></h3>
<p>Stash becomes your ally in addressing critical issues without compromising your ongoing work. It's also a safety net for experimenting with changes. Stash lets you try out ideas, and if they don't work, you can effortlessly revert to your stashed state.</p>
<h2 id="heading-detailed-exploration-of-commands"><strong>Detailed Exploration of Commands:</strong></h2>
<ol>
<li><p><strong>Stashing Your Changes (git stash):</strong></p>
<p> Use <code>git stash</code> to temporarily store changes without committing.</p>
<pre><code class="lang-bash"> git stash
</code></pre>
</li>
<li><p><strong>Listing All Stashes (git stash list):</strong></p>
<p> See a list of all stashes and their reference numbers.</p>
<pre><code class="lang-bash"> git stash list
</code></pre>
</li>
<li><p><strong>Showing Changes in the Last Stash (git stash show):</strong></p>
<p> Display changes made in the last stash.</p>
<pre><code class="lang-bash"> git stash show
</code></pre>
</li>
<li><p><strong>Applying and Popping the Last Stash (git stash pop):</strong></p>
<p> Apply and remove the last stash.</p>
<pre><code class="lang-bash"> git stash pop
</code></pre>
</li>
<li><p><strong>Applying the Last Stash (git stash apply):</strong></p>
<p> Apply the last stash while keeping it in the stash list.</p>
<pre><code class="lang-bash"> git stash apply
</code></pre>
</li>
<li><p><strong>Applying a Specific Stash (git stash apply stash@{revision}):</strong></p>
<p> Apply a stash by referencing its number (<strong>revision</strong>).</p>
<pre><code class="lang-bash"> git stash apply stash@{3}
</code></pre>
</li>
<li><p><strong>Deleting All Stashes (git stash clear):</strong></p>
<p> Remove all stashes from the stash list.</p>
<pre><code class="lang-bash"> git stash clear
</code></pre>
</li>
<li><p><strong>Stashing untracked files (git stash -u):</strong></p>
<p> If you want to stash both changes to tracked files and untracked files simultaneously, you can use the <code>-u</code> or <code>--include-untracked</code> option with <code>git stash</code>. This option includes untracked files in the stash.</p>
<pre><code class="lang-bash"> git stash -u
</code></pre>
<blockquote>
<p>Note that untracked files stashed in this way won't be listed in the subsequent <code>git stash list</code> output, as they are not changes that can be applied or popped like changes to tracked files.</p>
</blockquote>
</li>
<li><p><strong>Deleting a Specific Stash (git stash drop stash@{revision}):</strong></p>
<p> Discard a specific stash using its reference number.</p>
<pre><code class="lang-bash"> git stash drop stash@{2}
</code></pre>
</li>
<li><p><strong>Creating a New Branch from the Last Stash (git stash branch &lt;branch_name&gt;):</strong></p>
<p>Start a new branch based on the last stash.</p>
<pre><code class="lang-bash">git stash branch &lt;branch_name&gt;
</code></pre>
</li>
<li><p><strong>Creating a Branch from a Specific Stash (git stash branch &lt;branch_name&gt; stash@{revision}):</strong></p>
<p>Begin a branch from a specific stash using its reference.</p>
<pre><code class="lang-bash">git stash branch &lt;branch_name&gt; stash@{revision}
</code></pre>
</li>
</ol>
<h2 id="heading-git-stash-in-action-switching-to-the-right-branch"><strong>Git Stash in Action: Switching to the Right Branch</strong></h2>
<p>Let's say you've mistakenly started coding on the <code>master</code> branch, but your intended changes should be on the existing <code>feature/live-chat</code> branch. Here's how Git stash comes to your rescue:</p>
<ol>
<li><p><strong>Stash Your Changes on Master:</strong></p>
<pre><code class="lang-bash"> git stash
</code></pre>
</li>
<li><p><strong>Switch to the Target Branch:</strong></p>
<pre><code class="lang-bash"> git checkout feature/live-chat
</code></pre>
</li>
<li><p><strong>Apply the Stashed Changes:</strong></p>
<pre><code class="lang-bash"> git stash apply
</code></pre>
<ul>
<li>Alternatively, use <code>git stash pop</code> if you want to drop the stash after applying.</li>
</ul>
</li>
<li><p><strong>Commit on the Correct Branch:</strong></p>
<pre><code class="lang-bash"> git commit -m <span class="hljs-string">"Your commit message"</span>
</code></pre>
</li>
</ol>
<p>By using Git stash, you've seamlessly switched branches, preserved your changes, and committed them to the correct branch. It's a simple yet powerful workflow that keeps your version control history organised.</p>
<h2 id="heading-summary"><strong>Summary:</strong></h2>
<p>Git stash is not just a feature; it's a versatile tool that empowers developers to navigate the complexities of software development with finesse and efficiency. Whether you're juggling multiple tasks, experimenting with changes, or addressing urgent issues, Git stash has got your back. As you integrate these stash commands into your workflow, you'll discover a newfound agility in managing your codebase. Happy stashing!</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to Prompt Engineering]]></title><description><![CDATA[Let’s be real for a second. You’ve probably played around with ChatGPT. You type something, it types something back. Sometimes it’s magic, and sometimes... well, it’s like talking to a brick wall that thinks it’s a poet.
The difference between gettin...]]></description><link>https://blog.manikagnish.com/introduction-to-prompt-engineering</link><guid isPermaLink="true">https://blog.manikagnish.com/introduction-to-prompt-engineering</guid><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[gpt]]></category><category><![CDATA[chatgpt]]></category><category><![CDATA[#PromptEngineering]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sat, 30 Sep 2023 06:01:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695470650016/17e0c2d7-f2d1-4f30-8318-93ba9efa9499.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let’s be real for a second. You’ve probably played around with ChatGPT. You type something, it types something back. Sometimes it’s magic, and sometimes... well, it’s like talking to a brick wall that thinks it’s a poet.</p>
<p>The difference between getting a "meh" answer and a mind-blowing one isn't magic… it’s <strong>Prompt Engineering</strong>.</p>
<p>Before we dive into the hacks, let's make sure we’re speaking the same language. And don't worry, I’m not going to bore you with a lecture.</p>
<h3 id="heading-the-basics-what-are-we-dealing-with">The Basics: What are we dealing with?</h3>
<ul>
<li><p><strong>AI (The Brain):</strong> Think of Artificial Intelligence as a computer trying to mimic a human brain. It solves problems, recognises patterns, and tries to act smart.</p>
</li>
<li><p><strong>LLMs (The Well-Read Librarian):</strong> Large Language Models (LLMs) are a type of AI that have read basically the entire internet. Imagine a librarian who has memorised every book in the library but sometimes forgets which book is non-fiction and which is sci-fi. That's an LLM (like GPT).</p>
</li>
<li><p><strong>Prompting (The Ask):</strong> This is just you texting the AI. The quality of your text (the prompt) determines the quality of its reply. Garbage in, garbage out.</p>
</li>
</ul>
<h3 id="heading-the-big-bang-of-ai-the-transformer">The "Big Bang" of AI: The Transformer</h3>
<p>Okay, here is the cool part that most people skip over. AI used to be pretty dumb at reading. It would read a sentence one word at a time, left to right. By the time it got to the end of a long sentence, it often forgot how the sentence started!</p>
<p>Then, in <strong>2017</strong>, everything changed.</p>
<p>A team of researchers at Google dropped a research paper with the mic-drop title: <strong>"Attention Is All You Need."</strong></p>
<p>They introduced something called the <strong>Transformer</strong> architecture. Instead of reading word-by-word like a slow student, the Transformer looks at the <em>entire</em> sentence at once. It uses a mechanism called <strong>"Self-Attention"</strong> to figure out which words relate to each other, no matter how far apart they are.</p>
<p>For example, in the sentence <em>"The animal didn't cross the street because</em> <strong><em>it</em></strong> <em>was too tired,"</em> an old AI gets confused about what "it" refers to. A Transformer knows instantly that "it" refers to the animal, not the street.</p>
<p>This was a massive breakthrough. It paved the way for every modern AI model we use today (the "T" in GPT literally stands for Transformer!).</p>
<h3 id="heading-so-what-is-prompt-engineering">So, What is Prompt Engineering?</h3>
<p>Prompt engineering is simply the art of whispering into the AI's ear to get exactly what you want. It’s not just asking questions; it’s about setting the stage, giving context, and guiding the AI so it doesn't go off the rails.</p>
<p>Your job as a "Prompt Engineer" is essentially:</p>
<ol>
<li><p><strong>Designing</strong> the perfect question.</p>
</li>
<li><p><strong>Testing</strong> if it works.</p>
</li>
<li><p><strong>Refining</strong> it when the AI gets confused.</p>
</li>
</ol>
<h3 id="heading-how-to-write-good-prompts-best-practices">How to Write Good Prompts (Best Practices)</h3>
<p>You do not need to be a coder to be good at this. You just need to be clear. Think of the AI as a really smart intern who has read every book in the world but has zero common sense. If you are vague, it guesses. If you are specific, it delivers.</p>
<p>Here are the techniques the pros use:</p>
<p><strong>1. Don't be Vague (Clear Instructions)</strong> If you ask, "Write code," the AI will guess. If you ask, "Write a Python script to calculate the fibonacci sequence," you win. Treat the AI like a really smart intern who needs specific instructions to get the job done right.</p>
<p><strong>2. Give it a Role (Persona)</strong> This is my favourite trick. Tell the AI who it is.</p>
<ul>
<li><p><em>Bad:</em> "Explain quantum physics."</p>
</li>
<li><p><em>Good:</em> "You are a wacky high school science teacher. Explain quantum physics using an analogy about donuts."</p>
</li>
</ul>
<p><strong>3. Show, Don't Just Tell (Few-Shot Prompting)</strong> Sometimes instructions aren't enough. Give it examples.</p>
<ul>
<li><p><em>Prompt:</em> "Convert these movie titles into emojis.</p>
<ul>
<li><p>Star Wars -&gt; ⭐️⚔️</p>
</li>
<li><p>The Lion King -&gt; 🦁👑</p>
</li>
<li><p>Titanic -&gt; ?" The AI will immediately understand the pattern and give you "🚢🧊".</p>
</li>
</ul>
</li>
</ul>
<p><strong>4. "Show Your Work" (Chain of Thought)</strong> If you ask a complex logic question, the AI might guess and get it wrong. If you tell it to "think step-by-step," it acts like a student showing their math homework. It forces the model to reason through the problem, which usually leads to the right answer.</p>
<p><strong>5. Emotional Prompting (Yes, really)</strong> Studies have shown that LLMs actually perform better when you add emotional stakes. It sounds weird, but it works.</p>
<ul>
<li><p><em>The Trick:</em> Add phrases like "This is very important for my career" or "You effectively have a tip of $200 for a perfect solution."</p>
</li>
<li><p><em>Why it works:</em> The AI creates a "hyper-focus" state because, in its training data, text surrounded by high urgency usually requires higher quality and precision.</p>
</li>
</ul>
<h3 id="heading-watch-out-for-ai-hallucinations">Watch Out for AI Hallucinations</h3>
<p>Here is the scary part: <strong>AI lies.</strong></p>
<p>Well, it doesn't <em>mean</em> to lie. But remember, LLMs are just predicting the next likely word in a sentence. They aren't fact-checkers. If they don't know the answer, they might confidently make one up. This is called a <strong>Hallucination</strong>.</p>
<ul>
<li><p><strong>Why?</strong> Because it wants to please you by completing the pattern, even if the facts are wrong.</p>
</li>
<li><p><strong>The Fix:</strong> Always verify important facts. Treat the AI as a helper, not the ultimate source of truth.</p>
</li>
</ul>
<h3 id="heading-under-the-hood-how-does-it-actually-understand-embeddings">Under the Hood: How Does It Actually "Understand"? (Embeddings)</h3>
<p>You might be wondering, "How does a computer actually understand the concept of an apple? It is just a machine made of sand and electricity."</p>
<p>It uses something called <strong>Vector Embeddings</strong>, and this is the secret sauce behind modern AI.</p>
<p><strong>1. Turning Words into Numbers</strong> Computers cannot read words; they only do math. So, the first thing an AI does is turn every word (or token) into a list of numbers. But it is not just one number like "Apple = 1". That would be too simple. Instead, "Apple" becomes a long list of numbers, like <code>[0.9, -0.2, 0.5, ...]</code>. In models like GPT, this list can be over 1,500 numbers long!</p>
<p><strong>2. The Giant Map (High-Dimensional Space)</strong> Imagine a graph.</p>
<ul>
<li><p>If you have 2 numbers, you can plot a point on a 2D piece of paper (X and Y axis).</p>
</li>
<li><p>If you have 3 numbers, you can plot a point in a 3D cube (X, Y, and Z).</p>
</li>
<li><p>Now, imagine a space with <strong>1,500 dimensions</strong>. Our human brains cannot visualise it, but computers handle it easily.</p>
</li>
</ul>
<p>Every word in the English language gets a specific coordinate in this massive 1,500-dimensional space.</p>
<p><strong>3. The "Angle" of Meaning (Cosine Similarity)</strong> Here is the magic part. The AI doesn't just look at where the words are; it measures the <strong>angle</strong> between them.</p>
<ul>
<li><p>The concept of "King" and "Queen" are different words, but they point in almost the exact same direction in this space.</p>
</li>
<li><p>"Apple" and "Banana" also point in the same direction (the "Fruit" direction).</p>
</li>
<li><p>"Apple" and "Car" point in completely different directions.</p>
</li>
</ul>
<p>To find out if two things are related, the computer calculates the "Cosine Similarity" (basically, the angle).</p>
<ul>
<li><p>If the angle is small, the concepts are related.</p>
</li>
<li><p>If the angle is wide, they are unrelated.</p>
</li>
</ul>
<p><strong>Why does this matter to you?</strong> This is how <strong>RAG (Retrieval-Augmented Generation)</strong> works. When you chat with a PDF or your company's data, the AI converts your question into numbers, searches its database for paragraphs that have a "similar angle" to your question, and reads only those parts to give you an answer.</p>
<p>It is not magic; it is just really, really high-dimensional geometry.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Prompt engineering isn't about memorising a dictionary of secret codes. It’s about communication. It’s about learning how to guide these powerful new tools to do work for you.</p>
<p>Whether you want to code faster, write better emails, or just have a funny conversation, the skill is in how you ask. So go ahead, open up ChatGPT, and try telling it to "think step-by-step" or "act like a pirate." You might be surprised at what you get back.</p>
]]></content:encoded></item><item><title><![CDATA[Demystifying the Nullish Coalescing Operator in JavaScript]]></title><description><![CDATA[Nullish Coalescing Operator (??) is a relatively new addition to JavaScript, introduced with ES11. In this blog, we'll explore what it is, why it's useful, and how you can leverage it in your JavaScript projects.
Syntax:
const defaultAge = age ?? 18;...]]></description><link>https://blog.manikagnish.com/demystifying-the-nullish-coalescing-operator-in-javascript</link><guid isPermaLink="true">https://blog.manikagnish.com/demystifying-the-nullish-coalescing-operator-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[logical operator]]></category><category><![CDATA[ecmascript]]></category><category><![CDATA[es11]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Mon, 18 Sep 2023 17:34:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695144556221/a8e61424-de9d-4ca2-992d-a7b4c03523cc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Nullish Coalescing Operator (<code>??</code>) is a relatively new addition to JavaScript, introduced with ES11. In this blog, we'll explore what it is, why it's useful, and how you can leverage it in your JavaScript projects.</p>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> defaultAge = age ?? <span class="hljs-number">18</span>;
</code></pre>
<p>In the above code snippet if <code>age</code> is not null or undefined <code>defaultAge</code> will be set to <code>age</code> otherwise it will be set to 18.</p>
<p>Before you start screaming that the logical OR (<code>||</code>) will do the exact same thing, hear me out.</p>
<p><strong>The problem with OR (</strong><code>||</code><strong>):</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> age = <span class="hljs-number">23</span>;
<span class="hljs-keyword">const</span> defaultAge = age || <span class="hljs-number">18</span>;
<span class="hljs-built_in">console</span>.log(defaultAge); <span class="hljs-comment">// Output: 23</span>
</code></pre>
<p>The above code will work perfectly fine in this case as it will return 18 if age is a <code>falsy</code> value and <code>age</code> otherwise. The problem occurs when we are dealing with values that could be legitimate falsy values, such as the number <code>0</code> or an empty string <code>""</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> age = <span class="hljs-number">0</span>;
<span class="hljs-keyword">const</span> defaultAge = age || <span class="hljs-number">18</span>;
<span class="hljs-built_in">console</span>.log(defaultAge); <span class="hljs-comment">// Output: 18</span>
</code></pre>
<p>In this case, the default age is set to 18, even though <code>age</code> has a value of 0, which is a valid age. This unintended behaviour can lead to bugs and unexpected results in your code.</p>
<p><strong>Nullish Coalescing Operator to the rescue 🛟</strong></p>
<p>The Nullish Coalescing Operator (<code>??</code>) provides a solution to the problem mentioned above. It specifically checks for <code>null</code> or <code>undefined</code> values and doesn't treat other <code>falsy</code> values as null or undefined.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> age = <span class="hljs-number">0</span>;
<span class="hljs-keyword">const</span> defaultAge = age ?? <span class="hljs-number">18</span>;
<span class="hljs-built_in">console</span>.log(defaultAge); <span class="hljs-comment">// Output: 0</span>
</code></pre>
<p><strong>Real-world example</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateMetadata</span>(<span class="hljs-params">{ params: { myParams } }</span>) </span>{
  <span class="hljs-keyword">const</span> topic = myParams?.[<span class="hljs-number">0</span>] ?? <span class="hljs-string">"curated"</span>;
  <span class="hljs-keyword">const</span> page = myParams?.[<span class="hljs-number">1</span>] ?? <span class="hljs-string">"1"</span>;

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">title</span>: <span class="hljs-string">`Results for <span class="hljs-subst">${topic}</span> - Page <span class="hljs-subst">${page}</span>`</span>,
  };
}
</code></pre>
<p>The above example shows the setting of metadata using params in a next 13 server-component. The topic will show <code>general</code> only if we don't get data from params i.e. if it is null or undefined. Similarly for the page.</p>
<p><strong>Conclusion</strong></p>
<p>The Nullish coalescing operator is a great tool to resolve the issue of unintentional defaults when dealing with falsy values, ensuring that <code>null</code> and <code>undefined</code> are the only triggers for providing default values. By incorporating this operator into your code, you can write cleaner, more robust JavaScript applications with fewer surprises and bugs. So, the next time you find yourself setting default values, consider using the Nullish Coalescing Operator to make your code safer and more concise.</p>
]]></content:encoded></item><item><title><![CDATA[Array reduce method in JS]]></title><description><![CDATA[In simple words, the array reduce method is used to reduce an array into a single value, after performing some operations on its elements. The value can be a string, number, boolean, object, array, or any other custom data type, depending on how the ...]]></description><link>https://blog.manikagnish.com/array-reduce-method-in-js</link><guid isPermaLink="true">https://blog.manikagnish.com/array-reduce-method-in-js</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array]]></category><category><![CDATA[array methods]]></category><category><![CDATA[interview]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Sun, 30 Jul 2023 13:00:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695144594067/44b67f85-a66a-4d5f-aa57-bd65b7ac47c8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In simple words, the array reduce method is used to reduce an array into a single value, after performing some operations on its elements. The value can be a string, number, boolean, object, array, or any other custom data type, depending on how the callback function is implemented.</p>
<p>Syntax: <code>arr.reduce(callbackFn, initialValue)</code></p>
<p>It accepts two arguments, a callback function and an initial value (which is optional by the way).</p>
<p>The callback function accepts 4 arguments:</p>
<ol>
<li><p><code>accumulator</code>: It keeps track of the intermediate result as the reduce operation progresses. It starts with the value of the <code>initialValue</code> if provided, or the first element of the array if no <code>initialValue</code> is given.</p>
</li>
<li><p><code>currentValue</code>: This is the current element being processed in the array during the iteration.</p>
</li>
<li><p><code>currentIndex</code>: This is the index of the current element being processed. It is an optional property.</p>
</li>
<li><p><code>array</code>: It is the original array upon which the reduce is being called. It is an optional property.</p>
</li>
</ol>
<p>Let's understand the concept of reduce with an example of a sneaker cart. Consider the following dataset for a sneaker cart:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sneakers = [
  {
    <span class="hljs-attr">brand</span>: <span class="hljs-string">"Nike"</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-string">"Running"</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"Black"</span>,
    <span class="hljs-attr">discounted</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">price</span>: <span class="hljs-number">100</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Air Zoom"</span>,
  },
  {
    <span class="hljs-attr">brand</span>: <span class="hljs-string">"Adidas"</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-string">"Casual"</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"White"</span>,
    <span class="hljs-attr">discounted</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">price</span>: <span class="hljs-number">80</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Superstar"</span>,
  },
  {
    <span class="hljs-attr">brand</span>: <span class="hljs-string">"Nike"</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-string">"Basketball"</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"Red"</span>,
    <span class="hljs-attr">discounted</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">price</span>: <span class="hljs-number">120</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"LeBron 18"</span>,
  },
  {
    <span class="hljs-attr">brand</span>: <span class="hljs-string">"Reebok"</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-string">"Training"</span>,
    <span class="hljs-attr">color</span>: <span class="hljs-string">"Blue"</span>,
    <span class="hljs-attr">discounted</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">price</span>: <span class="hljs-number">90</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Nano X"</span>,
  },
];
</code></pre>
<ul>
<li>Say we want to count the number of sneakers per brand:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> brandCounts = sneakers.reduce(<span class="hljs-function">(<span class="hljs-params">counts, sneaker</span>) =&gt;</span> {
  counts[sneaker.brand] = (counts[sneaker.brand] || <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>;
  <span class="hljs-keyword">return</span> counts;
}, {});
<span class="hljs-comment">// OUTPUT: { Nike: 2, Adidas: 1, Reebok: 1 }</span>
</code></pre>
<p>In the above example, <code>counts</code> is our <code>accumulator</code> and <code>sneaker</code> is our <code>currentValue</code>. The initial value for our accumulator is an empty object <code>{}</code>.</p>
<p>Initially, the accumulator (counts) is an empty object, in the first iteration of the loop we add a key of brand name, which we get from <code>sneaker.brand</code>, to the accumulator and check if the key already exists in the object; if it does, then the count is increased by 1. If it doesn't exist, a new property with the brand name is created, and its value is set to 1. This way, the <code>brandCounts</code> object keeps track of how many sneakers are from each brand in the <code>sneakers</code> array.</p>
<p>This operation is performed on every element of the array and each time we return the updated value of our accumulator (<code>return counts;</code>) and we get our final output as <code>{ Nike: 2, Adidas: 1, Reebok: 1 }</code>.</p>
<ul>
<li>Now if we want to get the total price of the cart:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> totalCost = sneakers.reduce(<span class="hljs-function">(<span class="hljs-params">total, sneaker</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> total + sneaker.price;
}, <span class="hljs-number">0</span>);
<span class="hljs-comment">// OUTPUT: 390</span>
</code></pre>
<ul>
<li>What if we want to get a list of the names of all the sneakers in the cart:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sneakerNames = sneakers.reduce(<span class="hljs-function">(<span class="hljs-params">names, sneaker</span>) =&gt;</span> {
  names.push(sneaker.name);
  <span class="hljs-keyword">return</span> names;
}, []);
<span class="hljs-comment">// OUTPUT: ["Air Zoom", "Superstar", "LeBron 18", "Nano X"]</span>
</code></pre>
<p>Now to practice your newly acquired skill try to use the array reduce method to return the list of sneakers that are discounted.</p>
<p>With this, we conclude this article on the <code>array.reduce()</code> method. I hope you now have a better grasp of how to harness its power for performing cumulative operations on arrays. Whether you're calculating totals, counting occurrences, or aggregating data, <code>array.reduce()</code> proves to be an invaluable tool in your programming arsenal. Stay tuned for more informative content, as we'll continue exploring other exciting JavaScript concepts in the next article. Until then, happy coding and keep honing your skills!</p>
]]></content:encoded></item><item><title><![CDATA[Mastering TypeScript Fundamentals]]></title><description><![CDATA[What is typescript?
TypeScript is a programming language that builds upon JavaScript and brings additional features. It introduces static type checking, which means it checks the types of values you're using in your code to catch mistakes early on. A...]]></description><link>https://blog.manikagnish.com/mastering-typescript-fundamentals</link><guid isPermaLink="true">https://blog.manikagnish.com/mastering-typescript-fundamentals</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[app development]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Mon, 12 Jun 2023 12:53:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695471420238/aaf31244-a91d-497f-8ec9-ef5b9fa0e921.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-is-typescript">What is typescript?</h3>
<p>TypeScript is a programming language that builds upon JavaScript and brings additional features. It introduces static type checking, which means it checks the types of values you're using in your code to catch mistakes early on. As you write your code, TypeScript analyzes it in real time, providing feedback and ensuring you use the correct types effectively. It's like having a helpful friend who analyzes your code as you type, making your coding experience easier and more organized.</p>
<h3 id="heading-types-in-typescript">Types in typescript</h3>
<p>TypeScript has a variety of built-in types that you can use to define your variables. Here are some of the most common ones:</p>
<ul>
<li><p><code>number</code>: represents numeric values like 42 or 3.14</p>
</li>
<li><p><code>string</code>: represents text values like "Hello, world!" or "42"</p>
</li>
<li><p><code>boolean</code>: represents boolean values <code>true</code> or <code>false</code></p>
</li>
<li><p><code>null</code> and <code>undefined</code>: represents the absence of a value</p>
</li>
<li><p><code>object</code>: represents any object type, including arrays and functions</p>
</li>
<li><p><code>any</code>: represents any type, and can be used when you don't know the type of a variable ahead of time</p>
</li>
<li><p><code>void</code>: represents the absence of a value, typically used as a return type for functions that don't return anything</p>
</li>
</ul>
<p>In addition to these basic types, TypeScript also supports more advanced types like union types, intersection types, and generics. But more on these later.</p>
<p><strong>Syntax</strong>: <code>let variableName: type = value</code></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> num: <span class="hljs-built_in">number</span> = <span class="hljs-number">67</span>
</code></pre>
<h3 id="heading-type-inference">Type Inference</h3>
<p>Type inference in TypeScript is like having a clever assistant who can automatically guess and figure out the types of values in your code based on how you use them. It saves you from explicitly declaring types every time, making your code more concise and readable. With type inference, TypeScript analyzes your code and infers the types behind the scenes, making programming faster and more intuitive.</p>
<p>eg: <code>let num = 7</code></p>
<p>The type of num will automatically be inferred as a number.</p>
<blockquote>
<p>In case ts is not able to infer the type, it will set it as <code>any</code>.</p>
<p>To prevent the above scenario from happening we can use <code>noImplicitAny</code> in our config file. As <code>any</code> isn't type-checked, we should avoid using it.</p>
</blockquote>
<h3 id="heading-defining-functions">Defining Functions</h3>
<p>Defining parameter types:</p>
<p><code>cont funcName = ( var1: type, var2: type) =&gt; {}</code></p>
<p>Defining return type:</p>
<p><code>cont funcName = (): type =&gt; {}</code></p>
<p>Example: A function taking in the date and returning the number of days from that date</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> getDaysFromDate = (date: <span class="hljs-built_in">Date</span>): <span class="hljs-function"><span class="hljs-params">number</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> today: <span class="hljs-built_in">Date</span> = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
  <span class="hljs-keyword">const</span> timeDifference: <span class="hljs-built_in">number</span> = today.getTime() - date.getTime();
  <span class="hljs-keyword">const</span> daysDifference: <span class="hljs-built_in">number</span> = <span class="hljs-built_in">Math</span>.floor(timeDifference / (<span class="hljs-number">1000</span> * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">24</span>));
  <span class="hljs-keyword">return</span> daysDifference;
}
</code></pre>
<h3 id="heading-type-alias">Type Alias</h3>
<p>A type alias in TypeScript is like giving a nickname to a specific type. It allows you to create a custom name for a type, making your code more expressive and readable. Instead of repeatedly using complex or lengthy type annotations, you can define a type alias once and then use that alias throughout your code.</p>
<p>Eg: you can create a type alias, <code>userD</code>, which you can use anywhere you want to perform any operation on the user.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> UserD = {
    name: <span class="hljs-built_in">string</span>;
    age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">const</span> updateUser = <span class="hljs-function">(<span class="hljs-params">user: UserD</span>) =&gt;</span> {
    <span class="hljs-comment">// some code</span>
}
</code></pre>
<p><strong>Readonly</strong></p>
<p>The <code>readonly</code> modifier in TypeScript is used to indicate that a property of a type can only be read and cannot be modified. It ensures that once a property is assigned a value, it cannot be changed later.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> UserD = {
    <span class="hljs-keyword">readonly</span> _id: <span class="hljs-built_in">string</span>;
    name: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>Typescript will throw an error if we try to change the value of the _id.</p>
<blockquote>
<p>Combining types</p>
<p><code>type A = { name: string }</code></p>
<p><code>type B = A &amp; { isPro: boolean }</code></p>
<p>now B becomes: <code>{ name: string; isPro: boolean }</code></p>
</blockquote>
<h3 id="heading-defining-arrays">Defining Arrays</h3>
<p><strong>type[] and Array&lt;type&gt;</strong></p>
<p>These are functionally equivalent and can be used interchangeably. The choice between them often comes down to personal preference or the existing coding style within a project.</p>
<p><code>const arrName: type[] = []</code></p>
<p><code>const arrName: Array&lt;type&gt; = []</code></p>
<p><strong>Specifying length:</strong></p>
<p>We can specify the length an array is supposed to be, if you try to add or remove values from the array, TypeScript will give you an error because it doesn't match the defined length.</p>
<p><code>const arrName: Array&lt;type, length&gt; = []</code></p>
<p><strong>ReadonlyArray:</strong></p>
<p><code>ReadonlyArray</code> type is a built-in utility type that represents an immutable array. It ensures that the array cannot be modified once it is created, preventing any additions, removals, or modifications to its elements.</p>
<p>The <code>ReadonlyArray</code> type is useful when you want to create arrays that should remain constant and not be modified inadvertently.</p>
<p><code>const arrName: ReadonlyArray&lt;type&gt; = []</code></p>
<p>A good use case of type aliases can be defining a type of userD for an array of users.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> UserD = {
    id: <span class="hljs-built_in">number</span>;
    name: <span class="hljs-built_in">string</span>;
    age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">const</span> users: UserD[] = [
    {id: <span class="hljs-number">1</span>, name: <span class="hljs-string">'Mario'</span>, age: <span class="hljs-number">20</span>},
    {id: <span class="hljs-number">2</span>, name: <span class="hljs-string">'Luigi'</span>, age: <span class="hljs-number">23</span>}
]
</code></pre>
<h3 id="heading-unions">Unions</h3>
<p>A union in TypeScript is like a combination of different types. It allows you to define a type that can be one of several types. For example, you could have a variable that can be either a number or a string. The types are separated by pipe <code>|</code> symbol.</p>
<p><code>type id = number | string</code></p>
<p><code>type arr = (boolean | string)[]</code></p>
<h3 id="heading-tuples">Tuples</h3>
<p>A tuple is an array type that knows exactly how many elements it contains and exactly which types it contains at specific positions.</p>
<p>syntax: <code>type tupleName = [string, number]</code></p>
<p>eg: <code>let arr: [string, boolean];</code></p>
<p>if we define arr like this: <code>arr = [23, false]</code> it will throw an error as type of element on index 0 should be a string, not a number.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Person = [<span class="hljs-built_in">string</span>, <span class="hljs-built_in">number</span>, <span class="hljs-built_in">boolean</span>]

<span class="hljs-keyword">const</span> person: Person = [<span class="hljs-string">"John Doe"</span>, <span class="hljs-number">30</span>, <span class="hljs-literal">true</span>]
</code></pre>
<h3 id="heading-interface">Interface</h3>
<p>The interface is the same as the <code>type alias</code> but with a few additional features:</p>
<ol>
<li><p>It can be re-opened i.e., we can redefine the interface with some additional properties. E.g.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> UserD { 
     name: <span class="hljs-built_in">string</span>;
     age: <span class="hljs-built_in">number</span>;
  }

 <span class="hljs-keyword">interface</span> UserD {
     isPro: <span class="hljs-built_in">boolean</span>;
 }
</code></pre>
<p> Re-opening interface does not override the previous definition. But it adds the new types with the previous ones. So now <code>UserD</code> contains name, age and isPro.</p>
</li>
<li><p>Can extend other interfaces. E.g.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">interface</span> Animal {
   name: <span class="hljs-built_in">string</span>;
   age: <span class="hljs-built_in">number</span>;
   sound(): <span class="hljs-built_in">void</span>;
 }

 <span class="hljs-keyword">interface</span> Dog <span class="hljs-keyword">extends</span> Animal {
   breed: <span class="hljs-built_in">string</span>;
   bark(): <span class="hljs-built_in">void</span>;
 }
</code></pre>
</li>
</ol>
<blockquote>
<p>Be careful while naming interfaces, as you might be re-opening some interface present in a file of some library that you downloaded.</p>
</blockquote>
<h3 id="heading-enum">Enum</h3>
<p>It allows you to define a set of named constants. It helps us define a specific list of options or choices that something can be. For example, if we have a system with three user roles: "Admin", "Moderator", and "User". Instead of using plain strings to represent these roles throughout the code, we can define an enum called "UserRole" with these three members.</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> UserRole {
  Admin = <span class="hljs-string">"ADMIN"</span>,
  Moderator = <span class="hljs-string">"MODERATOR"</span>,
  User = <span class="hljs-string">"USER"</span>
}
</code></pre>
<p>That concludes this blog, you now possess the essential knowledge to seamlessly incorporate TypeScript into your projects. Best of luck on your path to becoming an exceptional software developer, and may your web creations be nothing short of extraordinary!</p>
]]></content:encoded></item><item><title><![CDATA[Instantly improve your web typography skills]]></title><description><![CDATA[Choosing the correct font


The most commonly used typefaces on the web are Serif, Sans-Serif, Script, and monospaced fonts.

Serif:

These fonts are used for established or old-school brands like banks or for fashion magazines and jewellery brands.
...]]></description><link>https://blog.manikagnish.com/instantly-improve-your-web-typography-skills</link><guid isPermaLink="true">https://blog.manikagnish.com/instantly-improve-your-web-typography-skills</guid><category><![CDATA[typography]]></category><category><![CDATA[CSS]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[user experience]]></category><category><![CDATA[Web Design]]></category><dc:creator><![CDATA[Manik Agnish]]></dc:creator><pubDate>Thu, 13 Apr 2023 19:25:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695552056108/0ee6f40e-2137-4acb-aa6a-9946c1fe5c06.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><h3 id="heading-choosing-the-correct-font">Choosing the correct font</h3>
</li>
</ol>
<p>The most commonly used typefaces on the web are Serif, Sans-Serif, Script, and monospaced fonts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075195138/e1ca8bca-9a68-4c41-972b-154e3c3d2941.png" alt class="image--center mx-auto" /></p>
<p><strong>Serif:</strong></p>
<ul>
<li><p>These fonts are used for established or old-school brands like banks or for fashion magazines and jewellery brands.</p>
</li>
<li><p>These fonts convey a traditional and formal vibe.</p>
</li>
<li><p>They can be used for long-form copies, like big paragraphs.</p>
</li>
<li><p>Some popular serif fonts on the web are Bodoni, Garamond, PT serif, and Noto serif.</p>
</li>
</ul>
<p><strong>Sans Serif:</strong></p>
<ul>
<li><p>These are clean, minimal, and modern-looking fonts.</p>
</li>
<li><p>These are the most commonly used fonts on modern websites.</p>
</li>
<li><p>These can be used for long-form copies as they are easy on the eyes of the reader.</p>
</li>
<li><p>Some popular sans-serif fonts:  Inter, Open sans, Space Grotesk, Poppins, and Montserrat</p>
</li>
</ul>
<p><strong>Script:</strong></p>
<ul>
<li><p>These are the fonts that look like they were hand-drawn.</p>
</li>
<li><p>They provide a warm and personal touch.</p>
</li>
<li><p>They are not suitable for a long-form copy.</p>
</li>
<li><p>They are commonly used for logos, headlines, and wedding invitations.</p>
</li>
<li><p>Popular script fonts: pacifico, dancing script</p>
</li>
</ul>
<p><strong>Monospaced:</strong></p>
<ul>
<li><p>These have each character of a word equally spaced so that we can see each individual character clearly at a glance.</p>
</li>
<li><p>The personality of monospaced fonts is often seen as practical, precise, and functional.</p>
</li>
<li><p>Commonly used to show code IDEs.</p>
</li>
<li><p>Can be used to show code snippets on a website.</p>
</li>
<li><p>Popular monospaced fonts: Courier, roboto mono</p>
</li>
</ul>
<ol>
<li><h3 id="heading-tracking-and-leading">Tracking and leading</h3>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075297447/493180b2-8152-4b20-8560-0e3f7e75857f.png" alt class="image--center mx-auto" /></p>
<p><strong>Tracking:</strong></p>
<p>Tracking or Letter-spacing is the process of simultaneously adjusting the overall space between groups of letters.</p>
<ul>
<li><p>Larger type sizes, such as headlines, use tighter letter spacing to improve readability and reduce space between letters.</p>
</li>
<li><p>For smaller type sizes, looser letter spacing can improve readability</p>
</li>
<li><p>Increase letter spacing with uppercase text</p>
</li>
<li><p>Decrease letter spacing when increasing font size &amp; font weight</p>
</li>
</ul>
<p><strong>Leading:</strong></p>
<p>Leading or line spacing is the vertical distance between two lines.</p>
<ul>
<li><p>When text is very small we need to increase line spacing to make it more readable. Lines should not be too tight but they should also not be too big that you can actually notice the white blocks in between lines.</p>
</li>
<li><p>And decrease line spacing for large text sizes</p>
</li>
<li><p>The line height for a paragraph should be around 130 to 150% of the font size. Or you can always use the golden ratio (line height will be = font size * 1.618)</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075302467/0edb971d-3dd0-4049-ac6d-d35951f49ae7.png" alt class="image--center mx-auto" /></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075451351/10333e50-3b22-4234-a04c-c0ab7480550f.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<ol>
<li><h3 id="heading-text-wrapping">Text wrapping</h3>
</li>
</ol>
<p>Try to make each line about 10-11 words or 60 to 80 characters long, for mobile, it becomes 35 to 45 characters. Otherwise, people will have to turn their heads to read the long lines from left to right.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075481903/af508091-aca1-4a8d-b044-0db1d79df303.png" alt class="image--center mx-auto" /></p>
<p>A tick I use to ensure proper text wrapping of each paragraph in my HTML page is using the clamp CSS property and setting the width of the paragraph to 50% of its container with its maximum value to be 75ch (75 characters long) and min width to be 45ch.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075478400/7e73048d-41de-4543-8217-fa252f8a31ae.png" alt class="image--center mx-auto" /></p>
<p><strong>Widow</strong></p>
<p>A widow is a very short line – usually one word, or the end of a hyphenated word – at the end of a paragraph or column. A widow is considered poor typography because it leaves too much white space between paragraphs or at the bottom of a page. This results in poor horizontal alignment at the top of the column or page. So try to avoid it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075491249/34165802-d3a3-4923-b4d7-faa824a1de00.png" alt class="image--center mx-auto" /></p>
<ol>
<li><h3 id="heading-text-alignment">Text Alignment</h3>
</li>
</ol>
<p><strong>Left-aligned:</strong> Left-aligned text is most common for left-to-right languages like English.</p>
<p><strong>Centre-align:</strong> Centred text is best used to distinguish short typographic elements within a layout (such as pull quotes), and is not recommended for long copies.</p>
<p><strong>Right-align:</strong> It is the most common setting for right-to-left languages, such as Arabic.</p>
<ol>
<li><h3 id="heading-limit-the-number-of-fonts-you-use">Limit the number of fonts you use</h3>
</li>
</ol>
<p>Combining typefaces can be very tricky, so to avoid confusion:</p>
<ul>
<li><p>try to reduce the number of typefaces you use in your project and,</p>
</li>
<li><p>select the combinations that are guaranteed to work.</p>
</li>
<li><p>Some font families come with both serif and sans serif typefaces so they are guaranteed to work together. PT and Noto are great examples of this.</p>
</li>
</ul>
<ol>
<li><h3 id="heading-create-a-typographic-scale">Create a typographic scale</h3>
</li>
</ol>
<ul>
<li><p>Make sure you scale up your typography with some rhyme or reason, not some random stuff.</p>
</li>
<li><p>I suggest using the golden ratio as it almost always works.</p>
</li>
<li><p>Golden ratio: Basically, you multiply the font size by 1.618 for every increasing step in your scale.</p>
</li>
<li><p>A useful resource for setting up your type scale is <a target="_blank" href="https://typescale.com">https://typescale.com</a></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1681075495338/c099090c-02d8-43d1-a95c-e9c100149bfa.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<ol>
<li><h3 id="heading-contrast">Contrast</h3>
</li>
</ol>
<p>The most common ways of giving contrast are using font weight, font size, and color.</p>
<ul>
<li><p><strong>Font weight</strong>: We can adjust the weight of the text to make it stand out. Thus the weight of the heading is much higher than that of the paragraph that follows it.</p>
</li>
<li><p><strong>Font size</strong>: When adjusting the size of your typography to improve contrast, it's important to consider hierarchy and proportions and thus Headings and subheadings should be larger than the body text, to make them stand out and guide the reader's eye through the content.</p>
</li>
<li><p><strong>Color</strong>: Adding color to your typography can also help improve contrast. Using a darker color for the text against a lighter background, or vice versa, can create a sharp contrast that makes the text stand out.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>