<?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[Rohit Chornele's blog]]></title><description><![CDATA[This is about the technical articles mostly related to web development.]]></description><link>https://blog.rohitchornele.online</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Apr 2026 12:52:13 GMT</lastBuildDate><atom:link href="https://blog.rohitchornele.online/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Spread vs Rest Operators in JavaScript]]></title><description><![CDATA[The spread and rest operators are powerful features introduced in ES6 that use the same syntax (...) but serve completely different purposes.
Both are written with three dots ... which is exactly why ]]></description><link>https://blog.rohitchornele.online/spread-vs-rest-operators-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/spread-vs-rest-operators-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Spread operator]]></category><category><![CDATA[Rest operator]]></category><category><![CDATA[REST]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 17:51:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/01fbd9ba-fb2f-41db-85e5-d1da50c4856a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The spread and rest operators are powerful features introduced in ES6 that use the same syntax (<code>...</code>) but serve completely different purposes.</p>
<p>Both are written with three dots <code>...</code> which is exactly why they confuse so many people. They look identical. But they do opposite things depending on where and how you use them. One expands values out, the other collects values in. Once you internalize that contrast, the two become very easy to tell apart.</p>
<blockquote>
<p><strong>Spread = Expands values</strong></p>
<p><strong>Rest = Collects values</strong></p>
</blockquote>
<h3><strong>Why These Operators Are Important</strong></h3>
<p>They help:</p>
<ul>
<li><p>Simplify code</p>
</li>
<li><p>Handle data easily</p>
</li>
<li><p>Improve readability</p>
</li>
</ul>
<h2>1. What the Spread Operator Does</h2>
<p>The spread operator takes an array or object and expands it into individual elements out into a new context.</p>
<p>Think of it like unpacking a suitcase: you take everything that was bundled together and lay each item out separately.</p>
<pre><code class="language-javascript">const fruits = ['apple', 'banana', 'mango'];

// spread operator
console.log(...fruits); // apple banana mango
//         ↑ spread unpacks the array into three separate values
</code></pre>
<p>Instead of passing the whole array as one thing, spread breaks it apart and hands over each element individually. This becomes very useful when you need to pass array items as separate arguments to a function.</p>
<pre><code class="language-javascript">const numbers = [4, 1, 7, 2];

console.log(Math.max(...numbers)); // 7
// Math.max doesn't accept an array — it needs individual values
// spread converts [4, 1, 7, 2] into Math.max(4, 1, 7, 2)
</code></pre>
<p>Without spread, you'd have to manually write <code>Math.max(4, 1, 7, 2)</code> or use an older workaround like <code>.apply()</code>. Spread makes this elegant and readable.</p>
<h2>2. What the Rest Operator Does</h2>
<p>The rest operator does the exact opposite, it <strong>collects</strong> multiple individual values and bundles them together into a single array. <strong>If spread is unpacking a suitcase, rest is <em>packing</em> one.</strong></p>
<p>The most common place you'll see rest is in function parameters, where it gathers all the extra arguments passed into a function:</p>
<pre><code class="language-javascript">function sum(...numbers) {
  // `numbers` is now an array of everything passed in
  return numbers.reduce((total, n) =&gt; total + n, 0);
}

sum(1, 2, 3);       // 6
sum(10, 20, 30, 40); // 100
</code></pre>
<p>Here, no matter how many arguments you pass to <code>sum</code>, the rest operator collects all of them into the <code>numbers</code> array. The function doesn't need to know in advance how many values it will receive, rest handles that flexibility for you.</p>
<h2>3. The Difference Between Spread and Rest</h2>
<p>Even though they share the same <code>...</code> syntax, the key to telling them apart is asking: is this expanding values out, or collecting values in?</p>
<p>Spread appears where <strong>values are being used</strong>, in function calls, array literals, or object literals. It takes something bundled and spreads it open. Rest appears where <strong>parameters or variables are being defined</strong>, in function signatures or destructuring. It takes loose individual values and wraps them up.</p>
<p>A side-by-side comparison makes this very clear:</p>
<pre><code class="language-javascript">// SPREAD — expanding an array into a function call
const nums = [1, 2, 3];
console.log(Math.max(...nums)); // spread at the call site

// REST — collecting arguments inside a function definition
function add(...nums) {        // rest in the parameter list
  return nums.reduce((a, b) =&gt; a + b, 0);
}
</code></pre>
<p>Both lines use <code>...nums</code>, but the first is spreading outward and the second is collecting inward. The position call site vs. definition, is what tells you which one it is.</p>
<h2>4. Using Spread with Arrays and Objects</h2>
<p>Spread really shines when working with arrays and objects, particularly for creating copies and combining data without mutating the originals.</p>
<h3><strong>Copying an array</strong> without affecting the original:</h3>
<pre><code class="language-js">const original = [1, 2, 3];
const copy = [...original]; // a fresh, independent array

copy.push(4);
console.log(original); // [1, 2, 3] — untouched
console.log(copy);     // [1, 2, 3, 4]
</code></pre>
<p>This is important because in JavaScript, assigning an array directly (<code>const copy = original</code>) doesn't create a copy — both variables point to the same array. Spread gives you a true, independent copy.</p>
<h3><strong>Merging arrays</strong> is equally clean:</h3>
<pre><code class="language-js">const veggies = ['carrot', 'pea'];
const fruits  = ['apple', 'mango'];

const food = [...veggies, ...fruits, 'rice']; // mix and match freely
// ['carrot', 'pea', 'apple', 'mango', 'rice']
</code></pre>
<p>Spread works just as naturally with <strong>objects</strong>. You can copy or merge objects the same way:</p>
<pre><code class="language-js">const defaults = { theme: 'light', fontSize: 14, language: 'en' };
const userPrefs = { fontSize: 18, language: 'hi' };

// Merge: userPrefs values override defaults where they overlap
const settings = { ...defaults, ...userPrefs };
// { theme: 'light', fontSize: 18, language: 'hi' }
</code></pre>
<p>Notice that <code>fontSize</code> and <code>language</code> from <code>userPrefs</code> overwrite the values from <code>defaults</code>, while <code>theme</code> — which only exists in <code>defaults</code> — is preserved. This pattern of spreading defaults first and then spreading user-provided values on top is extremely common in real codebases.</p>
<h2>5. Practical Use Cases</h2>
<p>Knowing the mechanics is one thing, seeing where these operators actually appear in everyday code is what makes them stick. Adding items to an array without mutating it is a very common need, especially in frameworks like React where you're expected to treat data as immutable:</p>
<pre><code class="language-javascript">const cart = ['shoes', 'shirt'];

// Add an item by creating a new array instead of using push()
const updatedCart = [...cart, 'hat'];
// ['shoes', 'shirt', 'hat'] — cart itself is unchanged
</code></pre>
<p><strong>Passing a dynamic list of arguments</strong> to any function that expects individual values:</p>
<pre><code class="language-javascript">const dates = [2024, 6, 15]; // year, month, day
const birthday = new Date(...dates); // same as new Date(2024, 6, 15)
</code></pre>
<p><strong>Cloning and updating an object in one step</strong>, which you'll see constantly in state management:</p>
<pre><code class="language-javascript">const user = { name: 'Meera', age: 25, city: 'Pune' };

// Update age without mutating the original user object
const updatedUser = { ...user, age: 26 };
// { name: 'Meera', age: 26, city: 'Pune' }
</code></pre>
<p><strong>Building flexible utility functions</strong> using rest, so they can accept any number of arguments:</p>
<pre><code class="language-javascript">function logWithPrefix(prefix, ...messages) { 
    // prefix is one fixed argument, messages collects the rest
    messages.forEach(msg =&gt; console.log([\({prefix}] \){msg})); 
}

logWithPrefix('INFO', 'Server started', 'Listening on port 3000');
// [INFO] Server started
// [INFO] Listening on port 3000
</code></pre>
<p>This kind of function is far more flexible than one that accepts a fixed number of arguments. You can pass two messages or ten, it handles all of them gracefully.</p>
<h2>Conclusion</h2>
<p>Spread and rest are two sides of the same coin. Spread takes a collection and fans it out into individual pieces, useful when you need to pass, copy, or combine data. Rest takes individual pieces and gathers them into a collection, useful when you want a function to handle a variable number of arguments or when you want to capture "the remainder" in a destructuring pattern.</p>
<p>The three dots are the same, but the direction of flow is opposite, and that direction is always determined by context: are you <em>providing</em> values (spread) or <em>receiving</em> them (rest)? Train yourself to ask that question whenever you see <code>...</code>, and the two will never feel confusing again.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding this Keyword in JavaScript]]></title><description><![CDATA[If you've spent any time with JavaScript, you've probably run into this and thought : "okay what is this thing and why does it keep breaking my code?"
You're not alone. this is one of those concepts t]]></description><link>https://blog.rohitchornele.online/understanding-this-keyword-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/understanding-this-keyword-in-javascript</guid><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 17:11:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/9d4e1b4b-8da8-4b0b-afb3-49cd591f85b5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've spent any time with JavaScript, you've probably run into <code>this</code> and thought : "okay what is this thing and why does it keep breaking my code?"</p>
<p>You're not alone. <code>this</code> is one of those concepts that feels confusing at first, but once it clicks, you'll wonder why it ever confused you. Let's fix that today.</p>
<p>In simple words : The keyword <code>this</code> refers to the object that is currently calling the function.</p>
<p><strong>“this = who is calling the function”</strong></p>
<p>Once you understand this idea, most of the confusion disappears.</p>
<h2>1. What Does <code>this</code> Represent?</h2>
<p>The value of <code>this</code> depends on <strong>how a function is called</strong>, not where it is written.</p>
<p><code>this</code> is the object that called the function. That's it. Not where the function was defined, not what the function does, purely who <em>ran</em> it. Every confusing behavior of <code>this</code> traces back to this single idea.</p>
<p><strong>Basic Example :</strong></p>
<pre><code class="language-javascript">function show() {
  console.log(this);
}

show(); // global object
</code></pre>
<p>Think of it like the word "home." If you ask Ravi where home is, he'll say Mumbai. Ask Priya the same question and she'll say Delhi. The word "home" is the same, but what it points to depends entirely on who's asking. <code>this</code> works the same way : it's a pointer whose value depends on the context of the call.</p>
<h2>2. <code>this</code> in the Global Context</h2>
<p>When you write code at the top level : outside any function or object, <code>this</code> points to the <strong>global object</strong>. In a browser, that's <code>window</code>. In Node.js, it's <code>global</code>.</p>
<pre><code class="language-javascript">console.log(this);             // Window { ... } in a browser
console.log(this === window);  // true
</code></pre>
<p>You can think of the global context as JavaScript's default home. When no specific object is making the call, <code>this</code> falls back here automatically.</p>
<p>One thing worth knowing early: in <strong>strict mode</strong> (<code>'use strict'</code>), <code>this</code> inside a regular function becomes <code>undefined</code> instead of pointing to the global object. This is a deliberate safety feature to stop you from accidentally creating or modifying global variables when you didn't intend to. You'll encounter strict mode often in modern JavaScript, so it's good to keep this in the back of your mind.</p>
<h2>3. <code>this</code> Inside Objects</h2>
<p>This is where <code>this</code> stops being abstract and starts being genuinely useful. When a function is a method on an object and you call it through that object, <code>this</code> points to the object itself.</p>
<pre><code class="language-javascript">const person = {
  name: 'Arjun',
  greet: function() {
    // `this` is `person`, because person is the one calling greet()
    console.log('Hello, I am ' + this.name);
  }
};

person.greet(); // Hello, I am Arjun
</code></pre>
<p>Here's a practical trick to always get this right: <strong>look at what's to the left of the dot at the call site.</strong> Whatever object you see there is what <code>this</code> will be inside the function. <code>person.greet()</code>, <code>person</code> is to the left, so <code>this</code> is <code>person</code>.</p>
<h2>4. <code>this</code> Inside Functions</h2>
<p>Here's where most people hit their first real wall with <code>this</code>, so let's walk through it carefully.</p>
<p>If you take a method off an object and call it as a plain, standalone function, it <strong>loses its context</strong>. There's no longer an object to the left of the dot, so <code>this</code> reverts to the global object (or <code>undefined</code> in strict mode).</p>
<p>js</p>
<pre><code class="language-javascript">const person = {
  name: 'Priya',
  greet: function() {
    console.log('Hello, I am ' + this.name);
  }
};

const sayHello = person.greet;  // detached — just a reference to the function

sayHello();  // Hello, I am undefined  ← `this` is now window, not person
</code></pre>
<p>When you assigned <code>person.greet</code> to <code>sayHello</code>, you only copied the function reference, you didn't carry the object along with it. So when <code>sayHello()</code> runs, JavaScript looks for a caller to the left of the dot, finds nothing, and defaults to global. Since <a href="http://window.name"><code>window.name</code></a> doesn't exist in your code, you get <code>undefined</code>.</p>
<h3><code>this</code> inside Arrow Functions :</h3>
<p><strong>Arrow functions</strong> are the clean solution to this. Unlike regular functions, an arrow function doesn't have its own <code>this</code> at all — it simply inherits <code>this</code> from wherever it was <em>written</em> (its surrounding scope). This means it locks in the value of <code>this</code> at definition time, not call time.</p>
<pre><code class="language-javascript">const user = {
  name: 'Kiran',
  sayHi: function() {
    // Arrow function inherits `this` from sayHi(), where `this` is `user`
    setTimeout(() =&gt; {
      console.log('Hi, ' + this.name);  // Hi, Kiran ✓
    }, 500);
  }
};

user.sayHi();
</code></pre>
<p>The arrow function inside <code>setTimeout</code> looks outward to <code>sayHi()</code>'s scope to find <code>this</code>, and since <code>sayHi</code> was called as <code>user.sayHi()</code>, <code>this</code> there is <code>user</code>. Problem solved.</p>
<h2>5. How the Calling Context Changes <code>this</code></h2>
<p>JavaScript gives you three built-in methods : <code>call()</code>, <code>apply()</code>, and <code>bind()</code> , to take manual control of <code>this</code>. Think of them as tools for saying "run this function, but pretend <em>this specific object</em> called it."</p>
<p><code>call()</code> invokes the function immediately with a <code>this</code> you choose:</p>
<pre><code class="language-javascript">function introduce() {
  console.log('Hi, I am ' + this.name);
}

const user1 = { name: 'Ravi' };
const user2 = { name: 'Meera' };

introduce.call(user1);  // Hi, I am Ravi
introduce.call(user2);  // Hi, I am Meera
</code></pre>
<p><code>apply()</code> does exactly the same thing, but you pass any extra arguments as an array rather than individually. Functionally, <code>call</code> and <code>apply</code> are nearly identical, the only difference is that syntax detail.</p>
<p><code>bind()</code> is different in one important way: instead of calling the function immediately, it returns a <em>new</em> function that is permanently locked to the <code>this</code> you specify, no matter how or where it gets called later.</p>
<pre><code class="language-javascript">function introduce() {
  console.log('Hi, I am ' + this.name);
}

const greetAsRavi = introduce.bind({ name: 'Ravi' });

greetAsRavi();          // Hi, I am Ravi — always, no matter what
greetAsRavi.call({ name: 'Someone Else' });  // Still: Hi, I am Ravi
</code></pre>
<p><code>bind()</code> is especially valuable when you're passing a method as a callback, situations where you <em>know</em> the function will lose its context. Instead of relying on arrow functions or workarounds, you can just bind it upfront and trust it'll always have the right <code>this</code>.</p>
<h2>Conclusion</h2>
<p>At its core, <code>this</code> comes down to one question you should ask every time you see it: <em>who is calling this function right now?</em> Follow the dot at the call site, trace the caller, and <code>this</code> almost always makes perfect sense. Global code defaults to the global object, object methods point back to the object, detached functions lose their context, and arrow functions simply inherit <code>this</code> from wherever they were written. When you need full control, <code>call</code>, <code>apply</code>, and <code>bind</code> let you set the caller yourself.</p>
<p>What makes <code>this</code> feel tricky at first is that the same function can behave differently depending on <em>how</em> it's invoked, not how it's written. That flexibility is actually what makes <code>this</code> so powerful, one reusable function can work correctly across many different objects just by calling it the right way.</p>
]]></content:encoded></item><item><title><![CDATA[Map and Set in JavaScript]]></title><description><![CDATA[Map and Set in JavaScript are modern data structures introduced in ES6 to solve common problems developers face when working with objects and arrays.
While objects and arrays are powerful, they have l]]></description><link>https://blog.rohitchornele.online/map-and-set-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/map-and-set-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[map]]></category><category><![CDATA[Sets]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 16:32:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/e305fe52-dc04-40b1-95e7-d98f552cb4bb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Map and Set in JavaScript are modern data structures introduced in ES6 to solve common problems developers face when working with objects and arrays.</p>
<p>While objects and arrays are powerful, they have limitations when it comes to handling key-value pairs and unique data. That’s where <code>Map</code> and <code>Set</code> come in—they provide cleaner, more efficient ways to manage data.</p>
<p>They're not replacements for objects and arrays, they're specialized tools that do certain jobs significantly better.</p>
<p>This article will show you exactly what those jobs are.</p>
<h2>1. What Map Is ?</h2>
<p>A Map is a collection of <strong>key-value pairs</strong>, just like an object.</p>
<p>The critical difference: <strong>Map accepts any value as a key.</strong> Numbers, objects, booleans, even other Maps. Objects only support strings and symbols as keys.</p>
<p><strong>Creating and using a Map:</strong></p>
<pre><code class="language-javascript">let userRoles = new Map();

userRoles.set("priya", "admin");
userRoles.set("rahul", "editor");
userRoles.set("ananya", "viewer");

console.log(userRoles.get("priya"));   // "admin"
console.log(userRoles.has("rahul"));   // true
console.log(userRoles.size);           // 3

userRoles.delete("ananya");
console.log(userRoles.size);           // 2
</code></pre>
<p>Notice the clean API : <code>.set()</code>, <code>.get()</code>, <code>.has()</code>, <code>.delete()</code>, <code>.size</code>. Everything is explicit and purpose-built, unlike objects where you use <code>obj.key</code>, <code>delete obj.key</code>, and <code>Object.keys(obj).length</code>.</p>
<h2>2. What Set Is ?</h2>
<p>A Set is a collection of <strong>unique values</strong>. Add the same value twice, it only appears once. That's the defining characteristic, and it's the whole reason Set exists.</p>
<pre><code class="language-js">let tags = new Set();

tags.add("javascript");
tags.add("frontend");
tags.add("javascript");  // duplicate — silently ignored
tags.add("es6");

console.log(tags.size);  // 3 — not 4
console.log(tags);       // Set { "javascript", "frontend", "es6" }
</code></pre>
<p>No error on duplicates. No fuss. They're just ignored.</p>
<p><strong>Common Set operations:</strong></p>
<pre><code class="language-javascript">let skills = new Set(["html", "css", "javascript", "css", "html"]);

console.log(skills.size);              // 3 — duplicates removed automatically
console.log(skills.has("javascript")); // true
console.log(skills.has("python"));     // false

skills.add("react");
skills.delete("html");

console.log([...skills]);  // ["css", "javascript", "react"]
</code></pre>
<p><strong>The most practical use : removing duplicates from an array:</strong></p>
<pre><code class="language-javascript">let rawTags = ["javascript", "css", "javascript", "react", "css", "html"];

let uniqueTags = [...new Set(rawTags)];

console.log(uniqueTags);
// ["javascript", "css", "react", "html"]
</code></pre>
<p>One line. No loops, no filters, no manual checking. Create a Set (duplicates removed automatically), spread it back into an array.</p>
<p><strong>Iterating a Set:</strong></p>
<pre><code class="language-javascript">let categories = new Set(["books", "electronics", "clothing"]);

for (let category of categories) {
  console.log(category);
}
// books
// electronics
// clothing
</code></pre>
<h2>3. Map vs Object</h2>
<p>Both store key-value pairs. Here's where they diverge in ways that actually matter:</p>
<p><strong>Key types:</strong></p>
<pre><code class="language-javascript">// Object — keys are always strings (or symbols)
let obj = {};
obj[1] = "one";
obj[true] = "yes";

console.log(Object.keys(obj));  // ["1", "true"] — converted to strings

// Map — keys keep their actual type
let map = new Map();
map.set(1, "one");
map.set(true, "yes");

console.log([...map.keys()]);  // [1, true] — kept as number and boolean
</code></pre>
<p><strong>Size:</strong></p>
<pre><code class="language-javascript">let obj = { a: 1, b: 2, c: 3 };
let map = new Map([["a", 1], ["b", 2], ["c", 3]]);

// Object — no built-in size
console.log(Object.keys(obj).length);  // 3 — manual calculation

// Map — built-in
console.log(map.size);  // 3 — direct property
</code></pre>
<p><strong>Iteration:</strong></p>
<pre><code class="language-javascript">// Object — needs Object.entries(), not directly iterable
for (let [key, value] of Object.entries(obj)) {
  console.log(key, value);
}

// Map — directly iterable
for (let [key, value] of map) {
  console.log(key, value);
}
</code></pre>
<p><strong>Prototype pollution risk:</strong></p>
<p>Plain objects inherit from <code>Object.prototype</code>. This means they come with built-in properties like <code>toString</code>, <code>hasOwnProperty</code>, and <code>constructor</code>. These can cause subtle bugs if you're not careful with key names:</p>
<pre><code class="language-javascript">let permissions = {};
permissions["admin"] = true;
permissions["toString"] = true;  // shadows Object.prototype.toString

// Now toString is broken on this object
console.log(permissions.toString());  // "true" — not the function anymore
</code></pre>
<p>Map has no such issue. It has no inherited prototype properties that could conflict with your data.</p>
<h3><strong>Side-by-side comparison:</strong></h3>
<table>
<thead>
<tr>
<th></th>
<th>Object</th>
<th>Map</th>
</tr>
</thead>
<tbody><tr>
<td>Key types</td>
<td>Strings / Symbols only</td>
<td>Any value</td>
</tr>
<tr>
<td>Size</td>
<td>Manual (<code>Object.keys().length</code>)</td>
<td><code>.size</code> property</td>
</tr>
<tr>
<td>Iteration</td>
<td>Via <code>Object.entries()</code></td>
<td>Directly iterable</td>
</tr>
<tr>
<td>Insertion order</td>
<td>Not guaranteed (older JS)</td>
<td>Always preserved</td>
</tr>
<tr>
<td>Prototype risk</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Best for</td>
<td>Structured records, config</td>
<td>Dynamic key-value storage</td>
</tr>
</tbody></table>
<h2>4. Set vs Array</h2>
<p>Both hold collections of values. The difference is purpose, arrays are ordered lists that allow duplicates; Sets are collections that guarantee uniqueness.</p>
<p><strong>Duplicate behavior:</strong></p>
<pre><code class="language-javascript">let arr = [1, 2, 2, 3, 3, 3];
console.log(arr.length);  // 6 — keeps duplicates

let set = new Set([1, 2, 2, 3, 3, 3]);
console.log(set.size);    // 3 — removes duplicates
</code></pre>
<p><strong>Membership checking:</strong></p>
<pre><code class="language-javascript">let arr = ["apple", "banana", "mango"];
let set = new Set(["apple", "banana", "mango"]);

// Array — scans the whole array O(n)
console.log(arr.includes("mango"));  // true

// Set — direct lookup O(1)
console.log(set.has("mango"));       // true
</code></pre>
<p>For large collections, this performance difference is significant. If you're frequently checking whether a value exists, Set is dramatically faster than an array.</p>
<p><strong>What arrays can do that Set can't:</strong></p>
<pre><code class="language-javascript">let arr = [1, 2, 3, 4, 5];

// Index access
console.log(arr[2]);  // 3

// map, filter, reduce
let doubled = arr.map(x =&gt; x * 2);

// Duplicates (when you want them)
let repeated = [1, 1, 2, 2, 3];
</code></pre>
<p>Sets don't support index access <code>set[0]</code> gives you <code>undefined</code>. They also don't have <code>map</code>, <code>filter</code>, or <code>reduce</code> directly. For those operations, convert to an array first:</p>
<pre><code class="language-javascript">let set = new Set([1, 2, 3, 4, 5]);
let doubled = [...set].map(x =&gt; x * 2);
// [2, 4, 6, 8, 10]
</code></pre>
<h3><strong>Side-by-side comparison:</strong></h3>
<table>
<thead>
<tr>
<th></th>
<th>Array</th>
<th>Set</th>
</tr>
</thead>
<tbody><tr>
<td>Duplicates</td>
<td>Allowed</td>
<td>Not allowed</td>
</tr>
<tr>
<td>Index access</td>
<td>Yes (<code>arr[0]</code>)</td>
<td>No</td>
</tr>
<tr>
<td>Has <code>.map/.filter</code></td>
<td>Yes</td>
<td>No (convert first)</td>
</tr>
<tr>
<td>Membership check</td>
<td><code>includes()</code> — O(n)</td>
<td><code>has()</code> — O(1)</td>
</tr>
<tr>
<td>Order preserved</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Best for</td>
<td>Ordered lists, transformations</td>
<td>Unique collections, lookup</td>
</tr>
</tbody></table>
<h2>5. When to Use Map and Set</h2>
<p>The clearest signal for reaching for Map or Set is when you find yourself working around a limitation of plain objects or arrays. Use Map when: You need non-string keys, especially when you want to associate data with DOM elements or objects:</p>
<pre><code class="language-javascript">let elementData = new Map();

let button = document.getElementById("submit");
let input  = document.getElementById("email");

elementData.set(button, { clickCount: 0, lastClicked: null });
elementData.set(input,  { errorCount: 0, lastError: null });
</code></pre>
<p>You need to know the size directly, or iterate keys and values frequently:</p>
<pre><code class="language-javascript">let config = new Map([
  ["theme", "dark"],
  ["language", "en"],
  ["timezone", "IST"]
]);

console.log(`${config.size} settings loaded`);

for (let [key, value] of config) {
  applyConfig(key, value);
}
</code></pre>
<p>The data is highly dynamic, keys being added and removed frequently:</p>
<pre><code class="language-javascript">let activeSessions = new Map();

function login(userId, token) {
  activeSessions.set(userId, { token, loginTime: Date.now() });
}

function logout(userId) {
  activeSessions.delete(userId);
}

function isActive(userId) {
  return activeSessions.has(userId);
}
</code></pre>
<p><strong>Use Set when:</strong></p>
<p>You're collecting values and don't want duplicates:</p>
<pre><code class="language-javascript">// Collecting unique error codes from multiple API calls
let errorCodes = new Set();

responses.forEach(response =&gt; {
  if (response.error) errorCodes.add(response.error.code);
});

console.log([...errorCodes]);  // only unique error codes
</code></pre>
<p>You need fast membership checking over a large list:</p>
<pre><code class="language-javascript">// Blocklist lookup — Set is much faster than array for this
let blockedUsers = new Set(["user_42", "user_99", "user_187"]);

function canPost(userId) {
  return !blockedUsers.has(userId);
}
</code></pre>
<p>You want to find the union, intersection, or difference of two collections:</p>
<pre><code class="language-js">let setA = new Set([1, 2, 3, 4]);
let setB = new Set([3, 4, 5, 6]);

// Union — all values from both
let union = new Set([...setA, ...setB]);
// Set { 1, 2, 3, 4, 5, 6 }

// Intersection — only values in both
let intersection = new Set([...setA].filter(x =&gt; setB.has(x)));
// Set { 3, 4 }

// Difference — values in A but not B
let difference = new Set([...setA].filter(x =&gt; !setB.has(x)));
// Set { 1, 2 }
</code></pre>
<p>These patterns come up in real features, finding common friends, shared tags, users who belong to one group but not another.</p>
<h2>Conclusion</h2>
<p>Map and Set aren't replacements for objects and arrays. They're specialized tools that solve specific problems cleanly.</p>
<p>Reach for <strong>Map</strong> when your keys aren't strings, when you need reliable size and iteration, or when data is dynamic enough that an object's prototype quirks could be a problem.</p>
<p>Reach for <strong>Set</strong> when uniqueness matters, when you need fast membership checking, or when you want to perform set operations like union and intersection cleanly.</p>
]]></content:encoded></item><item><title><![CDATA[Destructuring in JavaScript]]></title><description><![CDATA[Destructuring in JavaScript is a powerful feature that allows you to extract values from arrays and objects quickly and easily. Instead of writing repetitive code to access individual values, destruct]]></description><link>https://blog.rohitchornele.online/destructuring-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/destructuring-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Destructuring]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 15:40:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/9b4bdecb-3c7e-4c39-9192-b6b73c6a745b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Destructuring in JavaScript is a powerful feature that allows you to extract values from arrays and objects quickly and easily. Instead of writing repetitive code to access individual values, destructuring lets you unpack them in a clean and readable way.</p>
<p>Imagine you receive a packed box with several items inside. Without destructuring, you'd reach in and pull out each item one by one, labeling each as you go:</p>
<pre><code class="language-javascript">let box = ["laptop", "charger", "mouse"];

let item1 = box[0];
let item2 = box[1];
let item3 = box[2];
</code></pre>
<p>It works. But it's repetitive — you're writing <code>box[0]</code>, <code>box[1]</code>, <code>box[2]</code> for every single item. Now imagine doing that for an object with ten properties.</p>
<p>Destructuring is JavaScript's way of letting you unpack values from arrays or objects into named variables — in one clean, expressive line.</p>
<pre><code class="language-javascript">let [laptop, charger, mouse] = box;
</code></pre>
<p>Same result. One line. No index juggling.</p>
<h2>1. What Destructuring Means</h2>
<p>Destructuring is a syntax feature introduced in ES6. It lets you extract values from arrays or properties from objects, and assign them to variables, all in a single statement.</p>
<p>The word itself is descriptive, you're breaking a structure apart into its individual pieces.</p>
<p>Two important things to understand before diving in:</p>
<p><strong>Destructuring doesn't modify the original.</strong> The array or object you're destructuring stays completely intact. You're just creating new variables that hold copies of the values.</p>
<p><strong>The syntax mirrors the structure.</strong> For arrays, you use <code>[ ]</code>. For objects, you use <code>{ }</code>. The shape of the destructuring expression matches the shape of the data.</p>
<h2>2. Destructuring Arrays</h2>
<p>Array destructuring assigns values based on position. The first variable gets the first element, the second variable gets the second, and so on.</p>
<p>Example :</p>
<pre><code class="language-javascript">let colors = ["red", "green", "blue"];

// Without destructuring
let first = colors[0];
let second = colors[1];
let third = colors[2];

// With destructuring
let [first, second, third] = colors;

console.log(first);   // "red"
console.log(second);  // "green"
console.log(third);   // "blue"
</code></pre>
<p><strong>Skipping Elements</strong></p>
<p>You don't have to extract everything. Leave a blank slot with a comma to skip an element :</p>
<pre><code class="language-javascript">let [,, blue] = colors;
console.log(blue);  // "blue" — skipped red and green
</code></pre>
<p><strong>Rest Elements</strong></p>
<p>Collect remaining elements into a new array using <code>...</code> :</p>
<pre><code class="language-javascript">let scores = [95, 87, 76, 65, 54];

let [top, second, ...rest] = scores;

console.log(top);     // 95
console.log(second);  // 87
console.log(rest);    // [76, 65, 54]
</code></pre>
<p><strong>Swapping Variables</strong></p>
<p>One of the neatest tricks destructuring enables is swapping two variables without a temporary:</p>
<pre><code class="language-javascript">let a = 1;
let b = 2;

[a, b] = [b, a];

console.log(a);  // 2
console.log(b);  // 1
</code></pre>
<p>Before ES6, you need a temp variable to do this. Now it's one line.</p>
<h2>3. Destructuring Objects</h2>
<p>Object destructuring assigns values based on <strong>property names</strong>, not position. The variable name must match the property name in the object.</p>
<pre><code class="language-javascript">let user = {
  name: "Priya",
  age: 24,
  city: "Pune"
};

// Without destructuring
let name = user.name;
let age = user.age;
let city = user.city;

// With destructuring
let { name, age, city } = user;

console.log(name);  // "Priya"
console.log(age);   // 24
console.log(city);  // "Pune"
</code></pre>
<p>The repetition of <a href="http://user.name"><code>user.name</code></a>, <code>user.age</code>, <a href="http://user.city"><code>user.city</code></a> disappears entirely.</p>
<p><strong>Renaming Variables</strong></p>
<p>If you want a different variable name than the property name, use a colon:</p>
<pre><code class="language-javascript">let { name: userName, city: location } = user;

console.log(userName);  // "Priya"
console.log(location);  // "Pune"
</code></pre>
<p>This is useful when a property name conflicts with an existing variable, or when the property name isn't descriptive enough in context.</p>
<p><strong>Nested Objects</strong></p>
<p>You can destructure nested objects in one expression:</p>
<pre><code class="language-javascript">let order = {
  id: "ORD-421",
  product: {
    name: "Keyboard",
    price: 1299
  }
};

let { id, product: { name: productName, price } } = order;

console.log(id);           // "ORD-421"
console.log(productName);  // "Keyboard"
console.log(price);        // 1299
</code></pre>
<p>For deeply nested structures, though, keep readability in mind. One or two levels is usually fine. Beyond that, pull values out in separate steps.</p>
<h2>4. Default Values</h2>
<p>When you destructure a value that doesn't exist in the source, you get undefined. Default values let you specify a fallback instead:</p>
<pre><code class="language-javascript">let settings = { theme: "dark" };

let { theme, fontSize = 16, language = "en" } = settings;

console.log(theme);     // "dark"    — existed in object
console.log(fontSize);  // 16        — used default, not in object
console.log(language);  // "en"      — used default, not in object
</code></pre>
<p>This works for arrays too:</p>
<pre><code class="language-javascript">let [x = 0, y = 0, z = 0] = [10, 20];

console.log(x);  // 10
console.log(y);  // 20
console.log(z);  // 0  — used default
</code></pre>
<p>Defaults only kick in when the value is <code>undefined</code>. If the value is <code>null</code>, <code>false</code>, or <code>0</code>, the default is <em>not</em> used.</p>
<pre><code class="language-javascript">let { score = 100 } = { score: null };
console.log(score);  // null — not 100. null is not undefined.
</code></pre>
<p>This is a subtle but important distinction, especially when working with API responses where <code>null</code> and <code>undefined</code> mean different things.</p>
<p><strong>Defaults in Function Parameters</strong></p>
<p>Combining destructuring with defaults in function signatures is a powerful pattern for writing flexible, self-documenting functions:</p>
<pre><code class="language-javascript">function createButton({ label = "Click me", color = "blue", size = "medium" } = {}) {
  return `&lt;button class="\({color} \){size}"&gt;${label}&lt;/button&gt;`;
}

createButton({ label: "Submit", color: "green" });
// &lt;button class="green medium"&gt;Submit&lt;/button&gt;

createButton();
// &lt;button class="blue medium"&gt;Click me&lt;/button&gt;  — all defaults used
</code></pre>
<p>The <code>= {}</code> at the end means the function works even if called with no argument at all, the parameter defaults to an empty object, and each property defaults individually.</p>
<h2>5. Benefits of Destructuring</h2>
<p>The concrete improvements destructuring brings to everyday code:</p>
<p><strong>Less repetition.</strong> <a href="http://user.name"><code>user.name</code></a>, <a href="http://user.email"><code>user.email</code></a>, <code>user.role</code> written five times throughout a function becomes three clean variables extracted once at the top. The body of the function reads clearly without the constant <code>user.</code> prefix noise.</p>
<p><strong>Clearer function signatures.</strong> A function that accepts <code>{ name, age, city }</code> tells you exactly what it needs. A function that accepts <code>userData</code> tells you nothing, you have to read the body to find out.</p>
<p><strong>Cleaner API response handling.</strong> API responses are almost always objects. Destructuring them at the point of use keeps the rest of your logic clean.</p>
<p><strong>Works naturally with array methods.</strong> When you map over an array of objects, destructuring in the callback parameter keeps things concise.</p>
<p><strong>Import statements.</strong> Every time you write a named import in JavaScript, you're using destructuring syntax.</p>
<p>The module exports an object. You're destructuring exactly the pieces you need from it.</p>
<h2>Conclusion</h2>
<p>Destructuring is one of those features that feels like a small convenience until you use it consistently and then going back to the old way feels genuinely uncomfortable.</p>
<p>The rule of thumb: any time you find yourself writing <a href="http://something.property"><code>something.property</code></a> more than twice in a short block of code, consider destructuring it at the top. Any time a function receives an object and uses three or more of its properties, destructure in the parameters.</p>
<p>It won't change what your code <em>does</em>. It will change how easily it <em>reads</em> and readable code is code that's easier to debug, easier to review, and easier to hand off to someone else.</p>
]]></content:encoded></item><item><title><![CDATA[JavaScript Promises Explained for Beginners]]></title><description><![CDATA[A Promise is an object that represents a value you don't have yet — but will have at some point in the future. Instead of blocking your code waiting for that value, JavaScript hands you the Promise im]]></description><link>https://blog.rohitchornele.online/javascript-promises-explained-for-beginners</link><guid isPermaLink="true">https://blog.rohitchornele.online/javascript-promises-explained-for-beginners</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[promises]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 11:13:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/fba452dc-4f64-4800-9a67-cdda594eb6d9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A Promise is an object that represents a value you don't have <em>yet</em> — but will have at some point in the future. Instead of blocking your code waiting for that value, JavaScript hands you the Promise immediately and lets you describe what to do when it resolves.</p>
<p>This makes it easier to handle tasks like API calls, file operations, and timers.</p>
<p>Before Promises existed, JavaScript developers handled async operations with callbacks. Promises didn't just offer a cleaner syntax, they solved real structural problems that callbacks couldn't.</p>
<h2><strong>1. Why Promises Were Introduced</strong></h2>
<p>Before promises:</p>
<ul>
<li><p>Code became messy with nested callbacks</p>
</li>
<li><p>Error handling was difficult</p>
</li>
<li><p>Readability suffered</p>
</li>
</ul>
<p>Let's understand with an example :</p>
<pre><code class="language-javascript">getUser(userId, function(err, user) {
  if (err) return console.error(err);

  getOrders(user.id, function(err, orders) {
    if (err) return console.error(err);

    getOrderDetails(orders[0].id, function(err, details) {
      if (err) return console.error(err);

      console.log("Details:", details);
    });
  });
});
</code></pre>
<p>In above operation, therer are three operations. Already three levels of nesting. Each level has its own error check. Adding one more step means another level of indentation. This is the pyramid of doom.</p>
<p>It has three specific problems Promises are designed to fix:</p>
<p><strong>Error handling is repetitive :</strong> Every single callback needs its own <code>if (err)</code> check. Miss one and errors silently disappear.</p>
<p><strong>Flow is hard to follow :</strong> Logic flows diagonally, not top to bottom. Reading this requires tracking indentation levels instead of reading normally.</p>
<p><strong>Reusability is poor :</strong> These nested callbacks are tightly coupled. Pulling one piece out to reuse it elsewhere is painful.</p>
<p>Now here's the same logic with Promises:</p>
<pre><code class="language-javascript">getUser(userId)
  .then(user =&gt; getOrders(user.id))
  .then(orders =&gt; getOrderDetails(orders[0].id))
  .then(details =&gt; console.log("Details:", details))
  .catch(err =&gt; console.error(err));
</code></pre>
<p>One error handler at the end covers everything. The flow reads top to bottom. Each step is one clean line. This is the core promise of Promises, flattening the pyramid into a readable chain.</p>
<h2>2. Promise States</h2>
<p>Every Promise exists in exactly one of the three states at any moment. Understanding these states is understanding how Promises work.</p>
<p><strong>Pending</strong> : the initial state. The operation has started but hasn't finished. Like your package that's been shipped but not delivered.</p>
<p><strong>Fulfilled</strong> : the operation completed successfully. The Promise now has a resolved value. Your package arrived.</p>
<p><strong>Rejected</strong> : the operation failed. The Promise has a reason for failure (an error). Delivery failed.</p>
<pre><code class="language-javascript">// A Promise starts pending
let myPromise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve("Package delivered!");  // moves to fulfilled
    // or: reject(new Error("Delivery failed")); // moves to rejected
  }, 2000);
});

console.log(myPromise);  // Promise { &lt;pending&gt; } — checked too early
</code></pre>
<p>Two rules about states worth remembering:</p>
<p><strong>States are final once settled.</strong> Once a Promise fulfills or rejects, it cannot change. A fulfilled Promise stays fulfilled forever. You can attach handlers to it even after it's resolved, you'll still get the value.</p>
<p><strong>A settled Promise is either fulfilled or rejected, never both.</strong> Only <code>resolve</code> or <code>reject</code> is ever called, and only the first call matters:</p>
<pre><code class="language-javascript">let p = new Promise((resolve, reject) =&gt; {
  resolve("first");   // this one counts
  reject("second");   // ignored — Promise already settled
  resolve("third");   // also ignored
});

p.then(val =&gt; console.log(val));  // "first"
</code></pre>
<h2>3. Basic Promise Lifecycle</h2>
<p>Now let's look at how you create and consume Promises.</p>
<h3><strong>Creating a Promise</strong></h3>
<p>You create a Promise with <code>new Promise()</code>, passing it an executor function. The executor receives two arguments — <code>resolve</code> and <code>reject</code> — which you call depending on whether the operation succeeded or failed:</p>
<p>js</p>
<pre><code class="language-javascript">let fetchWeather = new Promise(function(resolve, reject) {
  // Simulating an API call with a timer
  setTimeout(function() {
    let success = true;

    if (success) {
      resolve({ city: "Indore", temp: 32, condition: "Sunny" });
    } else {
      reject(new Error("Weather service unavailable"));
    }
  }, 1500);
});
</code></pre>
<p>The executor runs <em>immediately</em> when the Promise is created. The async work happens inside it. When the work completes, call <code>resolve</code> with the result, or <code>reject</code> with an error.</p>
<h3><strong>Consuming a Promise</strong></h3>
<p>Once you have a Promise, you attach handlers to it using <code>.then()</code> and <code>.catch()</code>:</p>
<pre><code class="language-javascript">fetchWeather
  .then(function(data) {
    console.log(`\({data.city}: \){data.temp}°C, ${data.condition}`);
    // "Indore: 32°C, Sunny"
  })
  .catch(function(err) {
    console.error("Error:", err.message);
  });
</code></pre>
<p><code>.then()</code> receives the resolved value. <code>.catch()</code> receives the rejection reason. Neither is called synchronously, they're always called asynchronously, after the current synchronous code finishes.</p>
<h3><strong>Promise Shorthand</strong></h3>
<p>For cases where you already have a value (or a known error), you don't need to construct a full Promise:</p>
<pre><code class="language-javascript">// Already have a value — resolve immediately
let resolved = Promise.resolve(42);
resolved.then(val =&gt; console.log(val));  // 42

// Already know it failed
let rejected = Promise.reject(new Error("Known failure"));
rejected.catch(err =&gt; console.log(err.message));  // "Known failure"
</code></pre>
<h2>4. Handling Success and Failure</h2>
<p><code>.then()</code> and <code>.catch()</code> are your main tools for responding to a Promise's outcome. Let's look at them in depth.</p>
<h3><code>.then(onFulfilled, onRejected)</code> :</h3>
<p><code>.then()</code> actually accepts two arguments, a success handler and an optional failure handler:</p>
<pre><code class="language-javascript">fetchUser(42).then(
  function(user) { console.log("Got user:", user.name); },   // success
  function(err)  { console.log("Failed:", err.message); }    // failure
);
</code></pre>
<p>In practice, most developers use <code>.catch()</code> for the failure case instead — it's cleaner and handles errors from anywhere in the chain. But knowing <code>.then()</code> accepts both is useful context.</p>
<h3><code>.catch()</code><strong>: Centralized Error Handling</strong></h3>
<p><code>.catch(handler)</code> is shorthand for <code>.then(null, handler)</code>. It catches rejections from the Promise it's attached to, or from any <code>.then()</code> earlier in the chain:</p>
<pre><code class="language-javascript">fetchUserProfile(userId)
  .then(profile =&gt; {
    if (!profile.isActive) throw new Error("Account suspended");
    return profile;
  })
  .then(profile =&gt; displayProfile(profile))
  .catch(err =&gt; {
    // Catches: fetchUserProfile rejection OR the "Account suspended" throw
    showErrorBanner(err.message);
  });
</code></pre>
<p>Notice the <code>throw</code> inside <code>.then()</code> — throwing inside a <code>.then()</code> handler automatically converts the chain into a rejection, which flows down to <code>.catch()</code>. This is one of the most useful features of the Promise chain.</p>
<h3><code>.finally()</code> <strong>: Always Runs</strong></h3>
<p>Just like <code>try/catch/finally</code>, Promises have <code>.finally()</code> — a handler that runs regardless of outcome:</p>
<pre><code class="language-javascript">showSpinner();

fetchDashboardData()
  .then(data =&gt; renderDashboard(data))
  .catch(err =&gt; showErrorMessage(err.message))
  .finally(() =&gt; hideSpinner());  // always called
</code></pre>
<p><code>.finally()</code> doesn't receive any argument, it has no way of knowing whether the Promise fulfilled or rejected, and intentionally so. It's only for cleanup.</p>
<h2>5. Promise Chaining</h2>
<p><strong>The Key Rule:</strong> <code>.then()</code> always returns a new Promise. Whatever you return from a <code>.then()</code> handler, becomes the resolved value of that new Promise, which the next <code>.then()</code> in the chain receives.</p>
<p>In simple word, outcome of the one <code>.then()</code> can be input in the next <code>.then()</code> in the chain.</p>
<pre><code class="language-javascript">Promise.resolve(1)
  .then(val =&gt; val + 1)      // receives 1, returns 2
  .then(val =&gt; val * 10)     // receives 2, returns 20
  .then(val =&gt; console.log(val));  // receives 20
// 20
</code></pre>
<p>Each <code>.then()</code> transforms the value and passes it to the next. It's a pipeline.</p>
<p><strong>Returning Promises From Chains</strong></p>
<p>When you return a <em>Promise</em> from a <code>.then()</code> handler, the chain waits for that Promise to resolve before calling the next <code>.then()</code>:</p>
<pre><code class="language-javascript">fetchUser(userId)
  .then(user =&gt; {
    return fetchOrders(user.id);  // returns a Promise — chain waits for it
  })
  .then(orders =&gt; {
    return fetchDetails(orders[0].id);  // same — returns a Promise
  })
  .then(details =&gt; {
    displayDetails(details);
  })
  .catch(err =&gt; handleError(err));
</code></pre>
<p>This is the mechanic that flattens callback hell. Instead of nesting callbacks inside callbacks, each async step returns a Promise, and the chain handles the sequencing for you.</p>
<h2>Conclusion</h2>
<p>Promises solved a real, painful problem in JavaScript, and they did it by changing how async results are represented, not just how they're written.</p>
<p>A Promise is a placeholder for a future value. It moves from pending to either fulfilled or rejected , once, permanently. You respond to outcomes with <code>.then()</code> for success, <code>.catch()</code> for failure, and <code>.finally()</code> for cleanup. You chain them to sequence async operations cleanly, without nesting.</p>
<p>The mental model to carry forward: a Promise is a contract. It says "I may not have the answer right now , but I will give you one, and you can tell me what to do with it when I do."</p>
<p>once you're comfortable with Promises, async/await becomes completely natural, because it's just Promises, written to look like the synchronous code you already know.</p>
]]></content:encoded></item><item><title><![CDATA[Error Handling in JavaScript: Try, Catch, Finally]]></title><description><![CDATA[If you are a developer, at some point, you have seen your program crash with a cryptic red message in the console, and had absolutely no idea where things went wrong.
Errors are not the enemy. They ar]]></description><link>https://blog.rohitchornele.online/error-handling-in-javascript-try-catch-finally</link><guid isPermaLink="true">https://blog.rohitchornele.online/error-handling-in-javascript-try-catch-finally</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[error handling]]></category><category><![CDATA[trycatch]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 10:14:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/cd2edd34-430a-4f15-8539-06f082a3c567.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are a developer, at some point, you have seen your program crash with a cryptic red message in the console, and had absolutely no idea where things went wrong.</p>
<p>Errors are not the enemy. They are information. The real problem isn't that errors happen, it's when they happen silently, or crash your entire application, or give the user a broken experience with no explanation.</p>
<p>Good error handling is the difference between a program that collapses the moment something unexpected happens, and one that responds gracefully, informs the user, and keeps running where it can.</p>
<p>JavaScript provides tools like <code>try</code>, <code>catch</code>, and <code>finally</code> to manage errors gracefully. Instead of crashing your application, these tools allow your program to recover and continue running.</p>
<h2>1. What Errors Are in JavaScript</h2>
<p>JavaScript has several built-in error types, each representing a different kind of problem:</p>
<p>We can devide errors into two broad categories for understanding:</p>
<ol>
<li><p>Syntax Error : caught before code runs. Your editor or the JavaScript engine spots them immediately. You can't handle these with try/catch because the code never starts executing.</p>
</li>
<li><p>Runtime Error : happen while the code runs. These are the ones error handling is designed for, like : unexpected conditions, bad data, failed network requests, null values where objects were expected.</p>
</li>
</ol>
<h2>2. Understanding try and catch Blocks</h2>
<p>The <code>try/catch</code> block is JavaScript's fundamental error handling structure. The concept is simple: <em>try</em> to run some code, and if anything goes wrong, <em>catch</em> the error and handle it.</p>
<pre><code class="language-javascript">try {
  let result = undefinedVariable;
} catch (error) {
  console.log("Error caught:", error.message);
}
</code></pre>
<h3>Runtime Error Examples</h3>
<p>Without <code>try/catch</code>, a runtime error crashes the entire program, everything after it stops running.</p>
<p><strong>Without Error Handling</strong></p>
<pre><code class="language-javascript">let result = undefinedVariable;
console.log(result);
</code></pre>
<p>This will crash the program.</p>
<p>With <code>try/catch</code>, execution jumps to the <code>catch</code> block, handles the error, and continues normally afterward.</p>
<p><strong>Common Error Scenarios</strong></p>
<ul>
<li><p>Accessing undefined variables</p>
</li>
<li><p>Invalid operations</p>
</li>
</ul>
<h2>3. The finally Block</h2>
<p><code>finally</code> is a block that runs no matter what, whether the <code>try</code> succeeded, whether an error was caught, even if there's a <code>return</code> statement inside <code>try</code> or <code>catch</code>.</p>
<p>Syntax :</p>
<pre><code class="language-javascript">try {
  // attempt something
} catch (err) {
  // handle failure
} finally {
  // ALWAYS runs
}
</code></pre>
<p>Primary use cases of <code>finally</code> : cleanup resources that need to be released, loading spinners that need to be hidden, connections that need to be closed, regardless of what happened.</p>
<p>Example :</p>
<pre><code class="language-javascript">async function submitForm(formData) {
  showLoadingSpinner();

  try {
    let result = await sendToServer(formData);
    showSuccessMessage("Form submitted!");
    return result;
  } catch (err) {
    showErrorMessage("Submission failed. Please try again.");
  } finally {
    hideLoadingSpinner();  // always hides — success or failure
  }
}
</code></pre>
<p>Without <code>finally</code>, you'd need to call <code>hideLoadingSpinner()</code> in both the <code>try</code> and <code>catch</code> blocks. Duplicating code and risking missing it in one path. <code>finally</code> guarantees it runs once, cleanly, regardless of the outcome.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/4f74bd56-e3de-48da-99b2-33f23207ffe8.png" alt="" style="display:block;margin:0 auto" />

<h2>4. Throwing Custom Errors</h2>
<p>So far, we've been catching errors that JavaScript throws. But you can throw errors yourself, and you should, when your code encounters a condition it can't or shouldn't handle silently.</p>
<p>The <code>throw</code> keyword works with any value, but throwing an <code>Error</code> object is best practice because it includes a stack trace.</p>
<pre><code class="language-javascript">throw new Error("Something went wrong");
throw new TypeError("Expected a string");
throw new RangeError("Value must be between 1 and 100");
</code></pre>
<p>Example :</p>
<pre><code class="language-javascript">function createUser(name, age) {
  if (!name || typeof name !== "string") {
    throw new TypeError("Name must be a non-empty string");
  }

  if (age &lt; 0 || age &gt; 120) {
    throw new RangeError("Age must be between 0 and 120");
  }

  return { name, age, createdAt: new Date() };
}


try {
  let user = createUser("", 25);
} catch (err) {
  console.error(`\({err.name}: \){err.message}`);
  // "TypeError: Name must be a non-empty string"
}
</code></pre>
<h2>5. Why Error Handling Matters</h2>
<p>Error handling is a professional practice. Here's why it matters beyond just keeping your app from crashing.</p>
<ol>
<li><p><strong>User Experience :</strong> An unhandled error shows the user a broken, frozen, or confusing interface. A handled error shows them a clear message and a path forward. This is the difference between a product that feels trustworthy and one that feels fragile.</p>
</li>
<li><p><strong>Debugging :</strong> Caught errors with logged stack traces tell you exactly what went wrong, where, and under what conditions. Uncaught errors that silently corrupt state are some of the hardest bugs to diagnose.</p>
</li>
<li><p><strong>Separation of Concerns :</strong> Throwing errors at the point of failure and handling them at the appropriate level keeps your code clean. A database function doesn't need to know how to show UI messages it throws. The UI layer catches and responds.</p>
</li>
</ol>
<h2>Conclusion</h2>
<p>Error handling isn't the fancy part of JavaScript, but it's one of the most important habits you can build as a developer.</p>
<p>The pattern is simple: <code>try</code> the risky code, <code>catch</code> what goes wrong, <code>finally</code> clean up regardless.</p>
<p>Throw your own errors when you catch invalid conditions early. Use custom error classes when different failures need different responses.</p>
<p>Code that handles errors well doesn't just survive the unexpected, it communicates clearly, recovers gracefully, and earns the trust of the people using it.</p>
]]></content:encoded></item><item><title><![CDATA[Async/Await in JavaScript: Writing Cleaner Asynchronous Code]]></title><description><![CDATA[Async/Await in JavaScript is a modern way to handle asynchronous operations in a simple and readable manner. Before async/await, developers relied on callbacks and promises, which often made code hard]]></description><link>https://blog.rohitchornele.online/async-await-in-javascript-writing-cleaner-asynchronous-code</link><guid isPermaLink="true">https://blog.rohitchornele.online/async-await-in-javascript-writing-cleaner-asynchronous-code</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[asynchronous JavaScript]]></category><category><![CDATA[async/await]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Thu, 26 Mar 2026 08:28:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/455b8d98-b887-4cec-9069-826f37d5fdf1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Async/Await in JavaScript is a modern way to handle asynchronous operations in a simple and readable manner. Before async/await, developers relied on callbacks and promises, which often made code harder to understand.</p>
<p>Async/await was introduced in ES2017 to make asynchronous code look and behave more like synchronous code. This makes your programs easier to read, write, and debug.</p>
<p>Code Example before async/await :</p>
<pre><code class="language-javascript">getUserData(userId)
  .then(user =&gt; {
    return getOrders(user.id);
  })
  .then(orders =&gt; {
    return getOrderDetails(orders[0].id);
  })
  .then(details =&gt; {
    return sendConfirmation(details.email);
  })
  .then(result =&gt; {
    console.log("Done!", result);
  })
  .catch(err =&gt; {
    console.error("Something went wrong:", err);
  });
</code></pre>
<p>It works. It's better than callback hell. But it still requires a kind of mental gymnastics while tracking what each <code>.then()</code> receives, what it returns, and where errors bubble up from.</p>
<p>Now look at the same logic written with async/await:</p>
<pre><code class="language-javascript">async function processOrder(userId) {
  try {
    let user = await getUserData(userId);
    let orders = await getOrders(user.id);
    let details = await getOrderDetails(orders[0].id);
    let result = await sendConfirmation(details.email);
    console.log("Done!", result);
  } catch (err) {
    console.error("Something went wrong:", err);
  }
}
</code></pre>
<p>Same operations. Same asynchronous behavior underneath. But now it reads top to bottom, like a recipe. Each step is clear. Error handling is in one place. You can follow the logic without mentally unwrapping <code>.then()</code> chains.</p>
<h2>1. Why Async/Await Was Introduced</h2>
<p>Before async/await:</p>
<p>Callbacks caused messy nested code (callback hell).</p>
<p>Promises were a massive improvement over callbacks. They eliminated callback hell and gave us a cleaner way to sequence async operations. But as applications grew more complex, Promise chains developed their own friction.</p>
<p>Async/await simplifies both.</p>
<h2>2. Understanding Async Functions</h2>
<h3>What is an Async Function?</h3>
<p>An async function is a function declared using the <code>async</code> keyword.</p>
<ul>
<li><p>The function always returns a Promise : no matter what you write inside it</p>
</li>
<li><p>The <code>await</code> keyword becomes available inside it</p>
</li>
</ul>
<h3>How Async Functions Work ?</h3>
<p>When you use <code>async</code>, JavaScript automatically wraps the return value in a promise.</p>
<pre><code class="language-javascript">async function greet() {
  return "Hello";
}

greet().then(console.log);
</code></pre>
<p>You wrote <code>return "Hello!"</code> , but because the function is <code>async</code>, JavaScript automatically wraps that value in <code>Promise.resolve("Hello!")</code>. The function <em>looks</em> like it returns a string. It actually returns a resolved Promise.</p>
<h2>3. The Await Keyword Concept</h2>
<p>It's the keyword that actually makes asynchronous code look synchronous.</p>
<p>Put <code>await</code> in front of a Promise, and JavaScript will:</p>
<ol>
<li><p><strong>Pause execution of the async function</strong> at that line (Not whole program, rest of the js continues running normally)</p>
</li>
<li><p><strong>Wait for the Promise to resolve</strong></p>
</li>
<li><p><strong>Unwrap the resolved value</strong> and return it</p>
</li>
<li><p><strong>Resume the function</strong> from the next line</p>
</li>
</ol>
<p>Example :</p>
<pre><code class="language-javascript">async function getData() {
  let response = await fetch("https://api.example.com/data");
  let data = await response.json();
  console.log(data);
}
</code></pre>
<h2>4. Async/Await as Syntactic Sugar</h2>
<p><strong>What is Syntactic Sugar?</strong></p>
<p>Syntactic sugar means writing code in a simpler, cleaner way without changing how it works internally.</p>
<p><strong>How It Simplifies Promises :</strong></p>
<p>Async/await is built on top of promises but removes the need for <code>.then()</code> chains.</p>
<h3>Comparison With Promises</h3>
<p>Async/await and Promises are not competing approaches, they're the same underlying mechanism with different surfaces.</p>
<p>Examples :</p>
<p><strong>Promises:</strong></p>
<pre><code class="language-javascript">fetch(url)
  .then(res =&gt; res.json())
  .then(data =&gt; console.log(data));
</code></pre>
<p><strong>Async/Await:</strong></p>
<pre><code class="language-javascript">let res = await fetch(url);
let data = await res.json();
console.log(data);
</code></pre>
<h2>5. Error Handling with Async Code</h2>
<p>With Promises, you handle errors with <code>.catch()</code> at the end of the chain, or in each <code>.then()</code>. It works, but it separates your error handling from your logic:</p>
<pre><code class="language-javascript">fetchUser(id)
  .then(user =&gt; fetchOrders(user.id))
  .then(orders =&gt; processOrders(orders))
  .catch(err =&gt; console.error(err));  // handles errors from anywhere above
</code></pre>
<p><strong>Async/await</strong> allows simple error handling using <code>try...catch</code>.</p>
<pre><code class="language-javascript">async function processUserOrders(id) {
  try {
    let user = await fetchUser(id);
    let orders = await fetchOrders(user.id);
    let result = await processOrders(orders);
    console.log("Success:", result);
  } catch (err) {
    console.error("Failed:", err.message);
  }
}
</code></pre>
<p>The <code>try</code> block contains your happy path. The <code>catch</code> block handles any failure, from any <code>await</code> in the try block. One error handler covers the whole flow.</p>
<h2>Conclusion</h2>
<p>Async/await didn't change how JavaScript handles asynchronous operations. Promises still power everything underneath. The event loop still coordinates the task queue. None of that changed.</p>
<p>What changed is how you <em>express</em> that logic, and that change in expression has a surprisingly large impact on how readable, debuggable, and maintainable your code is.</p>
<p>The mental model is simple: mark a function <code>async</code>, and inside it you can <code>await</code> any Promise. The function pauses at each <code>await</code> without blocking the main thread, collects the result, and continues. Errors are handled with <code>try/catch/finally</code>, the same way you handle synchronous errors.</p>
]]></content:encoded></item><item><title><![CDATA[Synchronous vs Asynchronous JavaScript]]></title><description><![CDATA[Let's start to understand with real life scenario :
Imagine you're at a chai stall. The owner takes your order, makes your chai right then and there... you stand and wait, no one else gets served, the]]></description><link>https://blog.rohitchornele.online/synchronous-vs-asynchronous-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/synchronous-vs-asynchronous-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[chaiblog]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[asynchronous]]></category><category><![CDATA[synchronous]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:45:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/2aa678b9-9712-4df9-8c9e-ea71a7b47063.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's start to understand with real life scenario :</p>
<p>Imagine you're at a chai stall. The owner takes your order, makes your chai right then and there... you stand and wait, no one else gets served, the whole stall is frozen until your cup is ready.</p>
<p>That's synchronous. One thing at a time. Everything waits.</p>
<p>Now imagine a modern cafe. You walk up, place your order, get a token number, and go sit down. The barista starts on your coffee. While that's brewing, someone else orders. Then someone else. When your coffee is ready, they call your number... you walk up, pick it up, and continue your day. Nobody waited. Nothing was blocked.</p>
<p>That's asynchronous. Multiple things happening, results delivered when ready.</p>
<p>JavaScript, by nature, is the chai stall owne, it runs on a single thread, doing one thing at a time. But the real world is the modern cafe, data loads from servers, files get read, timers fire, users click things, and none of it arrives at a predictable moment.</p>
<p>Asynchronous JavaScript is how the single-threaded chai stall learned to behave like a modern cafe, without actually becoming one.</p>
<h2>1. What Synchronous Code Means</h2>
<p>Synchronous code executes line by line, one step at a time. Each task must complete before the next one begins.</p>
<p>No line begins until the previous one is completely done. The execution is sequential, predictable, and perfectly ordered.</p>
<pre><code class="language-javascript">console.log("Step 1: Wake up"); 
console.log("Step 2: Make tea"); 
console.log("Step 3: Check phone");
console.log("Step 4: Start work");
</code></pre>
<pre><code class="language-plaintext">
Output — exactly as written, exactly in order:

Step 1: Wake up
Step 2: Make tea
Step 3: Check phone
Step 4: Start work
</code></pre>
<p>JavaScript read line one, ran it, moved to line two, ran it, and so on.</p>
<h2>2. What Asynchronous Code Means</h2>
<p>Asynchronous code allows tasks to run in the background without blocking the main program.</p>
<p>Asynchronous code breaks the "wait for it to finish before moving on" rule.</p>
<p>When JavaScript encounters an asynchronous operation, it says: "I'll start this, but I'm not going to sit here waiting. I'll move on and come back to handle the result when it's ready."</p>
<p><strong>The simple code example :</strong> <code>setTimeout</code><strong>:</strong></p>
<pre><code class="language-javascript">console.log("1. Before timer");

setTimeout(function() {
  console.log("2. Inside timer — ran after 2 seconds");
}, 2000);

console.log("3. After timer");
</code></pre>
<p>What do you expect the output to be?</p>
<p>If you're thinking synchronously, you'd say: <code>1, then 2 (after a 2-second pause), then 3.</code></p>
<p>But here's what actually prints:</p>
<pre><code class="language-plaintext">1. Before timer
3. After timer
2. Inside timer — ran after 2 seconds
</code></pre>
<p>Line 3 printed <em>before</em> line 2, even though line 2 comes earlier in the code.</p>
<p>JavaScript didn't freeze for 2 seconds. It registered the timer, moved on to line 3, and later, when the 2 seconds elapsed, came back to run the callback.</p>
<p>This is asynchronous behavior in its most fundamental form.</p>
<p><strong>Here's what's happening under the hood :</strong></p>
<ul>
<li><p>JavaScript's call stack runs <code>console.log("1.")</code> ---&gt; done</p>
</li>
<li><p>It encounters <code>setTimeout</code> ---&gt; hands the timer off to the browser's timer API and says <em>"call this function in 2 seconds"</em></p>
</li>
<li><p>It moves on immediately and runs <code>console.log("3.")</code> ---&gt; done</p>
</li>
<li><p>2 seconds later, the callback is placed in the <strong>task queue</strong></p>
</li>
<li><p>When the call stack is empty, it picks up the callback from the queue and runs it ---&gt; <code>console.log("2.")</code></p>
</li>
</ul>
<h2>3. Why JavaScript Needs Asynchronous Behavior</h2>
<p>JavaScript was designed to run in a browser, and browsers do things that take unpredictable amounts of time.</p>
<p>A user clicks a button --&gt; how long does the click handler take? Milliseconds. A page loads an image from a server --&gt; how long does that take? Anywhere from 50ms to 5 seconds. A script reads from a database --&gt; how long? Completely depends on network conditions.</p>
<p>If JavaScript blocked on every single one of these operations, the browser tab would freeze. Completely. Scroll wouldn't work. Animations would stop. Other buttons wouldn't respond. The user would stare at an unresponsive page and close the tab.</p>
<p>This is the core problem that asynchronous JavaScript solves: keeping the main thread free so the browser (and users) can keep functioning while slow operations happen in the background.</p>
<p>The browser provides Web APIs: <code>setTimeout</code>, <code>fetch</code>, <code>XMLHttpRequest</code>, DOM event listeners, that handle slow operations <em>outside</em> the main JavaScript thread. JavaScript kicks them off, hands them to the browser, and picks up the results via callbacks when they're ready. That handoff is the key of async JavaScript.</p>
<h2>4. Examples — API Calls and Timers</h2>
<p>Let's look at the two most common sources of asynchronous behavior in real JavaScript work.</p>
<h3>Timers — <code>setTimeout</code> and <code>setInterval</code></h3>
<pre><code class="language-javascript">setTimeout(() =&gt; {
  console.log("Runs later");
}, 1000);


setInterval(() =&gt; {
  secondsElapsed++;
  console.log(`${secondsElapsed} second(s) have passed.`);

  if (secondsElapsed === 5) {
    clearInterval(timer);
    console.log("Timer stopped.");
  }
}, 1000);

console.log("Timer started — main thread continues freely.");
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Timer started — main thread continues freely. 

1 second(s) have passed. 
2 second(s) have passed. 
3 second(s) have passed. 
4 second(s) have passed. 
5 second(s) have passed. 
Timer stopped.
</code></pre>
<h3>API Calls — Fetching Data from a Server</h3>
<p>This is where asynchronous behavior matters most in modern web development. Almost every meaningful web app loads data from somewhere : a backend, a third-party API, a database.</p>
<p>Here's what an API call looks like using the modern <code>fetch</code> API:</p>
<pre><code class="language-javascript">fetch("https://api.example.com/data")
  .then(response =&gt; response.json())
  .then(data =&gt; console.log(data));
</code></pre>
<p>These examples show how async tasks don’t block execution.</p>
<h2>5. Problems That Occur With Blocking Code</h2>
<p>If any piece of synchronous code takes a long time to finish, <em>everything else stops.</em> The call stack is occupied. No callbacks can run. No events can be handled. No UI updates can happen. The page freezes.</p>
<p>Here's a simple example:</p>
<pre><code class="language-javascript">console.log("Before heavy task");

// Simulating a blocking operation — a tight loop running for ~3 seconds
let start = Date.now();
while (Date.now() - start &lt; 3000) {
  // doing nothing — just burning time
}

console.log("After heavy task");
</code></pre>
<p>While that <code>while</code> loop runs, nothing else in the browser can happen. Click a button — nothing. Scroll the page — nothing. Type in an input — nothing. The JavaScript thread is completely occupied.</p>
<h3><strong>Example Scenario</strong></h3>
<p>Imagine clicking a button and waiting several seconds with no response: this is blocking behavior.</p>
<p><strong>Heavy Data Processing :</strong></p>
<p>Imagine you receive a JSON response with 50,000 records and you loop through all of them synchronously to build a UI:</p>
<pre><code class="language-javascript">// This blocks the thread for the entire duration
let processedData = [];

for (let i = 0; i &lt; 50000; i++) {
  processedData.push(heavyTransform(records[i]));
}

renderUI(processedData);
</code></pre>
<p>While this loop runs, the user can't interact with anything. On a slow device, this could mean a noticeable freeze.</p>
<h2>Conclusion</h2>
<p>Synchronous code is your baseline, sequential, predictable, line by line. It's perfect for logic that runs fast and doesn't depend on the outside world.</p>
<p>Asynchronous code is what lets JavaScript stay responsive in a world where things take time. Timers, API calls, user events, none of these arrive predictably, and waiting for them synchronously would make every web app feel broken.</p>
<p>The mental model to carry with you:</p>
<p><strong>Synchronous</strong> : the chai stall owner who stops everything to make your drink while the queue waits.</p>
<p><strong>Asynchronous</strong> : the cafe that takes your order, hands you a token, keeps serving others, and calls your number when it's ready.</p>
<p>JavaScript is always the single-threaded chai stall at heart. But with the event loop, the task queue, and the browser's Web APIs, it has learned to run like the cafe : handling multiple things, staying responsive, and delivering results exactly when they're ready.</p>
<p>Everything that comes next in your JavaScript journey, Promises, async/await, event handling, performance optimization, is built directly on top of this foundation. And now you have it.</p>
]]></content:encoded></item><item><title><![CDATA[String Polyfills and Common String Methods in JavaScript]]></title><description><![CDATA[Here's a question that shows up in JavaScript interviews more often than you'd expect:

Can you implement your own version of String.prototype.includes()?

And here's what usually happens. The candida]]></description><link>https://blog.rohitchornele.online/string-polyfills-and-common-string-methods-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/string-polyfills-and-common-string-methods-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[polyfills]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:02:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/4c9f3c53-f34a-4fc9-83e1-b5f97557321b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here's a question that shows up in JavaScript interviews more often than you'd expect:</p>
<blockquote>
<p><em>Can you implement your own version of</em> <code>String.prototype.includes()</code><em>?</em></p>
</blockquote>
<p>And here's what usually happens. The candidate has used <code>includes()</code> hundreds of times. They know exactly what it does. But when asked to write it from scratch, without calling the built-in, they stuck. Not because they are not smart. But because they've been using the method without ever thinking about the logic <em>inside</em> it.</p>
<p>This article is about closing that gap.</p>
<p>String Polyfills and Common Interview Methods in JavaScript are essential topics for anyone preparing for coding interviews or trying to deepen their understanding of JavaScript fundamentals.</p>
<h3><strong>Why This Topic is Important for Interviews</strong></h3>
<p>Interviewers often test:</p>
<ul>
<li><p>Your understanding of core JavaScript concepts</p>
</li>
<li><p>Your ability to think logically</p>
</li>
<li><p>Your skill in writing clean, efficient code</p>
</li>
</ul>
<h2>1. What Are String Methods</h2>
<p>In simple terms, string methods are built-in tools that help you manipulate text.</p>
<p>In JavaScript, strings are primitive values... but they behave like objects when you access properties on them. When you write <code>"hello".toUpperCase()</code>, JavaScript temporarily wraps the string in a <code>String</code> object, finds the <code>toUpperCase</code> method on <code>String.prototype</code>, calls it, and returns the result.</p>
<p><code>String.prototype</code> is essentially a shared shelf of methods that every string in JavaScript has access to. When you call a method on a string, JavaScript goes to that shelf and borrow the method.</p>
<p>JavaScript provides many built-in methods such as : <code>split()</code> , <code>trim()</code> , <code>replace()</code> , <code>includes()</code> , <code>toUpperCase()</code> , <code>toLowerCase()</code> etc.</p>
<p>These methods simplify string manipulation.</p>
<p>Each of these methods takes the string, does something to it, and returns a result. They never modify the original string. <strong>Strings in JavaScript are immutable</strong>. Every string method returns a new value. The original stays untouched.</p>
<p>Example :</p>
<pre><code class="language-javascript">let name = "rohit";

// All of these live on String.prototype
name.toUpperCase();    // "ROHIT"
name.includes("hit");  // true
name.trim();           // "rohit" (no spaces to trim here)
name.startsWith("roh"); // true
name.repeat(2);        // "rohitrohit"

// After performing all these operation, name would have the same value as initial value
console.log(name)        //rohit (Immutable: no change in original string)
</code></pre>
<h2>2. Why Developers Write Polyfills</h2>
<p>The word <code>polyfill</code> sounds technical, but the idea is simple. A polyfill is custom code that replicates the behavior of a built-in method.</p>
<p>Imagine you're using a feature in a newer version of JavaScript.... let's say, <code>String.prototype.padStart()</code>, introduced in ES2017. Your code runs beautifully in Chrome. But then you test it in an older browser that doesn't know what <code>padStart</code> is, and it throws an error.</p>
<p>A polyfill is your solution now: <strong>write your own version of the missing method, and attach it to the prototype so it behaves exactly like the real thing would.</strong></p>
<p>Code Implementation :</p>
<pre><code class="language-javascript">// Check if the method doesn't exist yet
if (!String.prototype.padStart) {
  // If not, add our own version
  String.prototype.padStart = function(targetLength, padString) {
    // we can write our implementation here
  };
}
</code></pre>
<p>The pattern is always the same:</p>
<ol>
<li><p>Check if the built-in already exists</p>
</li>
<li><p>If it doesn't, define your own version with identical behavior</p>
</li>
<li><p>Attach it to the prototype so every string can use it</p>
</li>
</ol>
<p>One important rule: in production code, always check before adding to native prototypes. Adding to <code>String.prototype</code> without checking can break other code or conflict with future language updates.</p>
<h2>3. Implementing Simple String Utilities</h2>
<p>Now let's actually build some polyfills. For each one, we'll understand what the built-in does conceptually and then write our own version from scratch.</p>
<h3><code>trim()</code> — Remove Whitespace From Both Ends</h3>
<p><strong>What it does:</strong> Removes all leading and trailing whitespace from a string. Whitespace includes spaces, tabs, and newlines. The middle of the string is untouched.</p>
<pre><code class="language-javascript">"  hello world  ".trim()   // "hello world"
"   hi   ".trim()          // "hi"
"no spaces".trim()         // "no spaces"
</code></pre>
<p><strong>The Logic :</strong> Walk from the left end to right until you hit a non-space character. Walk from the right end to left until you hit a non-space character. Return everything in between.</p>
<p><strong>Implementation</strong> :</p>
<pre><code class="language-javascript">String.prototype.myTrim = function() {
  let str = this;
  let start = 0;
  let end = str.length - 1;

  // Move start forward while there's whitespace
  while (start &lt;= end &amp;&amp; str[start] === ' ') {
    start++;
  }

  // Move end backward while there's whitespace
  while (end &gt;= start &amp;&amp; str[end] === ' ') {
    end--;
  }

  // Return the slice between the two pointers
  return str.slice(start, end + 1);
};

// Uses
"  hello  ".myTrim();  // "hello"
"  hi there  ".myTrim(); // "hi there"
</code></pre>
<h3><code>repeat()</code> — Repeat a String N Times</h3>
<p><strong>What it does:</strong> Returns a new string made by repeating the original string a given number of times.</p>
<pre><code class="language-javascript">"ha".repeat(3)     // "hahaha"
"ab".repeat(4)     // "abababab"
"*".repeat(5)      // "*****"
"hi".repeat(0)     // ""
</code></pre>
<p><strong>The logic:</strong> Start with an empty result. Add the string to it <code>n</code> times using a loop.</p>
<p><strong>Implementation</strong> :</p>
<pre><code class="language-javascript">String.prototype.myRepeat = function(count) {
  if (count &lt; 0) throw new RangeError("Invalid count value");
  if (count === 0) return "";

  let str = this.valueOf();
  let result = "";

  for (let i = 0; i &lt; count; i++) {
    result += str;
  }

  return result;
};


//Uses
"ha".myRepeat(3);   // "hahaha"
"*".myRepeat(5);    // "*****"
</code></pre>
<h2>4. Common Interview String Problems</h2>
<p>Now let's move from polyfills to classic string problems. These are the kinds of questions that appear in real interviews, just to understand how you think through a problem.</p>
<h3>Problem 1 : Reverse a String</h3>
<pre><code class="language-javascript">// Using built-ins (what they might ask you NOT to use)
"hello".split("").reverse().join("")  // "olleh"


/*-------------------------------------------------------------------*/

// Manual approach — what they usually want to see
function reverseString(str) {
  let reversed = "";

  for (let i = str.length - 1; i &gt;= 0; i--) {
    reversed += str[i];
  }

  return reversed;
}



reverseString("hello");       // "olleh"
reverseString("JavaScript");  // "tpircSavaJ"
</code></pre>
<h3>Problem 2 : Check if a String is a Palindrome</h3>
<pre><code class="language-javascript">function isPalindrome(str) {
  let cleaned = str.toLowerCase();
  let left = 0;
  let right = cleaned.length - 1;

  while (left &lt; right) {
    if (cleaned[left] !== cleaned[right]) {
      return false;  // mismatch found — not a palindrome
    }
    left++;
    right--;
  }

  return true;
}



isPalindrome("madam");    // true
isPalindrome("racecar");  // true
isPalindrome("hello");    // false
isPalindrome("Level");    // true — case insensitive
</code></pre>
<h3>Problem 3 — Count Occurrences of a Character</h3>
<pre><code class="language-javascript">function countOccurrences(str, char) {
  let count = 0;

  for (let i = 0; i &lt; str.length; i++) {
    if (str[i] === char) {
      count++;
    }
  }

  return count;
}

countOccurrences("javascript", "a");   // 2
countOccurrences("mississippi", "s");  // 4
countOccurrences("hello", "z");        // 0
</code></pre>
<p>Follow-up question : <em>"What if we want to count all characters and return a frequency map?"</em></p>
<pre><code class="language-javascript">function charFrequency(str) {
  let freq = {};

  for (let char of str) {
    freq[char] = (freq[char] || 0) + 1;
  }

  return freq;
}


charFrequency("javascript");
// { j: 1, a: 2, v: 1, s: 1, c: 1, r: 1, i: 1, p: 1, t: 1 }
</code></pre>
<h2>5. Importance of understanding built-in behavior</h2>
<p>Every built-in string method has a specification. The JavaScript language defines exactly what <code>trim()</code> should do with unicode whitespace, what <code>includes()</code> should do with an empty search string, what <code>padStart()</code> should do if the pad string is longer than the padding needed. These edge cases are all defined.</p>
<pre><code class="language-javascript">// Edge cases you discover when implementing

"".myIncludes("");          // should return true — empty string is inside everything
"hello".myIncludes("");     // should return true
"hi".myRepeat(0);           // should return "" — zero repetitions
"hi".myRepeat(-1);          // should throw RangeError
"hello".myPadStart(3, "*"); // should return "hello" — already longer than target
</code></pre>
<p>Every one of these is a real behavior of the built-in method. When you implement the polyfill and discover these cases, you understand the built-in <em>better</em> than you did before. That understanding pays off when:</p>
<ul>
<li><p>You're debugging unexpected output and need to know exactly what a method does in an edge case</p>
</li>
<li><p>You're doing a code review and spotting where a method might behave unexpectedly</p>
</li>
<li><p>You're in an interview and can speak to edge cases confidently</p>
</li>
<li><p>You're working on a performance-sensitive piece of code and know whether a built-in is the right tool</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The new Keyword in JavaScript]]></title><description><![CDATA[At some point while learning JavaScript, you've probably written something like this without fully questioning it :
let today = new Date();
let pattern = new RegExp("hello");

The new keyword just... ]]></description><link>https://blog.rohitchornele.online/the-new-keyword-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/the-new-keyword-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[chai-code ]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[new keyword]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Wed, 25 Mar 2026 11:59:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/837fe507-aa58-43c7-b487-357e7c02300e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At some point while learning JavaScript, you've probably written something like this without fully questioning it :</p>
<pre><code class="language-javascript">let today = new Date();
let pattern = new RegExp("hello");
</code></pre>
<p>The <code>new</code> keyword just... worked. The object appeared. You moved on.</p>
<p>But have you ever stopped to ask, what is <code>new</code> actually <em>doing</em> here? Why does this syntax exist? What happens between typing <code>new Date()</code> and getting a fully formed date object back?</p>
<p>Let's understand this step by step.</p>
<h2>1. What is new Keyword ?</h2>
<p>The new Keyword in JavaScript is a simple but powerful feature that helps you create objects from functions. If you're just starting with JavaScript, understanding this keyword will make object-oriented programming much easier.</p>
<p>In basic terms, the <code>new</code> keyword allows you to create multiple objects using a single blueprint, called a constructor function. This helps keep your code clean, reusable, and easy to manage.</p>
<h3>Importance of new</h3>
<p>The <code>new</code> keyword:</p>
<ul>
<li><p>Helps create objects easily</p>
</li>
<li><p>Allows reuse of code</p>
</li>
<li><p>Connects objects to shared methods</p>
</li>
</ul>
<h3><strong>Where It is Commonly Used</strong></h3>
<p>You’ll see <code>new</code> used in:</p>
<ul>
<li><p>Object creation</p>
</li>
<li><p>Built-in objects like <code>Date</code>, <code>Array</code></p>
</li>
<li><p>Custom constructor functions</p>
</li>
</ul>
<h2>2. What the new Keyword Does</h2>
<p>The <code>new</code> keyword creates a new object and connects it to a constructor function.</p>
<p>Internally <code>new</code> is a set of instructions disguised as a single word.</p>
<p>When you write <code>new SomeFunction()</code>, JavaScript doesn't just call that function. It does four specific things behind the scenes, in order:</p>
<ol>
<li><p><strong>Creates a brand new, empty object</strong> : <code>{}</code></p>
</li>
<li><p><strong>Links that object to a prototype</strong></p>
</li>
<li><p><strong>Runs the function with</strong> <code>this</code> <strong>pointing to that new object</strong></p>
</li>
<li><p><strong>Returns the new object automatically</strong></p>
</li>
</ol>
<p>That's it. Four steps. Every time you use <code>new</code>, these four things happen, whether you're using a built-in like <code>Date</code>, or a constructor you wrote yourself.</p>
<p><strong>Simple Example :</strong></p>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

let user = new Person("John");
console.log(user.name);
</code></pre>
<p><strong>Output Explanation :</strong></p>
<ul>
<li><p>A new object is created</p>
</li>
<li><p><code>this</code> refers to that object</p>
</li>
<li><p>The property <code>name</code> is added</p>
</li>
</ul>
<h2>3. Constructor Functions</h2>
<p>A constructor function is just a regular JavaScript function with one convention: <strong>its name starts with a capital letter.</strong></p>
<p>That capital letter is a signal that this function is meant to be called with <code>new</code>, not on its own.</p>
<p>Here's the simplest possible constructor :</p>
<pre><code class="language-javascript">function Person(name, age) {
  this.name = name;
  this.age = age;
}

// let's use this :

let rahul = new Person("Rahul", 28);
let priya = new Person("Priya", 24);

console.log(rahul.name);  // "Rahul"
console.log(priya.age);   // 24
</code></pre>
<p>That's it. No <code>return</code> statement. No magic. Just properties being attached to <code>this</code>.</p>
<p>Two separate objects, created from the same template. Each has its own <code>name</code> and <code>age</code>. They're independent, changing one doesn't affect the other.</p>
<h3>what happens if you call <code>Person</code> <em>without</em> <code>new</code> :</h3>
<pre><code class="language-javascript">let whoops = Person("Meera", 22);

console.log(whoops);        // undefined  — no object returned
console.log(window.name);   // "Meera"   — this.name went to the global object!
</code></pre>
<p>Without <code>new</code>, the function runs normally. <code>this</code> points to the global object (or is <code>undefined</code> in strict mode).</p>
<h2>4. Object Creation Process ( Step by Step )</h2>
<p>This is where The new Keyword in JavaScript becomes really interesting.</p>
<p>Let's walk through exactly what happens when you write <code>new Person("Rahul", 28)</code>, one step at a time.</p>
<h3>Step 1 : A new empty object is created</h3>
<p>JavaScript internally creates this:</p>
<pre><code class="language-javascript">let obj = {};
</code></pre>
<p>Nothing on it yet. A blank slate.</p>
<h3><strong>Step 2 : The prototype is linked</strong></h3>
<p>JavaScript connects <code>obj</code> to <code>Person.prototype</code>, a special object that holds shared behaviors.</p>
<pre><code class="language-javascript">obj.__proto__ = Person.prototype;
</code></pre>
<h3><strong>Step 3 — The constructor runs with</strong> <code>this = obj</code></h3>
<p>Now <code>Person</code> is called, but with <code>this</code> pointing to our new empty object:</p>
<pre><code class="language-javascript">// Inside Person, this = obj
this.name = "Rahul";   // obj.name = "Rahul"
this.age = 28;         // obj.age = 28
</code></pre>
<p>Properties are being stamped onto the fresh object.</p>
<h3><strong>Step 4 : The object is returned automatically</strong></h3>
<p>You didn't write a <code>return</code> statement, and that's correct. <code>new</code> handles the return automatically:</p>
<pre><code class="language-javascript">return obj;  // JavaScript does this for you
</code></pre>
<p>The finished object lands in <code>rahul</code>.</p>
<h2>5. How new Links Prototypes</h2>
<p>Every function in JavaScript has a property called <code>prototype</code>. It's an object that sits quietly attached to the function, waiting to be used.</p>
<p>When you create an object with <code>new</code>, that object gets a hidden link to the constructor's <code>prototype</code> and share methods via the <code>prototype</code>. This means the object can access anything on <code>prototype</code>, even though those properties aren't directly on the object itself.</p>
<p><strong>Example with Prototype</strong></p>
<pre><code class="language-javascript">function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  return this.name + " makes a sound";
};

let dog = new Animal("Dog");
console.log(dog.speak());
</code></pre>
<p>This avoids duplicating methods for every object.</p>
<h2>6. Instances Created From Constructors</h2>
<p>Every object created with <code>new</code> is called an instance of that constructor.</p>
<p>The word "instance" just means: a specific object built from a specific template. There may be multiple objects created from one constructor, each object is called an instance of that particular constructor.</p>
<p><code>rahul</code> is an instance of <code>Person</code>. <code>laptop</code> is an instance of <code>Product</code>.</p>
<p>Each object is separate but shares the same structure.</p>
<pre><code class="language-javascript">let user1 = new Person("Alice");
let user2 = new Person("Bob");
</code></pre>
<p>Both objects:</p>
<ul>
<li><p>Have different values</p>
</li>
<li><p>Share the same methods</p>
</li>
</ul>
<h2>7. A Note on Modern Syntax : Classes</h2>
<p>You may have seen this style in modern JavaScript:</p>
<pre><code class="language-javascript">class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hi, I'm ${this.name}!`);
  }
}

let rahul = new Person("Rahul", 28);
rahul.greet();  // "Hi, I'm Rahul!"
</code></pre>
<p>This <code>class</code> syntax was introduced in ES6. It looks different, cleaner, more familiar if you've used other languages, but under the hood, it does <em>exactly the same thing</em> as the constructor function approach you just learned.</p>
<p><code>class</code> is syntactic sugar. The prototype chain, the <code>new</code> keyword, the four-step creation process, all of it still happens. JavaScript didn't change how objects work. It just gave us a different way to write it.</p>
<p>If you understand constructor functions and <code>new</code>, you already understand classes.</p>
<table>
<thead>
<tr>
<th>Constructor Function Style</th>
<th>Class Style</th>
</tr>
</thead>
<tbody><tr>
<td><code>function Person(name) {</code> <a href="http://this.name"><code>this.name</code></a> <code>= name; }</code></td>
<td><code>constructor(name) {</code> <a href="http://this.name"><code>this.name</code></a> <code>= name; }</code></td>
</tr>
<tr>
<td><code>Person.prototype.greet = function() {}</code></td>
<td><code>greet() {}</code> inside the class body</td>
</tr>
<tr>
<td><code>new Person("Rahul")</code></td>
<td><code>new Person("Rahul")</code> — identical</td>
</tr>
</tbody></table>
<p>Classes are the preferred modern style — but the mental model is identical. Knowing both makes you a developer who truly understands the language, not just its surface.</p>
]]></content:encoded></item><item><title><![CDATA[Callbacks in JavaScript]]></title><description><![CDATA[Let's start with a real life situation, you've definitely lived through :
You call a restaurant to order food. The person on the phone says, "We'll call you back when your order is ready." So you hang]]></description><link>https://blog.rohitchornele.online/callbacks-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/callbacks-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[chai-code ]]></category><category><![CDATA[callback]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Wed, 25 Mar 2026 10:56:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/a27b722e-e87d-47eb-a31d-b614a9964b87.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's start with a real life situation, you've definitely lived through :</p>
<p>You call a restaurant to order food. The person on the phone says, "We'll call you back when your order is ready." So you hang up. You don't stand frozen at the phone, staring at it, waiting. You go do other things like watch TV, finish some work, make some tea. Then your phone rings, the food is ready, and then you act.</p>
<p>That "call us back when it's done" instruction? That's a callback.</p>
<p>In JavaScript, a callback is a function you hand to another function and say: "Run this when you're done."</p>
<p>At first glance, callbacks may seem confusing, but they are actually one of the most fundamental and powerful concepts in JavaScript.</p>
<p>JavaScript treats functions as “first-class citizens,” meaning they can be assigned to variables, passed as arguments, and returned from other functions. This flexibility is what makes callbacks possible.</p>
<h2>1. What is a Callback Function?</h2>
<p>A callback function is simply a function that is passed into another function as an argument and is executed later.</p>
<p>In JavaScript, functions are treated like any other value. This means you can:</p>
<ul>
<li><p>Store a function in a variable</p>
</li>
<li><p>Pass a function as an argument to another function</p>
</li>
<li><p>Return a function from a function</p>
</li>
</ul>
<p>Let's understand these one by one :</p>
<h3>Store a Function in a Variable :</h3>
<pre><code class="language-javascript">const sayHello = function() { 
    console.log("Hello!"); 
};

sayHello(); // "Hello!"
</code></pre>
<p>The function lives in <code>sayHello</code> like a value.</p>
<h3>Passing Functions as Arguments :</h3>
<pre><code class="language-javascript">// Main Function
function greet(callback) {
  console.log("Getting ready to greet...");
  callback();  // calling the function that was passed in
}

// Another Function
function sayHello() {
  console.log("Hello!");
}

// Calling Main Function with Another function as argument

greet(sayHello);

// "Getting ready to greet..."
// "Hello!"
</code></pre>
<p>We passed <code>sayHello</code>, the function itself, not its result, into <code>greet</code>. Then inside <code>greet</code>, we called it using <code>callback()</code>.</p>
<p><strong>That passed-in function :</strong> <code>sayHello</code> <strong>, is the callback.</strong></p>
<p>A callback is simply: a function passed into another function, to be called at a specific moment.</p>
<h3><strong>What a Callback Function Is</strong></h3>
<p><strong>Definition and Core Concept :</strong> A callback is executed after another function finishes its task.</p>
<p><strong>How Callbacks Work Internally :</strong> Think of callbacks as instructions passed to a function to run later.</p>
<h2>2. Why Callbacks Are Used in Asynchronous Programming</h2>
<p>JavaScript runs in a single thread. That means it does one thing at a time, one line at a time, top to bottom. Usually, that's fine. But some operations take time, like: fetching data from a server, reading a file, waiting for a timer. If JavaScript just stopped and waited for every slow operation, your entire webpage would freeze.</p>
<p>Imagine clicking a button on a website and having everything, scrolling, animations, all other buttons lock up for three seconds while data loads. That's what synchronous waiting would feel like. Unusable.</p>
<p>Callbacks help avoid this by allowing tasks to run in the background.</p>
<h2>3. Passing Functions as Arguments</h2>
<p>Now that we understand why callbacks exist, let's explore how to write and pass them.</p>
<p>There are a few different styles you'll see in real codebases, and they all mean the same thing.</p>
<h3>Style 1 : Named function, passed by reference</h3>
<pre><code class="language-javascript">function handleClick() {
  console.log("Button was clicked!");
}

document.getElementById("btn").addEventListener("click", handleClick);
</code></pre>
<p><code>handleClick</code> is defined separately and passed in by name. Notice: no <code>()</code> after <code>handleClick</code>, you're passing the function itself, not calling it.</p>
<h3>Style 2 : Anonymous function, defined inline</h3>
<pre><code class="language-javascript">document.getElementById("btn").addEventListener("click", function() {
  console.log("Button was clicked!");
});
</code></pre>
<p>Same result. The function has no name, it's defined right there, on the spot, inside the argument. This is extremely common and perfectly valid.</p>
<h3>Style 3 : Arrow function (modern shorthand)</h3>
<pre><code class="language-javascript">document.getElementById("btn").addEventListener("click", () =&gt; {
  console.log("Button was clicked!");
});
</code></pre>
<p>Arrow functions are ES6 syntax, shorter, cleaner, and you'll see them everywhere in modern code. For callbacks, they behave the same way.</p>
<p>All three styles do exactly the same job. Which one you use comes down to the situation:</p>
<ul>
<li><p>Use <strong>named functions</strong> when the same callback is reused in multiple places</p>
</li>
<li><p>Use <strong>anonymous functions</strong> when the callback is short and used only once</p>
</li>
<li><p>Use <strong>arrow functions</strong> when you want modern, concise syntax</p>
</li>
</ul>
<h2>4. Callback Usage in Common Scenarios</h2>
<p>Callbacks aren't an exotic feature you only use in special situations. They're woven into everyday JavaScript. Here are the scenarios where you'll encounter them constantly.</p>
<h3><strong>Array Methods :</strong> <code>.forEach()</code><strong>,</strong> <code>.map()</code><strong>,</strong> <code>.filter()</code></h3>
<p>Every time you use a higher-order array method, you're passing a callback:</p>
<pre><code class="language-javascript">let products = [
  { name: "Notebook", price: 120, inStock: true },
  { name: "Pen", price: 30, inStock: false },
  { name: "Backpack", price: 850, inStock: true },
];

// forEach — do something with each item
products.forEach(product =&gt; {
  console.log(`\({product.name}: ₹\){product.price}`);
});

// filter — get only items that match a condition
let available = products.filter(product =&gt; product.inStock);
// [{ name: "Notebook", ... }, { name: "Backpack", ... }]

// map — transform each item into something new
let names = products.map(product =&gt; product.name);
// ["Notebook", "Pen", "Backpack"]
</code></pre>
<p>In every case, you're handing a function to another function. The array method handles the looping, you just describe <em>what to do with each item.</em></p>
<h3>Event Handling :</h3>
<p>Every interactive element on a webpage uses callbacks:</p>
<pre><code class="language-javascript">button.addEventListener("click", function() {
  console.log("Button clicked!");
});
</code></pre>
<h3><strong>API Calls</strong></h3>
<p>Used to handle responses after data is fetched.</p>
<h3>Timers (setTimeout, setInterval)</h3>
<p>Every timer in JavaScript runs via a callback. The timer itself handles the waiting, you just provide what should happen when time is up.</p>
<pre><code class="language-javascript">setTimeout(function() { 
    console.log("Executed after 2 seconds"); 
}, 2000);
</code></pre>
<h2>5. Basic Problem of Callback Nesting</h2>
<p>Here's where the honest part of this article comes in, because callbacks aren't perfect, and it's important to know why.</p>
<h3><strong>Callback Hell :</strong></h3>
<p>When callbacks are nested inside each other repeatedly, it creates deeply indented code.</p>
<p>During callback each step depends on the previous one completing. In JavaScript code, when you chain several asynchronous operations where each depends on the last, you end up writing callbacks inside callbacks inside callbacks. Like this:</p>
<pre><code class="language-javascript">loginUser(username, password, function(user) {
  getUserProfile(user.id, function(profile) {
    getOrderHistory(profile.id, function(orders) {
      getOrderDetails(orders[0].id, function(details) {
        displayOrderSummary(details, function() {
          console.log("Done!");
        });
      });
    });
  });
});


loginUser(
  getUserProfile(
    getOrderHistory(
      getOrderDetails(
        displaySummary(
          // we've reached the pyramid's peak
        )
      )
    )
  )
)
</code></pre>
<p>This pyramid structure is often called <strong>callback hell</strong>.</p>
<h3><strong>Why It Becomes Hard to Maintain</strong></h3>
<ul>
<li><p>Difficult to read</p>
</li>
<li><p>Hard to debug</p>
</li>
<li><p>Error handling becomes complex</p>
</li>
</ul>
<h2><strong>Conclusion</strong></h2>
<p>Callbacks in JavaScript, becomes clear when you understand JavaScript’s asynchronous nature. They allow developers to manage tasks efficiently without blocking execution, making applications faster and more responsive.</p>
<p>While callbacks are powerful, they can become difficult to manage when overused. That’s why modern JavaScript often uses Promises and async/await for cleaner code. Still, callbacks remain a foundational concept that every JavaScript developer must understand.</p>
]]></content:encoded></item><item><title><![CDATA[Template Literals in JavaScript]]></title><description><![CDATA[If you've written JavaScript for more than a week, you've probably typed something like this:
let message = "Hello, " + userName + "! You have " + count + " new messages.";

You stare at it. You count]]></description><link>https://blog.rohitchornele.online/template-literals-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/template-literals-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[template literals]]></category><category><![CDATA[string]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Wed, 25 Mar 2026 09:20:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/a0b3a19c-ff74-4cce-9d49-eca8ff95314d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've written JavaScript for more than a week, you've probably typed something like this:</p>
<pre><code class="language-javascript">let message = "Hello, " + userName + "! You have " + count + " new messages.";
</code></pre>
<p>You stare at it. You count the quotes. You wonder if that space before the exclamation mark is in the right place. You run it, something looks off, and you spend five minutes realizing you missed a <code>+</code> somewhere between two strings.</p>
<p>Sound familiar?</p>
<p>String building in old JavaScript was one of those things that worked technically, but always felt slightly more painful than it needed to be.</p>
<p>Template literals are the better tool to work with complex string structure. Introduced in ES6, they completely change how you write strings in JavaScript, making them cleaner, more readable, and less error-prone.</p>
<h2>1. What Are Template Literals?</h2>
<p>Template literals are a modern JavaScript feature that allows you to create strings using backticks (<code>` `</code>) instead of single (<code>' '</code>) or double (<code>" "</code>) quotes.</p>
<p>They support:</p>
<ul>
<li><p>Embedded expressions</p>
</li>
<li><p>Multi-line strings</p>
</li>
<li><p>String interpolation</p>
</li>
</ul>
<h3>Importance in Modern JavaScript</h3>
<p>In modern development, readability and maintainability are most important thing. Template literals solve many problems that developers faced with traditional string handling.</p>
<p><strong>Few benefits of Template Literals :</strong></p>
<ul>
<li><p>Reduce code complexity</p>
</li>
<li><p>Improve readability</p>
</li>
<li><p>Make dynamic string creation easier</p>
</li>
</ul>
<h2>2. Problems with Traditional String Concatenation</h2>
<p>Before template literals, developers used string concatenation to combine text and variables. While it worked, it wasn’t always efficient or readable.</p>
<p>Let's suppose a simple welsome message for a user profile page, in old way :</p>
<pre><code class="language-javascript">let name = "Priya";
let age = 24;
let city = "Bhopal";

let profile = "Hi, my name is " + name + " and I am " + age + " years old. I live in " + city + ".";
</code></pre>
<h3>Problem 1 : Complex Syntex</h3>
<p>In above example, we are using few words inside <code>" "</code> and few are free from quotes, Traditional concatenation often looks cluttered, especially when multiple variables are involved.</p>
<p>As you can see in the above example, repeated use of <code>+</code> makes the code harder to read.</p>
<h3>Problem 2 : Space and Punctuation Errors</h3>
<p>Every space in your output has to be manually placed either at the end of a string (<code>"name is "</code>) or at the start (<code>" and I am"</code>). Miss one, and words collide. Add an extra, and your output gets awkward double spaces. These bugs are embarrassingly easy to introduce and annoying to spot.</p>
<h3>Problem 3 : Multi-line Strings Are a Nightmare</h3>
<p>What if you want a string that spans multiple lines, like an email template or a block of HTML? This is what you had to do:</p>
<pre><code class="language-javascript">let email = "Dear " + name + ",\n\n" +
            "Thank you for signing up.\n" +
            "Your account is ready.\n\n" +
            "Best,\nThe Team";
</code></pre>
<p>The <code>\n</code> characters are invisible newlines, you have to mentally convert them to line breaks as you read. And the <code>+</code> at the end of each line is just visual clutter doing nothing interesting.</p>
<p>There's nothing wrong with any of this code, it runs fine. But the actual problem is readability and writing complexity. Technically accurate. Needlessly difficult.</p>
<h3>Poorly Structured Strings</h3>
<p>This can be a mistake a developer can make, which may lead to confusing output and bugs.</p>
<p>Example :</p>
<pre><code class="language-javascript">let message = "Hi" + name + "you are" + age + "years old";
</code></pre>
<h2>2. Template Literal Syntax</h2>
<p>Template literals look like strings, but with two key differences:</p>
<ol>
<li><p>They use backticks ` instead of single ' or double " quotes</p>
</li>
<li><p>They let you embed expressions/variables directly using <code>${ }</code>, no <code>+</code> required</p>
</li>
</ol>
<p>That's genuinely the whole thing.</p>
<p>Example :</p>
<pre><code class="language-javascript"> // Old way
let greeting = "Hello, " + name + "!";

// Template literal 
let greeting = `Hello, ${name}!` ; 
</code></pre>
<p>Read the second line, "Hello, name, exclamation mark." It reads almost like natural English. No mental translation required. The backtick key lives in the top-left corner of most keyboards, just above the Tab key, same key as the <code>~</code> tilde character. You might have never used it before JavaScript gave it this purpose.</p>
<p>The syntax includes placeholders using <code>${}</code>.</p>
<p>Inside the <code>${ }</code>, you can put any valid JavaScript expression:</p>
<pre><code class="language-javascript">let name = "John";
let age = 25;

let message = `My name is \({name} and I am \){age} years old.`;
</code></pre>
<p>This is much cleaner and easier to read.</p>
<h2>3. Embedding Variables in Strings</h2>
<p>One of the most powerful features of Template Literals in JavaScript is variable embedding.</p>
<h3>String Intrpolation :</h3>
<p>String interpolation allows variables to be inserted directly into a string using <code>${}</code>.</p>
<p>You can even include expressions inside <code>${ }</code>:</p>
<p>Example :</p>
<pre><code class="language-javascript">let a = 5;
let b = 10;

let result = `The sum is ${a + b}`;
</code></pre>
<p>This makes your code dynamic and flexible.</p>
<h2>4. Multi-line Strings Made Easy</h2>
<p>As we discussed in chapter 2 (problems with traditional strings), handling multi-line strings used to be frustrating.</p>
<h3><strong>Limitations of Traditional Strings :</strong></h3>
<p>Previously, developers had to use:</p>
<ul>
<li><p><code>\n</code> for line breaks</p>
</li>
<li><p>Concatenation across lines</p>
</li>
</ul>
<h3><strong>Using Template Literals for Multi-line Text</strong></h3>
<p>Template literals allow natural multi-line strings:</p>
<pre><code class="language-javascript">let text = `This is line one
This is line two
This is line three`;
</code></pre>
<h3><strong>Real-World Example</strong></h3>
<pre><code class="language-javascript">let html = `
  &lt;div&gt;
    &lt;h1&gt;Hello&lt;/h1&gt;
    &lt;p&gt;Welcome to JavaScript&lt;/p&gt;
  &lt;/div&gt;
`;
</code></pre>
<p>This is especially useful for HTML templates.</p>
<h2>5. Use cases in modern JavaScript</h2>
<p>Template literals are not just a convenience feature but they show up everywhere in modern JavaScript development. Once you start spotting them, you'll realize they're in almost every codebase you read.</p>
<p>Some important use cases of template literals are as follow :</p>
<h3>Building HTML Templates</h3>
<p>They simplifiy dynamic HTML creation</p>
<pre><code class="language-javascript">let html = `
  &lt;div&gt;
    &lt;h1&gt;Hello&lt;/h1&gt;
    &lt;p&gt;Welcome to JavaScript&lt;/p&gt;
  &lt;/div&gt;
`;
</code></pre>
<h3>API Data Handling ( Dynamic URLs )</h3>
<p>Every time you make an API call with a dynamic ID or parameter, template literals make it clean:</p>
<pre><code class="language-javascript">let userId = 105;
let endpoint = `https://api.myapp.com/users/${userId}/orders`;
// "https://api.myapp.com/users/105/orders"
</code></pre>
<p>Compare this to <code>"</code><a href="https://api.myapp.com/users/"><code>https://api.myapp.com/users/</code></a><code>" + userId + "/orders"</code> and you immediately feel the improvement.</p>
<h3>React and JSX : Dynamic Class Names and Content</h3>
<p>In React, template literals are everywhere for conditional styling and dynamic content:</p>
<pre><code class="language-javascript">let isActive = true; 
let buttonClass = btn ${isActive ? "btn-active" : "btn-disabled"};

// In JSX 
&lt;button className={btn ${isActive ? "btn-active" : "btn-disabled"}}&gt; 
    Click Me
&lt;/button&gt;
</code></pre>
<h3>Logging and Debugging</h3>
<p>Template literals make your <code>console.log</code> statements dramatically easier to read while debugging:</p>
<pre><code class="language-javascript">// Old way — squinting required
console.log("User " + user.id + " failed login. Attempt: " + attempts + ". IP: " + ip);

// Template literal — readable at a glance
console.log(`User \({user.id} failed login. Attempt: \){attempts}. IP: ${ip}`);
</code></pre>
<h2><strong>6. Common Mistakes to Avoid</strong></h2>
<p><strong>Incorrect Use of Backticks :</strong> Using quotes instead of backticks will break interpolation.</p>
<p><strong>Misusing Expressions :</strong> Avoid overly complex expressions inside <code>${}</code>.</p>
<h2>Conclusion</h2>
<p>Template literals are one of those features that seem small on paper but quietly improve the experience of writing JavaScript every single day.</p>
<p>You're not learning a complex concept here — you're learning to swap <code>"</code> and <code>'</code> for <code>`</code>, and to replace <code>+</code> with <code>${ }</code>. That's the whole mechanical change. But the <em>effect</em> of that change on readability, on maintainability, on how confidently you can write and read strings, is surprisingly significant.</p>
<p>Here's the simple rule to carry forward:</p>
<p><strong>if your string involves any variable, any logic, or more than one line : use a template literal.</strong> Old-style concatenation has essentially one remaining use case: <strong>very simple, short, static strings where the old syntax genuinely feels fine.</strong></p>
<p>For everything else, backticks are your friend.</p>
]]></content:encoded></item><item><title><![CDATA[Array Flatten in JavaScript]]></title><description><![CDATA[In JavaScript, arrays can nest inside other arrays, sometimes several levels deep. And while that structure can make sense when data is first collected or received, there are plenty of moments where y]]></description><link>https://blog.rohitchornele.online/array-flatten-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/array-flatten-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[chaiblog]]></category><category><![CDATA[array]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Tue, 24 Mar 2026 18:03:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/e3a29264-a2d4-484f-95b6-5749449b6d59.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In JavaScript, arrays can nest inside other arrays, sometimes several levels deep. And while that structure can make sense when data is first collected or received, there are plenty of moments where you just need everything laid out flat in one clean, simple list.</p>
<p>That's what array flattening is. And by the end of this article, you'll not only understand what it means and why it matters, you'll have multiple ways to do it, and you'll know which way to reach for depending on the situation.</p>
<h2>1. What Are Nested Arrays</h2>
<p>Let's start from the beginning, because this concept is easier to feel than to define.</p>
<p>A normal array looks like this:</p>
<pre><code class="language-javascript">let fruits = ["apple", "banana", "mango"];
</code></pre>
<p>Simple. One level. Everything is right there.</p>
<p>Now imagine you're collecting the weekly shopping list from three different family members, and each person gave you their list separately:</p>
<pre><code class="language-javascript">let shoppingList = [
  ["apple", "banana"],           // Mom's list
  ["milk", "eggs", "butter"],    // Dad's list
  ["chips", "juice"]             // Your list
];
</code></pre>
<p>This is a <strong>nested array</strong>, an array that contains other arrays as its elements. Each inner array is sitting inside the outer one, like folders inside a folder.</p>
<p>It gets deeper too. Real-world data, especially from APIs can come in multiple levels of nesting:</p>
<pre><code class="language-javascript">let deepList = [
  ["apple", ["green apple", "red apple"]],
  ["milk", ["full fat", ["skimmed", "semi-skimmed"]]],
];
</code></pre>
<p>Now you've got arrays inside arrays inside arrays. Opening one box just reveals another.</p>
<h2>2. Why Flattening Arrays Is Useful</h2>
<p>Here's a real situation that every JavaScript developer eventually runs into.</p>
<p>You're building a recipe app. Each cuisine category has a list of dishes. Your data looks like this:</p>
<pre><code class="language-javascript">let menuByCategory = [
  ["Butter Chicken", "Palak Paneer", "Dal Makhani"],   // Indian
  ["Pasta Carbonara", "Risotto", "Tiramisu"],           // Italian
  ["Sushi", "Ramen", "Tempura"]                         // Japanese
];
</code></pre>
<p>This structure makes total sense for <em>organizing</em> the menu. But now you need to:</p>
<ul>
<li><p>Search across all dishes at once</p>
</li>
<li><p>Display every dish in a single scrollable list</p>
</li>
<li><p>Count the total number of dishes</p>
</li>
<li><p>Sort all dishes alphabetically</p>
</li>
</ul>
<p>Suddenly that nicely organized nested structure is working against you. You can't just do <code>menuByCategory.includes("Ramen")</code> — it won't work because <code>"Ramen"</code> is buried inside an inner array.</p>
<p>What you actually need is this:</p>
<pre><code class="language-javascript">["Butter Chicken", "Palak Paneer", "Dal Makhani", "Pasta Carbonara", "Risotto", "Tiramisu", "Sushi", "Ramen", "Tempura"]
</code></pre>
<p>One flat list. Everything accessible. Easy to loop, search, sort, and count.</p>
<p>That transformation, from nested to flat is array flattening.</p>
<p>Other common real-world moments where flattening becomes essential:</p>
<ul>
<li><p><strong>API responses</strong> that return grouped data (orders grouped by date, messages grouped by chat)</p>
</li>
<li><p><strong>Form data</strong> collected in sections that needs to be processed as one list</p>
</li>
<li><p><strong>Tag systems</strong> where each post has an array of tags, and you want all tags across all posts</p>
</li>
<li><p><strong>File paths</strong> grouped by directory that you need as one flat list</p>
</li>
</ul>
<h2>3. The <em>Concept</em> of Flattening (Step by Step)</h2>
<p>Before jumping into code, let's understand what flattening actually does at each step — because this is the kind of thinking that helps you in interviews too. Take this simple nested array: js</p>
<pre><code class="language-javascript">let nested = [1, [2, 3], [4, [5, 6]]];
</code></pre>
<p>Visually, it looks like this:</p>
<pre><code class="language-javascript">[ 1,  [ 2, 3 ],  [ 4, [ 5, 6 ] ] ]
  ↑       ↑            ↑
plain   inner        inner array
number  array      with ANOTHER
                   array inside
</code></pre>
<p><strong>Flattening by one level</strong> means: <em>"Open the outermost arrays and pull their contents up by one level."</em></p>
<pre><code class="language-javascript">Before:  [ 1,  [2, 3],  [4, [5, 6]] ]
After:   [ 1,   2,  3,   4,  [5, 6] ]
</code></pre>
<p>Notice that <code>[5, 6]</code> is still nested, because it was two levels deep, and we only flattened one level. The <code>4</code> came up, but <code>[5, 6]</code> is still wrapped.</p>
<p><strong>Flattening completely (infinite depth)</strong> means: "Keep opening arrays until there are no more arrays inside , just raw values."</p>
<pre><code class="language-javascript">Before:  [ 1,  [2, 3],  [4, [5, 6]] ]
After:   [ 1,   2,  3,   4,   5,  6 ]
</code></pre>
<p>Now every value is at the same level. Clean, flat, accessible.</p>
<h2>4. Different Approaches to Flatten Arrays</h2>
<p>Now let's get into the actual code. There are several ways to flatten arrays in JavaScript, and each has its own personality, some are modern and elegant, some are manual and educational. A well-rounded developer knows all of them.</p>
<h3>Approach 1 --&gt; <code>Array.flat()</code> : The Modern, Built-in Way</h3>
<p>Introduced in ES2019, <code>.flat()</code> is the cleanest solution and the one you'll reach for most often in real projects.</p>
<pre><code class="language-javascript">let nested = [1, [2, 3], [4, [5, 6]]];

nested.flat();      // [1, 2, 3, 4, [5, 6]]  — one level deep (default)
nested.flat(2);     // [1, 2, 3, 4, 5, 6]    — two levels deep
nested.flat(Infinity); // [1, 2, 3, 4, 5, 6] — completely flat, no matter how deep
</code></pre>
<p>Done. One method call, and you've got your clean list ready to display or process.</p>
<p><strong>The one thing to know:</strong> The number you pass in <code>flat(1)</code>, <code>flat(2)</code>, <code>flat(Infinity)</code>, is the <em>depth</em>. If you're unsure how deep your nesting goes, <code>flat(Infinity)</code> is your safest thing to add.</p>
<h3>Approach 2 --&gt; <code>flatMap()</code> : Flatten While You Transform</h3>
<p><code>flatMap()</code> is like <code>.map()</code> and <code>.flat()</code> had a child together. It transforms each element and flattens the result, all in one pass.</p>
<p>Here's a practical example. Say you have a list of sentences, and you want all individual words across all sentences as one flat array:</p>
<pre><code class="language-javascript">let sentences = ["Hello world", "JavaScript is fun", "Modules are great"];

let words = sentences.flatMap(sentence =&gt; sentence.split(" "));
// ["Hello", "world", "JavaScript", "is", "fun", "Modules", "are", "great"]
</code></pre>
<p>Compare this to doing it in two steps:</p>
<pre><code class="language-javascript">// Without flatMap — two operations
let words = sentences.map(sentence =&gt; sentence.split(" ")).flat();
</code></pre>
<p><code>flatMap()</code> does both in one cleaner step.</p>
<p>Another real example : expanding a list of orders where each order has multiple items:</p>
<pre><code class="language-javascript">let orders = [
  { id: 1, items: ["pizza", "cola"] },
  { id: 2, items: ["burger", "fries", "milkshake"] },
];

let allItems = orders.flatMap(order =&gt; order.items);
// ["pizza", "cola", "burger", "fries", "milkshake"]
</code></pre>
<h3>Approach 3 --&gt; <code>reduce()</code> : The Manual, Old-School Way</h3>
<p>Before <code>.flat()</code> existed, developers built their own flattening logic using <code>reduce()</code>. It's worth understanding this approach because it teaches you exactly what flattening <em>does</em> under the hood.</p>
<pre><code class="language-js">let nested = [1, [2, 3], [4, 5]];

let flat = nested.reduce((accumulator, current) =&gt; {
  return accumulator.concat(current);
}, []);

// [1, 2, 3, 4, 5]
</code></pre>
<p>Think of <code>reduce()</code> here as going through each element one by one and asking: <em>"Should I add this directly to my result list, or should I open it up first?"</em></p>
<p>The <code>accumulator</code> is your growing flat list. <code>concat</code> either adds a value directly, or spreads an inner array's items in.</p>
<p>For deeply nested arrays, you'd need a recursive version:</p>
<pre><code class="language-js">function flattenDeep(arr) {
  return arr.reduce((acc, current) =&gt; {
    if (Array.isArray(current)) {
      return acc.concat(flattenDeep(current));  // go deeper
    } else {
      return acc.concat(current);               // add value directly
    }
  }, []);
}

flattenDeep([1, [2, [3, [4]]]]);
// [1, 2, 3, 4]
</code></pre>
<p>Step by step, this is what happens:</p>
<ol>
<li><p>See <code>1</code> : it's not an array, add it directly → <code>[1]</code></p>
</li>
<li><p>See <code>[2, [3, [4]]]</code> : it IS an array, go inside it recursively</p>
</li>
<li><p>See <code>2</code> : add directly → <code>[1, 2]</code></p>
</li>
<li><p>See <code>[3, [4]]</code> : array again, go deeper</p>
</li>
<li><p>See <code>3</code> : add directly → <code>[1, 2, 3]</code></p>
</li>
<li><p>See <code>[4]</code> : array again, go deeper</p>
</li>
<li><p>See <code>4</code> : add directly → <code>[1, 2, 3, 4]</code></p>
</li>
</ol>
<h3>Approach 4 --&gt; Spread + <code>concat</code> : Quick One-Liner for One Level</h3>
<p>For a quick, shallow flatten — just one level deep — this classic trick still works and is fun to know:</p>
<pre><code class="language-js">let nested = [[1, 2], [3, 4], [5, 6]];

let flat = [].concat(...nested);
// [1, 2, 3, 4, 5, 6]
</code></pre>
<p>The spread operator <code>...nested</code> unpacks the outer array, and <code>concat</code> joins everything together. It's a clever trick, but it only works for one level, so don't reach for this with deeply nested data.</p>
<h2>5. Common Interview Scenarios</h2>
<p>Array flattening is a beloved interview topic — and for good reason. It tests whether you understand arrays, recursion, and problem-solving thinking all at once. Here are the scenarios you're most likely to face.</p>
<h3>Scenario 1 --&gt; "Write a flatten function without using <code>.flat()</code>"</h3>
<p>This is the classic. The interviewer wants to see your manual logic, not just your knowledge of built-in methods.</p>
<p>js</p>
<pre><code class="language-js">function flatten(arr) {
  let result = [];

  for (let i = 0; i &lt; arr.length; i++) {
    if (Array.isArray(arr[i])) {
      // It's an array : flatten it and merge into result
      let inner = flatten(arr[i]);
      result = result.concat(inner);
    } else {
      // It's a plain value : add it directly
      result.push(arr[i]);
    }
  }

  return result;
}

flatten([1, [2, [3, [4]]]]);
// [1, 2, 3, 4]
</code></pre>
<p>Walk through this out loud in an interview. Comment your thinking. Interviewers care about <em>how</em> you reason, not just whether the output is right.</p>
<hr />
<h3>Scenario 2 --&gt; "Flatten only up to N levels deep"</h3>
<p>This tests whether you understand the depth parameter concept.</p>
<p>js</p>
<pre><code class="language-js">function flattenToDepth(arr, depth) {
  if (depth === 0) return arr;  // stop going deeper

  let result = [];

  for (let item of arr) {
    if (Array.isArray(item) &amp;&amp; depth &gt; 0) {
      result = result.concat(flattenToDepth(item, depth - 1));
    } else {
      result.push(item);
    }
  }

  return result;
}

flattenToDepth([1, [2, [3, [4]]]], 2);
// [1, 2, 3, [4]]   — stopped at depth 2, so [4] stays nested
</code></pre>
<p>The key insight here: each recursive call <em>reduces the depth by 1</em>. When depth reaches 0, stop digging.</p>
<hr />
<h3>Scenario 3 --&gt; "Get all unique tags from a list of blog posts"</h3>
<p>This is a real-world application question that tests whether you can connect flattening to actual product logic.</p>
<pre><code class="language-js">let posts = [
  { title: "Intro to JS",     tags: ["javascript", "beginners"] },
  { title: "CSS Grid Guide",  tags: ["css", "layout", "beginners"] },
  { title: "Node.js Basics",  tags: ["javascript", "node", "backend"] },
];

let allTags = posts.flatMap(post =&gt; post.tags);
// ["javascript", "beginners", "css", "layout", "beginners", "javascript", "node", "backend"]

let uniqueTags = [...new Set(allTags)];
// ["javascript", "beginners", "css", "layout", "node", "backend"]
</code></pre>
<p>This kind of question tests three things at once: <code>flatMap</code>, data transformation thinking, and deduplication with <code>Set</code>. If you nail this in an interview, you make a strong impression.</p>
<hr />
<h3>Scenario 4 --&gt; "What's the output?" (Tricky Edge Case)</h3>
<p>Interviewers sometimes throw a tricky output question to test your depth understanding:</p>
<pre><code class="language-js">console.log([1, [2, [3]]].flat());
console.log([1, [2, [3]]].flat(1));
console.log([1, [2, [3]]].flat(Infinity));
</code></pre>
<p>Do you know the answers without running the code?</p>
<pre><code class="language-js">// [1, 2, [3]]     — default depth is 1, so [3] is still nested
// [1, 2, [3]]     — same thing, explicit depth 1
// [1, 2, 3]       — Infinity goes all the way
</code></pre>
<h2>Conclusion</h2>
<p>Nested arrays are everywhere in real JavaScript work, in API responses, in grouped data, in collected form inputs. And while nesting makes sense for <em>organizing</em> data, flattening is what makes that data <em>usable</em>.</p>
<p>Here's how to think about it going forward:</p>
<ul>
<li><p>Reach for <code>.flat()</code> in everyday code, it's clean and purpose-built</p>
</li>
<li><p>Use <code>flatMap()</code> when you're transforming and flattening in the same step</p>
</li>
<li><p>Understand <code>reduce()</code> <strong>with recursion</strong> for interviews and custom logic</p>
</li>
<li><p>Know the <strong>depth parameter</strong> : it's the key detail that separates a surface-level answer from a confident one</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[JavaScript Modules: Import and Export Explained]]></title><description><![CDATA[Have you ever opened a drawer, stuffed with everything like: phone chargers, old receipts, keys you don't recognize, a pen that definitely doesn't work anymore? You know what you're looking for is in ]]></description><link>https://blog.rohitchornele.online/javascript-modules-import-and-export-explained</link><guid isPermaLink="true">https://blog.rohitchornele.online/javascript-modules-import-and-export-explained</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[webdev]]></category><category><![CDATA[modules]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Tue, 24 Mar 2026 16:55:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/46ee85e2-fef9-46a8-b06e-63fef262d311.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever opened a drawer, stuffed with everything like: phone chargers, old receipts, keys you don't recognize, a pen that definitely doesn't work anymore? You know what you're looking for is in there somewhere, but finding it feels like an archaeological dig.</p>
<p>That's what your JavaScript code starts to feel like, when everything lives in one file.</p>
<p>Now let's imagine you started a project with excitement, writing everything in <code>index.js</code>. Two weeks later, that file is 800 lines long. Now you realize that your code is breaking somewhere... You scroll up, scroll down, lose your place, accidentally break something while fixing something else... and slowly, you start losing interest.</p>
<p>Modules are JavaScript's answer to that messy drawer. They let you organize your code into small, focused files, each with a clear purpose. And the way you connect those files? That's what <code>import</code> and <code>export</code> are for.</p>
<h2>1. Why Modules Are Needed</h2>
<p>Before modules became a standard part of JavaScript, developers had a serious problem, everything lived in one place. It may lead to global scope pollution problem.</p>
<h3><strong>Global Scope Pollution</strong> Problem :</h3>
<p>As applications grew, a single JavaScript file would become thousands of lines. Variables from one part of the code would accidentally overwrite variables in another. Functions with similar names would clash. Debugging felt like headache.</p>
<p>This is known as the global scope pollution problem. When everything is declared globally, everything can interfere with everything else.</p>
<p>Modules solve this by giving each piece of your code its own private space. Variables and functions inside a module are invisible to the outside world, unless you deliberately choose to share them.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/9cc47ff4-8a97-4306-aa06-eeaa32639159.png" alt="" style="display:block;margin:0 auto" />

<h2>2. Exporting Functions or Values</h2>
<p>To share something from a module, the first step is <strong>exporting</strong>, deciding what a module is willing to share with the rest of your app</p>
<p>Think of exporting as putting something on a shelf that others are allowed to pick up.</p>
<p>JavaScript gives you two ways to export: <strong>named exports</strong> and <strong>default exports</strong>. We will see both of them in detail further in this article, but here's the core idea of a named export:</p>
<p>In <strong>Named export</strong>, we need to export each function or variable, which can be imported in other files with their exact name.</p>
<p>Example : Suppose their is a file named as math.js</p>
<pre><code class="language-javascript">// math.js

export function add(a, b) { 
    return a + b; 
}

export function subtract(a, b) {
    return a - b; 
}

export const PI = 3.14159;
</code></pre>
<p>In above file, <code>add</code> <code>subtract</code> and <code>PI</code> all are made available to other files. Other than that whatever we write in <code>math.js</code> will stay private by default, means no accidental leaks.</p>
<p>We can also do named export in other way as follows :</p>
<pre><code class="language-javascript">// math.js

function add(a, b) { return a + b; }

function subtract(a, b) { return a - b; }

const PI = 3.14159;

export { add, subtract, PI };
</code></pre>
<p>Both approaches do exactly the same thing.</p>
<h2>3. Importing Modules</h2>
<p>Once something is exported, you can import it into another file.</p>
<p>Importing is how you say, "I need this specific tool from that specific shelf."</p>
<pre><code class="language-javascript">// app.js

import { add, PI } from './math.js';

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

console.log(PI);           // 3.14159
</code></pre>
<p>A few things to notice here:</p>
<ul>
<li><p>The curly braces <code>{ }</code> tell JavaScript exactly which named exports you want.</p>
</li>
<li><p>The path <code>./math.js</code> points to where the module lives. The <code>./</code> means <em>"look in the same folder."</em></p>
</li>
<li><p>You only import what you actually need, you don't have to bring in everything the module offers.</p>
</li>
</ul>
<p>If you want everything a module exports under one namespace, you can also do:</p>
<pre><code class="language-javascript">import * as MathUtils from './math.js';

console.log(MathUtils.add(4, 5));  // 9

console.log(MathUtils.PI);          // 3.14159
</code></pre>
<p>This is especially useful when you're using many functions from a module and want to keep them grouped.</p>
<h2>4. Default vs Named Exports</h2>
<p>This is a most confusing topic in export and import, let's understand this precisely.</p>
<h3>Named Exports</h3>
<p>Named exports let you export multiple things from a single file. When importing them, you must use the exact same name which must be wrapped in curly braces.</p>
<p>Example :</p>
<pre><code class="language-javascript">// greetings.js

export function sayHello() { 
    return "Hello!"; 
}

export function sayBye() { 
    return "Goodbye!"; 
}
</code></pre>
<pre><code class="language-javascript">// app.js

import { sayHello, sayBye } from './greetings.js';
</code></pre>
<p>The names must match, means <code>sayHello</code> must be imported as <code>sayHello</code>.</p>
<h3>Default Exports</h3>
<p>A default export is the main thing a module offers.</p>
<p>Each file can only have one default export.</p>
<p>Example :</p>
<pre><code class="language-javascript">// logger.js

export default function log(message) {
  console.log(`[LOG]: ${message}`);
}
</code></pre>
<p>When importing a default export, you skip the curly braces, and you can give it any name you want.</p>
<p>Example :</p>
<pre><code class="language-javascript">js// app.js

import log from './logger.js';
import printMessage from './logger.js'; // this also works!
</code></pre>
<h3>When to Use Which?</h3>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Use</th>
</tr>
</thead>
<tbody><tr>
<td>The file has one clear, main purpose</td>
<td>Default export</td>
</tr>
<tr>
<td>The file provides multiple utilities</td>
<td>Named exports</td>
</tr>
<tr>
<td>A utility library (like math helpers)</td>
<td>Named exports</td>
</tr>
<tr>
<td>A single component or class</td>
<td>Default export</td>
</tr>
</tbody></table>
<h2>5. Benefits of Modular Code</h2>
<p><strong>Better Organization :</strong> Each file has a single, well-defined responsibility. A <code>utils.js</code> file handles utilities. An <code>api.js</code> file handles network calls. You always know exactly where to look.</p>
<p><strong>Easier Maintenance :</strong> When something breaks, you don't hunt through a 3,000 line file. You open the relevant module, fix the issue, and move on. Changes in one module don't unexpectedly break another.</p>
<p><strong>Reusability</strong> : A well-written module is like a brick, you can snap it into any project that needs it. Write a <code>formatDate.js</code> once, and reuse it across five different applications.</p>
<p><strong>Collaboration-Friendly :</strong> Teams can work on different modules simultaneously without stepping on each other's code. Merge conflicts become rare. Code reviews become focused.</p>
<p><strong>Readability :</strong> Code that's split into focused, well-named modules reads almost like documentation. The structure itself communicates intent.</p>
<h2>6. Conclusion</h2>
<p>JavaScript modules aren't just a technical feature, they're a philosophy of writing code that's clean, focused, and built to grow. By using <code>export</code> to share only what's necessary and <code>import</code> to pull in only what's needed, you create applications that are easier to understand, debug, and maintain.</p>
]]></content:encoded></item><item><title><![CDATA[Getting Started with cURL]]></title><description><![CDATA[Whenever you open a website, submit a form, or load data in an app, your computer is communicating with a server somewhere on the internet.
A server is simply a computer designed to store information ]]></description><link>https://blog.rohitchornele.online/getting-started-with-curl</link><guid isPermaLink="true">https://blog.rohitchornele.online/getting-started-with-curl</guid><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 15:17:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/9b731b53-b798-4f61-bfeb-dfcbacc7df36.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Whenever you open a website, submit a form, or load data in an app, your computer is communicating with a server somewhere on the internet.</p>
<p>A server is simply a computer designed to store information and respond to requests from other machines.</p>
<p>For example:</p>
<ul>
<li><p>When you visit a website, your browser asks a server for a webpage.</p>
</li>
<li><p>When a mobile app loads data, it requests information from an API server.</p>
</li>
<li><p>When developers test an API, they send requests to a server.</p>
</li>
</ul>
<p>Normally, your browser handles these requests automatically. But developers often want a simpler way to send requests directly from the command line.</p>
<p>That’s where cURL comes in.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/f452427f-3ef8-4e40-962b-1ec7934003a3.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>What Is cURL?</h2>
<p>cURL is a command-line tool that lets you send requests to a server and receive responses.</p>
<p>In simple terms:</p>
<blockquote>
<p>cURL allows you to communicate with a server directly from your terminal.</p>
</blockquote>
<p>Instead of opening a browser, you can type a command and ask a server for data.</p>
<p>Developers use cURL to:</p>
<ul>
<li><p>test APIs</p>
</li>
<li><p>fetch data from servers</p>
</li>
<li><p>debug backend systems</p>
</li>
<li><p>automate network requests</p>
</li>
</ul>
<p>Because it works directly from the terminal, cURL is one of the most widely used tools in development and DevOps.</p>
<hr />
<h2>Why Programmers Need cURL</h2>
<p>During development, programmers often need to check how a server responds.</p>
<p>For example, you might want to:</p>
<ul>
<li><p>see if an API endpoint works</p>
</li>
<li><p>check the data returned by a server</p>
</li>
<li><p>test a POST request before writing code</p>
</li>
<li><p>debug an error in a backend service</p>
</li>
</ul>
<p>Instead of building a full frontend just to test an API, developers can simply use <strong>cURL</strong>.</p>
<p>It allows you to quickly ask a server:</p>
<pre><code class="language-plaintext">"Hey server, can you send me this data?"
</code></pre>
<p>And the server replies with a response.</p>
<p>This makes debugging and testing much faster.</p>
<hr />
<h2>Making Your First Request Using cURL</h2>
<p>The simplest thing you can do with cURL is fetch a webpage.</p>
<p>Example command:</p>
<pre><code class="language-plaintext">curl https://example.com
</code></pre>
<p>What happens here?</p>
<ol>
<li><p>cURL sends a request to the server at <code>example.com</code></p>
</li>
<li><p>The server processes the request</p>
</li>
<li><p>The server sends back a response</p>
</li>
<li><p>cURL prints the response in the terminal</p>
</li>
</ol>
<p>The output is usually the HTML content of the webpage.</p>
<p>So instead of seeing the webpage visually like in a browser, you see the raw response from the server.</p>
<hr />
<h2>Understanding Request and Response</h2>
<p>Whenever you communicate with a server, two things happen:</p>
<ol>
<li><p><strong>Request</strong> – your computer asks the server for something</p>
</li>
<li><p><strong>Response</strong> – the server sends back the result</p>
</li>
</ol>
<p>This interaction is the foundation of how the web works.</p>
<h3>Basic Flow</h3>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/022886ee-5ff0-4c29-ba40-223663d3dc22.png" alt="" style="display:block;margin:0 auto" />

<p>The response usually contains:</p>
<ul>
<li><p><strong>Status code</strong> (whether the request succeeded)</p>
</li>
<li><p><strong>Headers</strong> (metadata about the response)</p>
</li>
<li><p><strong>Body</strong> (the actual data returned)</p>
</li>
</ul>
<p>Example response idea:</p>
<pre><code class="language-plaintext">Status: 200 OK
Data: HTML page or JSON data
</code></pre>
<p>The <strong>status code</strong> tells you whether the request was successful.</p>
<p>Some common ones:</p>
<table>
<thead>
<tr>
<th>Status Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody><tr>
<td>200</td>
<td>Request successful</td>
</tr>
<tr>
<td>404</td>
<td>Resource not found</td>
</tr>
<tr>
<td>500</td>
<td>Server error</td>
</tr>
</tbody></table>
<hr />
<h2>Using cURL to Talk to APIs</h2>
<p>Many modern applications rely on <strong>APIs</strong>.</p>
<p>An API allows one program to request data from another program.</p>
<p>For example:</p>
<ul>
<li><p>Weather apps fetch weather data from an API</p>
</li>
<li><p>Mobile apps request user data from a backend server</p>
</li>
<li><p>Websites load product data from APIs</p>
</li>
</ul>
<p>cURL makes it easy to test these APIs.</p>
<hr />
<h3>Example GET Request</h3>
<p>A <strong>GET request</strong> asks the server for information.</p>
<p>Example:</p>
<pre><code class="language-plaintext">curl https://api.github.com
</code></pre>
<p>This sends a request to GitHub’s API and returns information about the API.</p>
<p>GET requests are used to:</p>
<ul>
<li><p>retrieve data</p>
</li>
<li><p>fetch resources</p>
</li>
<li><p>load information</p>
</li>
</ul>
<hr />
<h3>Example POST Request</h3>
<p>A <strong>POST request</strong> sends data to a server.</p>
<p>Example:</p>
<pre><code class="language-plaintext">curl -X POST https://example.com/api
</code></pre>
<p>POST requests are commonly used for:</p>
<ul>
<li><p>submitting forms</p>
</li>
<li><p>creating new records</p>
</li>
<li><p>sending data to APIs</p>
</li>
</ul>
<p>At the beginner stage, the key idea is simply:</p>
<pre><code class="language-plaintext">GET → receive data
POST → send data
</code></pre>
<hr />
<h2>Common Mistakes Beginners Make with cURL</h2>
<p>When starting with cURL, beginners often run into a few common issues.</p>
<h3>1. Forgetting the URL</h3>
<p>Every cURL command must include a <strong>valid URL</strong>.</p>
<p>Example mistake:</p>
<pre><code class="language-plaintext">curl
</code></pre>
<p>Correct:</p>
<pre><code class="language-plaintext">curl https://example.com
</code></pre>
<hr />
<h3>2. Confusing Browser Output with API Output</h3>
<p>Browsers render webpages visually, but cURL shows <strong>raw responses</strong>.</p>
<p>So instead of seeing a webpage layout, you’ll see:</p>
<pre><code class="language-plaintext">HTML
JSON
text data
</code></pre>
<p>This is expected.</p>
<hr />
<h3>3. Using Too Many Options Too Early</h3>
<p>cURL has many powerful flags and options, but beginners don’t need most of them right away.</p>
<p>Start with simple commands like:</p>
<pre><code class="language-plaintext">curl URL
curl -X POST URL
</code></pre>
<p>Once you’re comfortable, you can explore more advanced options.</p>
<hr />
<h2>Where cURL Fits in Backend Development</h2>
<p>cURL is widely used in development workflows.</p>
<p>Backend developers use it to:</p>
<ul>
<li><p>test API endpoints</p>
</li>
<li><p>check server responses</p>
</li>
<li><p>debug production services</p>
</li>
</ul>
<p>DevOps engineers use cURL to:</p>
<ul>
<li><p>monitor services</p>
</li>
<li><p>test network connectivity</p>
</li>
<li><p>automate requests in scripts</p>
</li>
</ul>
<p>Even many backend tools and libraries internally mimic what cURL does — sending HTTP requests and processing responses.</p>
<p>Understanding cURL helps developers better understand how clients and servers communicate.</p>
<hr />
<h2>Quick Revision</h2>
<table>
<thead>
<tr>
<th>Concept</th>
<th>Explanation</th>
</tr>
</thead>
<tbody><tr>
<td>cURL</td>
<td>Tool for sending requests from the terminal</td>
</tr>
<tr>
<td>Server</td>
<td>Computer that processes requests and returns responses</td>
</tr>
<tr>
<td>Request</td>
<td>Message sent to a server</td>
</tr>
<tr>
<td>Response</td>
<td>Data returned by the server</td>
</tr>
<tr>
<td>GET</td>
<td>Used to retrieve data</td>
</tr>
<tr>
<td>POST</td>
<td>Used to send data</td>
</tr>
</tbody></table>
<hr />
<h2>Conclusion</h2>
<p>cURL is one of the simplest tools for understanding how communication with servers works.</p>
<p>By sending requests directly from the terminal, you can see exactly how servers respond without needing a browser or application interface.</p>
<p>For developers working with APIs and backend systems, learning cURL provides a strong foundation for understanding HTTP communication and debugging network requests.</p>
<p>Once you're comfortable with the basics, you can explore more advanced features like headers, authentication, and request debugging.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Network Devices]]></title><description><![CDATA[Every time you open a website, send an API request, or deploy an application to the cloud, your data travels through a chain of network devices before reaching its destination.
At home or in an office]]></description><link>https://blog.rohitchornele.online/understanding-network-devices</link><guid isPermaLink="true">https://blog.rohitchornele.online/understanding-network-devices</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[networking]]></category><category><![CDATA[devices]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 14:17:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/f766f61b-2b01-4b29-9203-437b06a82de7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every time you open a website, send an API request, or deploy an application to the cloud, your data travels through a chain of network devices before reaching its destination.</p>
<p>At home or in an office, this journey starts with a few key devices working together. In large production environments, the same concepts scale up with more powerful hardware and cloud equivalents.</p>
<p>Understanding how these devices work is useful not only for network engineers but also for <strong>software developers who build and deploy applications</strong>.</p>
<p>Before diving into each device, let’s first look at how the internet actually reaches your system.</p>
<hr />
<h2>How the Internet Reaches Your Home or Office</h2>
<p>When you connect to the internet, your data flows through several networking devices before reaching your computer or phone.</p>
<p>A simplified version of that flow looks like this:</p>
<pre><code class="language-javascript">Internet → Modem → Router → Switch → Devices
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/fe09385f-598c-48f1-92de-17ddab0d38eb.png" alt="" style="display:block;margin:0 auto" />

<p>Here’s what happens step by step:</p>
<ol>
<li><p>The internet signal arrives from your ISP (Internet Service Provider).</p>
</li>
<li><p>The modem translates the signal into a form your local network can use.</p>
</li>
<li><p>The router decides where traffic should go.</p>
</li>
<li><p>A switch connects multiple devices inside the network.</p>
</li>
<li><p>Your computer, phone, or server receives the data.</p>
</li>
</ol>
<p>In larger systems, devices like firewalls and load balancers are added for security and scalability.</p>
<p>Let’s explore each device one by one.</p>
<hr />
<h2>What Is a Modem?</h2>
<p>A modem is the device that connects your local network to your Internet Service Provider (ISP).</p>
<p>The word <em>modem</em> comes from modulator-demodulator. Its job is to convert signals so that your devices can communicate with the internet.</p>
<h3>Simple Responsibility</h3>
<p>A modem’s main job is:</p>
<blockquote>
<p><strong>Translate signals between your ISP and your local network.</strong></p>
</blockquote>
<h3>Real-World Analogy</h3>
<p>Think of a modem like a <strong>language translator</strong>.</p>
<ul>
<li><p>Your ISP speaks one “language”</p>
</li>
<li><p>Your home network speaks another</p>
</li>
</ul>
<p>The modem translates between the two so communication is possible.</p>
<h3>Example Setup</h3>
<pre><code class="language-javascript">Internet line from ISP → Modem → Local network
</code></pre>
<p>Without a modem, your home network cannot directly communicate with the internet.</p>
<hr />
<h2>What Is a Router?</h2>
<p>Once the modem brings the internet into your network, something needs to decide where the data should go.</p>
<p>That device is the router.</p>
<p>A router connects multiple networks and directs traffic between them.</p>
<h3>Simple Responsibility</h3>
<blockquote>
<p><strong>A router decides where incoming and outgoing network traffic should go.</strong></p>
</blockquote>
<h3>Real-World Analogy</h3>
<p>Think of a router like a traffic police officer at an intersection.</p>
<p>It looks at incoming traffic and decides which direction each packet should take.</p>
<h3>Example</h3>
<p>When you open a website:</p>
<ol>
<li><p>Your laptop sends a request</p>
</li>
<li><p>The router forwards that request to the internet</p>
</li>
<li><p>The response returns</p>
</li>
<li><p>The router sends it back to the correct device</p>
</li>
</ol>
<p>Routers are essential because many devices share one internet connection.</p>
<hr />
<h2>Switch vs Hub: How Local Networks Work</h2>
<p>Inside an office or data center, many devices must communicate with each other.</p>
<p>Two devices historically used for this purpose are hubs and switches.</p>
<hr />
<h2>What Is a Hub?</h2>
<p>A hub is a very basic networking device.</p>
<p>When a hub receives data from one device, it sends that data to every device connected to it.</p>
<p>Example</p>
<p>If Device A sends data to other devices:</p>
<pre><code class="language-javascript">Hub → Broadcast to Device B, C, D, E
</code></pre>
<p>Every device receives the packet, even if it isn’t meant for them.</p>
<h3>Problem</h3>
<p>This causes:</p>
<ul>
<li><p>unnecessary network traffic</p>
</li>
<li><p>slower performance</p>
</li>
</ul>
<hr />
<h2>What Is a Switch?</h2>
<p>A switch is a smarter version of a hub.</p>
<p>Instead of broadcasting to every device, a switch sends the data only to the intended recipient.</p>
<p>Example</p>
<pre><code class="language-javascript">Device A → Switch → Device C
</code></pre>
<p>Only Device C receives the packet.</p>
<h3>Real-World Analogy</h3>
<ul>
<li><p><strong>Hub:</strong> Shouting a message in a crowded room</p>
</li>
<li><p><strong>Switch:</strong> Sending a direct message to the right person</p>
</li>
</ul>
<p>Because of this efficiency, modern networks almost always use switches instead of hubs.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/02c851fd-8742-454a-8be0-71918893b3b8.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>What Is a Firewall?</h2>
<p>Once your network is connected to the internet, security becomes extremely important.</p>
<p>This is where firewalls come in.</p>
<p>A firewall acts as a security gate between your internal network and the outside world.</p>
<h3>Simple Responsibility</h3>
<blockquote>
<p><strong>A firewall monitors and filters incoming and outgoing traffic.</strong></p>
</blockquote>
<p>It decides which traffic is allowed and which should be blocked.</p>
<h3>Real-World Analogy</h3>
<p>Think of a firewall as a <strong>security guard at a building entrance</strong>.</p>
<p>It checks:</p>
<ul>
<li><p>who is allowed in</p>
</li>
<li><p>who must be stopped</p>
</li>
</ul>
<h3>Example Rules</h3>
<p>A firewall might allow:</p>
<ul>
<li><p>HTTP traffic (port 80)</p>
</li>
<li><p>HTTPS traffic (port 443)</p>
</li>
</ul>
<p>But block:</p>
<ul>
<li><p>suspicious IP addresses</p>
</li>
<li><p>unauthorized access attempts</p>
</li>
</ul>
<p>In production systems, firewalls are critical for protecting servers and sensitive data.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/2b643141-733b-486b-ae60-03999b1b9e7f.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>What Is a Load Balancer?</h2>
<p>When a website becomes popular, a single server may not be able to handle all incoming traffic.</p>
<p>To solve this problem, systems use a <strong>load balancer</strong>.</p>
<h3>Simple Responsibility</h3>
<blockquote>
<p><strong>A load balancer distributes incoming traffic across multiple servers.</strong></p>
</blockquote>
<p>Instead of sending all requests to one server, the load balancer spreads them evenly.</p>
<h3>Real-World Analogy</h3>
<p>Imagine a toll booth with multiple lanes.</p>
<p>Instead of forcing every car into one lane, traffic is divided so cars move faster.</p>
<h3>Example</h3>
<pre><code class="language-javascript">User Request → Load Balancer
                ↓
        Server 1   Server 2   Server 3
</code></pre>
<p>This improves:</p>
<ul>
<li><p>performance</p>
</li>
<li><p>reliability</p>
</li>
<li><p>scalability</p>
</li>
</ul>
<p>Most large-scale systems (Netflix, Amazon, Google) rely heavily on load balancing.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/ca4f59e7-7b3f-4179-bfdd-1376f0423fb9.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>How These Devices Work Together</h2>
<p>Now let’s look at a simplified real-world network flow.</p>
<pre><code class="language-javascript">Internet
   ↓
Modem
   ↓
Router
   ↓
Firewall
   ↓
Switch
   ↓
Devices / Servers
</code></pre>
<p>For scalable applications:</p>
<pre><code class="language-javascript">Internet
   ↓
Load Balancer
   ↓
Application Servers
   ↓
Database Servers
</code></pre>
<p>Each device has a specific responsibility:</p>
<table>
<thead>
<tr>
<th>Device</th>
<th>Main Role</th>
</tr>
</thead>
<tbody><tr>
<td>Modem</td>
<td>Connects network to ISP</td>
</tr>
<tr>
<td>Router</td>
<td>Directs traffic between networks</td>
</tr>
<tr>
<td>Switch</td>
<td>Connects devices within a network</td>
</tr>
<tr>
<td>Hub</td>
<td>Broadcasts packets to all devices</td>
</tr>
<tr>
<td>Firewall</td>
<td>Protects network security</td>
</tr>
<tr>
<td>Load Balancer</td>
<td>Distributes traffic across servers</td>
</tr>
</tbody></table>
<p>Together, these devices create the foundation of modern networking.</p>
<hr />
<h2>Why This Matters for Software Engineers</h2>
<p>Even if you primarily write code, understanding networking is extremely valuable.</p>
<p>When deploying backend systems, you'll frequently encounter:</p>
<ul>
<li><p><strong>r</strong>everse proxies</p>
</li>
<li><p>load balancers</p>
</li>
<li><p>firewalls</p>
</li>
<li><p>network routing</p>
</li>
</ul>
<p>Cloud platforms like AWS, Azure, and Google Cloud provide virtual versions of these devices.</p>
<p>For example:</p>
<table>
<thead>
<tr>
<th>Hardware Device</th>
<th>Cloud Equivalent</th>
</tr>
</thead>
<tbody><tr>
<td>Router</td>
<td>VPC routing tables</td>
</tr>
<tr>
<td>Firewall</td>
<td>Security groups</td>
</tr>
<tr>
<td>Load Balancer</td>
<td>AWS ELB / ALB</td>
</tr>
<tr>
<td>Switch</td>
<td>Virtual networking</td>
</tr>
</tbody></table>
<p>Knowing how these pieces fit together helps developers:</p>
<ul>
<li><p>design scalable systems</p>
</li>
<li><p>debug networking issues</p>
</li>
<li><p>understand production architecture</p>
</li>
</ul>
<hr />
<h2>Conclusion</h2>
<p>Networking devices form the backbone of how the internet works. From the modem that connects your network to your ISP, to the router directing traffic, to load balancers powering large-scale applications, each device plays a specific role.</p>
<p>Once you understand how these components interact, the infrastructure behind modern applications becomes much easier to visualize.</p>
<p>For developers working with cloud platforms and backend systems, this knowledge provides a strong foundation for building reliable and scalable services.</p>
]]></content:encoded></item><item><title><![CDATA[The Magic of this, call(), apply(), and bind() in JavaScript]]></title><description><![CDATA[If you’ve spent some time learning JavaScript, you’ve probably come across the keyword this and had a thought about what it actually refers to.
Sometimes it points to an object. Sometimes it seems to ]]></description><link>https://blog.rohitchornele.online/the-magic-of-this-call-apply-and-bind-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/the-magic-of-this-call-apply-and-bind-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[call apply and bind methods]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 13:54:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/2db6983b-736b-4fcd-8812-dfdb2a13d4a9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve spent some time learning JavaScript, you’ve probably come across the keyword <code>this</code> and had a thought about what it actually refers to.</p>
<p>Sometimes it points to an object. Sometimes it seems to behave differently depending on how a function is called. This flexibility can feel confusing at first, but the idea behind it is actually simple.</p>
<p>A good way to understand <code>this</code> is to think about who is responsible for running the function.</p>
<p>In many situations, <code>this</code> simply refers to the object that calls the function. Once that idea clicks, the rest of the concepts—like <code>call()</code>, <code>apply()</code>, and <code>bind()</code>, start to make much more sense.</p>
<p>Let’s explore how it works.</p>
<h2>What "this" Means in JavaScript</h2>
<p>In JavaScript, The keyword <code>this</code> refers to the current object that is executing the function.</p>
<blockquote>
<p>Think of it like : “Who is calling this function right now?”</p>
</blockquote>
<p>A simpler way to remember this is:</p>
<blockquote>
<p><code>this</code> usually refers to <strong>the object that called the function</strong>.</p>
</blockquote>
<p>Here’s a simple example.</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

person.greet();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, my name is Alice
</code></pre>
<p>When <code>greet()</code> runs, it is called by the <code>person</code> object:</p>
<ul>
<li><p>The object <code>person</code> called the function</p>
</li>
<li><p>So <code>this</code> refers to person</p>
</li>
</ul>
<h2>"this" Inside Normal Functions</h2>
<p>If a function is being called on it's own, instead of being called through an object, it behaves differently.</p>
<p>In a regular standalone function, <code>this</code> usually refers to the <strong>global object</strong> (or <code>undefined</code> in strict mode).</p>
<p>Example:</p>
<pre><code class="language-javascript">function show() {
  console.log(this);
}

show();
</code></pre>
<p>Here, <code>this</code> does not refer to any specific object because the function was called directly.</p>
<p>This is why <code>this</code> is more useful when working with objects.</p>
<h2>"this" Inside Objects</h2>
<p>Inside objects, <code>this</code> refers to the object that owns the method.</p>
<p>Example:</p>
<pre><code class="language-javascript">let car = {
  brand: "Toyota",
  showBrand: function() {
    console.log(this.brand);
  }
};

car.showBrand();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Toyota
</code></pre>
<p>Here, the <code>showBrand</code> method is called by the <code>car</code> object. That means <code>this</code> points to car, allowing the method to access <code>car.brand</code>.</p>
<blockquote>
<p>this.brand ---&gt; car.brand</p>
</blockquote>
<hr />
<h2>What <code>call()</code> Does</h2>
<p>JavaScript includes methods that allow you to control what <code>this</code> refers to.</p>
<p>One of these is <code>call()</code>.</p>
<p>The <code>call()</code> method allows you to borrow a function from one object and use it with another object.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person1 = {
  name: "Rahul"
};

let person2 = {
  name: "Anita"
};

function greet() {
  console.log("Hello " + this.name);
}

greet.call(person1);
greet.call(person2);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello Rahul
Hello Anita
</code></pre>
<p>Here, the same function is used with different objects. <code>call()</code> temporarily assigns the object as the context for <code>this</code>.</p>
<p><code>call()</code> lets us manually choose what <code>this</code> should refer to.</p>
<h2>What <code>apply()</code> Does</h2>
<p>The <code>apply()</code> method works almost the same way as <code>call()</code>, but there is one small difference in how arguments are passed.</p>
<p>With <code>apply()</code>, arguments are provided inside an <strong>array</strong>.</p>
<p>Example:</p>
<pre><code class="language-javascript">function introduce(city, country) {
  console.log(this.name + " lives in " + city + ", " + country);
}

let person = {
  name: "Rahul"
};

introduce.apply(person, ["Delhi", "India"]);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Rahul lives in Delhi, India
</code></pre>
<p>So while both methods allow you to set <code>this</code>, the only real difference is how the arguments are passed.</p>
<pre><code class="language-plaintext">call() → arguments passed separately
apply() → arguments passed as an array
</code></pre>
<h2>What <code>bind()</code> Does</h2>
<p>Unlike <code>call()</code> and <code>apply()</code>, the <code>bind()</code> method does not immediately run the function.</p>
<p>Instead, it creates a new function where <code>this</code> is permanently set to a specific object.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Rahul"
};

function greet() {
  console.log("Hello " + this.name);
}

let greetUser = greet.bind(person);

greetUser();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello Rahul
</code></pre>
<p>In this case, <code>bind()</code> produces a new function that always treats <code>person</code> as <code>this</code>, no matter where the function is used later.</p>
<h2>Difference Between <code>call()</code>, <code>apply()</code>, and <code>bind()</code></h2>
<p>These three methods are closely related but serve slightly different purposes.</p>
<table>
<thead>
<tr>
<th>Method</th>
<th>Behavior</th>
<th>Arguments</th>
</tr>
</thead>
<tbody><tr>
<td>call()</td>
<td>Runs the function immediately</td>
<td>Arguments passed individually</td>
</tr>
<tr>
<td>apply()</td>
<td>Runs the function immediately</td>
<td>Arguments passed as an array</td>
</tr>
<tr>
<td>bind()</td>
<td>Returns a new function</td>
<td>Arguments provided later</td>
</tr>
</tbody></table>
<p>Example comparison:</p>
<pre><code class="language-javascript">func.call(obj, arg1, arg2);

func.apply(obj, [arg1, arg2]);

let newFunc = func.bind(obj);
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Understanding Object-Oriented Programming in JavaScript]]></title><description><![CDATA[Imagine a car company designing a new car model.
Before building thousands of cars, engineers first create a blueprint. That blueprint describes what every car should have — things like wheels, engine]]></description><link>https://blog.rohitchornele.online/understanding-object-oriented-programming-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/understanding-object-oriented-programming-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[chai-code ]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[oop]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 11:37:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/14c584f4-8dc6-4128-bb3b-49057b26bf71.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine a car company designing a new car model.</p>
<p>Before building thousands of cars, engineers first create a blueprint. That blueprint describes what every car should have — things like wheels, engine, color, and seats.</p>
<p>Once the blueprint is ready, the factory can produce many cars using that same design.</p>
<p>Programming works in a very similar way.</p>
<p>Instead of repeatedly writing the same structure for similar objects, developers create a blueprint in code. This blueprint is called a class, and the things created from it are called objects.</p>
<p>This concept is part of a programming approach known as Object-Oriented Programming, often shortened to OOP.</p>
<h2>What Object-Oriented Programming (OOP) Means</h2>
<p>Object-Oriented Programming is a style of writing code where we organize programs using objects.</p>
<p>An object represents something from the real world and usually contains:</p>
<ul>
<li><p>Properties --&gt; information about the object</p>
</li>
<li><p>Methods --&gt; actions the object can perform</p>
</li>
</ul>
<p>For example, think about a student.</p>
<p>A student object might contain properties like:</p>
<pre><code class="language-javascript">name
age
course
</code></pre>
<p>And it might have actions like:</p>
<pre><code class="language-javascript">printDetails()
</code></pre>
<p>Using OOP helps developers:</p>
<ul>
<li><p>organize code more clearly</p>
</li>
<li><p>reuse the same structure multiple times</p>
</li>
<li><p>make programs easier to maintain and expand</p>
</li>
</ul>
<h2>Real-World Analogy: Blueprint --&gt; Objects</h2>
<p>Let's revisit the car blueprint example.</p>
<p>A blueprint describes how a car should look and behave.</p>
<p>Using that blueprint, a factory can create many cars:</p>
<pre><code class="language-javascript">Blueprint --&gt; Car 1
Blueprint --&gt; Car 2
Blueprint --&gt; Car 3
</code></pre>
<p>In programming:</p>
<pre><code class="language-javascript">Class --&gt; Blueprint
Object --&gt; Actual item created from the blueprint
</code></pre>
<p>So a <strong>class defines the structure</strong>, and <strong>objects are the real instances created from it</strong>.</p>
<h2>What Is a Class in JavaScript?</h2>
<p>In JavaScript, a class is used to define the structure of objects.</p>
<p>It describes what properties and methods objects created from it should have.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Person {

}
</code></pre>
<p>This class doesn't do anything yet, but it serves as a template for creating person objects.</p>
<h2>Creating Objects Using Classes</h2>
<p>Once a class exists, we can create objects using the <code>new</code> keyword.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person1 = new Person();
</code></pre>
<p>Here:</p>
<pre><code class="language-javascript">Person --&gt; class
person1 --&gt; object
</code></pre>
<p>We can create multiple objects from the same class:</p>
<pre><code class="language-javascript">let person2 = new Person();
let person3 = new Person();
</code></pre>
<p>This demonstrates one of the main benefits of OOP: <strong>code reusability</strong>.</p>
<h2>The Constructor Method</h2>
<p>When creating objects, we usually want to give them initial values.</p>
<p>That’s where the constructor method comes in.</p>
<p>The constructor runs automatically whenever a new object is created.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Person {

  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

}
</code></pre>
<p>Explanation:</p>
<ul>
<li><p><code>this.name</code> refers to the object's name property</p>
</li>
<li><p><code>this.age</code> refers to the object's age property</p>
</li>
</ul>
<p>Now we can create objects with data:</p>
<pre><code class="language-javascript">let person1 = new Person("Alice", 25);
let person2 = new Person("David", 30);
</code></pre>
<p>Each object now contains its own values.</p>
<h2>Methods Inside a Class</h2>
<p>Classes can also contain methods, which are functions that belong to the object.</p>
<p>Methods allow objects to perform actions.</p>
<p>Example:</p>
<pre><code class="language-javascript">class Person {

  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log("Hello, my name is " + this.name);
  }

}
</code></pre>
<p>Now we can create an object and call the method:</p>
<pre><code class="language-javascript">let person1 = new Person("Alice", 25);

person1.greet();
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, my name is Alice
</code></pre>
<p>Methods help objects perform behaviors related to their data.</p>
<h2>Basic Idea of Encapsulation</h2>
<p>Encapsulation is a concept where data and related functions are kept together inside a class.</p>
<p>For example, a Student class might contain:</p>
<ul>
<li><p>student name</p>
</li>
<li><p>student age</p>
</li>
<li><p>a method that prints student details</p>
</li>
</ul>
<p>Instead of managing these pieces separately in different parts of the code, everything stays inside the class structure.</p>
<p>This approach makes programs:</p>
<ul>
<li><p>easier to understand</p>
</li>
<li><p>easier to maintain</p>
</li>
<li><p>easier to reuse</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding Objects in JavaScript]]></title><description><![CDATA[Imagine you are building a small application that stores information about a student.
You might need details like: name, age, course, city.
One way to store this information is by using separate varia]]></description><link>https://blog.rohitchornele.online/understanding-objects-in-javascript</link><guid isPermaLink="true">https://blog.rohitchornele.online/understanding-objects-in-javascript</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Objects]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 11:21:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/57588b19-b0f7-4241-8020-8d3a8221a2ea.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine you are building a small application that stores information about a student.</p>
<p>You might need details like: name, age, course, city.</p>
<p>One way to store this information is by using separate variables:</p>
<pre><code class="language-javascript">let name = "Rahul";
let age = 21;
let course = "Computer Science";
</code></pre>
<p>This works for small examples, but things get messy very quickly when you start working with many students or more properties.</p>
<p>Instead of scattering related data across multiple variables, JavaScript gives us a much better way to organize it.</p>
<p>That solution is called an object.</p>
<p>Objects allow us to group related information together in a single structure, making our code easier to read and manage.</p>
<h2>What Are Objects and Why Are They Needed?</h2>
<p>An object is simply a collection of key–value pairs.</p>
<p>You can think of it like a profile card or form where each field has a label and a value.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "John",
  age: 25,
  city: "New York"
};
</code></pre>
<p>Here:</p>
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody><tr>
<td>name</td>
<td>"John"</td>
</tr>
<tr>
<td>age</td>
<td>25</td>
</tr>
<tr>
<td>city</td>
<td>"New York"</td>
</tr>
</tbody></table>
<p>Each piece of information is stored as:</p>
<pre><code class="language-plaintext">key : value
</code></pre>
<p>Objects make it easy to group related data together instead of spreading it across many variables.</p>
<h2>Array vs Object</h2>
<p>At this point, beginners often wonder:</p>
<p>When should I use an array and when should I use an object?</p>
<p>The difference is simple.</p>
<p>Arrays store ordered lists :</p>
<pre><code class="language-javascript">let fruits = ["Apple", "Banana", "Mango"];
</code></pre>
<p>You access values using indexes.</p>
<pre><code class="language-javascript">console.log(fruits[0]);
</code></pre>
<p>Objects store labeled information</p>
<pre><code class="language-javascript">let person = {
  name: "John",
  age: 25
};
</code></pre>
<p>You access values using keys.</p>
<pre><code class="language-javascript">console.log(person.name);
</code></pre>
<p>A good rule of thumb:</p>
<ul>
<li><p>Use arrays for lists</p>
</li>
<li><p>Use objects for structured data</p>
</li>
</ul>
<h2>Creating Objects</h2>
<p>Creating an object in JavaScript is straightforward.</p>
<p>We use curly braces <code>{ }</code> and define properties inside.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28,
  city: "London"
};
</code></pre>
<p>Each property follows the format:</p>
<pre><code class="language-plaintext">key : value
</code></pre>
<p>Multiple properties are separated by commas.</p>
<p>This structure makes objects easy to read and understand.</p>
<h2>Accessing Object Properties</h2>
<p>Once an object is created, the next step is accessing the information inside it.</p>
<p>JavaScript provides two common ways to do this.</p>
<h3>Dot Notation :</h3>
<p>This is the most common and readable method.</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28
};

console.log(person.name);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Alice
</code></pre>
<p>Here we are directly accessing the name property of the object.</p>
<h3>Bracket Notation :</h3>
<p>Another way to access properties is by using square brackets.</p>
<pre><code class="language-javascript">console.log(person["age"]);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">28
</code></pre>
<p>Bracket notation becomes useful when the property name is stored inside a variable.</p>
<p>Example:</p>
<pre><code class="language-javascript">let key = "name";

console.log(person[key]);
</code></pre>
<h2>Updating Object Properties</h2>
<p>Objects are not fixed — their values can change.</p>
<p>If you want to update a property, simply assign a new value.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28
};

person.age = 30;

console.log(person.age);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">30
</code></pre>
<p>This flexibility makes objects very practical when working with dynamic data.</p>
<h2>Adding New Properties</h2>
<p>Another useful feature of objects is that new properties can be added at any time.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28
};

person.city = "London";

console.log(person);
</code></pre>
<p>Result:</p>
<pre><code class="language-plaintext">{
  name: "Alice",
  age: 28,
  city: "London"
}
</code></pre>
<p>This makes objects highly adaptable when your program grows.</p>
<h2>Deleting Properties</h2>
<p>If a property is no longer needed, it can be removed using the delete keyword.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28,
  city: "London"
};

delete person.city;

console.log(person);
</code></pre>
<p>Result:</p>
<pre><code class="language-plaintext">{
  name: "Alice",
  age: 28
}
</code></pre>
<h2>Looping Through Object Keys</h2>
<p>Often you will want to go through every property in an object.</p>
<p>JavaScript provides a convenient loop called for...in.</p>
<p>Example:</p>
<pre><code class="language-javascript">let person = {
  name: "Alice",
  age: 28,
  city: "London"
};

for (let key in person) {
  console.log(key, person[key]);
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">name Alice
age 28
city London
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>key</code> represents each property name</p>
</li>
<li><p><code>person[key]</code> gives the corresponding value</p>
</li>
</ul>
<p>This loop is useful when you want to inspect or process all properties in an object.</p>
]]></content:encoded></item><item><title><![CDATA[Control Flow in JavaScript: If, Else, and Switch Explained]]></title><description><![CDATA[When writing programs, we often need the computer to make decisions.
For example:

If it is raining → take an umbrella

If a student scores above 40 → they pass

If today is Sunday → take a holiday


]]></description><link>https://blog.rohitchornele.online/control-flow-in-javascript-if-else-and-switch-explained</link><guid isPermaLink="true">https://blog.rohitchornele.online/control-flow-in-javascript-if-else-and-switch-explained</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[control flow]]></category><category><![CDATA[chai-code ]]></category><dc:creator><![CDATA[Rohit Chornele]]></dc:creator><pubDate>Fri, 13 Mar 2026 11:02:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6688fdd59dfed4afe8f5b269/7ce3af0c-2e87-4a9e-ad1a-a9f96a0c5482.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When writing programs, we often need the computer to make decisions.</p>
<p>For example:</p>
<ul>
<li><p>If it is raining → take an umbrella</p>
</li>
<li><p>If a student scores above 40 → they pass</p>
</li>
<li><p>If today is Sunday → take a holiday</p>
</li>
</ul>
<p>This type of decision-making in programming is called control flow.</p>
<p>Control flow allows our program to choose which code should run based on conditions.</p>
<p>In JavaScript, the most common control flow tools are:</p>
<ul>
<li><p><code>if</code></p>
</li>
<li><p><code>if-else</code></p>
</li>
<li><p><code>else if</code></p>
</li>
<li><p><code>switch</code></p>
</li>
</ul>
<p>Let’s understand how each one works.</p>
<h2>What Control Flow Means in Programming</h2>
<p>Control flow determines the order in which statements are executed in a program.</p>
<p>Normally, code runs line by line from top to bottom.</p>
<p>Example:</p>
<pre><code class="language-javascript">let number = 5;

console.log("Start");
console.log(number);
console.log("End");
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Start
5
End
</code></pre>
<p>But sometimes we want the program to run code only when a condition is true.</p>
<p>That’s where control flow statements come in.</p>
<h2>The if Statement</h2>
<p>The <code>if</code> statement runs a block of code only if a condition is true.</p>
<p>Syntax :</p>
<pre><code class="language-javascript">if (condition) {
  // code runs if condition is true
}
</code></pre>
<p>Example: Checking Age</p>
<pre><code class="language-javascript">let age = 20;

if (age &gt;= 18) {
  console.log("You are eligible to vote.");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">You are eligible to vote.
</code></pre>
<p>Step by step:</p>
<ol>
<li><p>JavaScript checks the condition <code>age &gt;= 18</code></p>
</li>
<li><p>If it is true, the code inside <code>{}</code> runs</p>
</li>
<li><p>If it is false, nothing happens</p>
</li>
</ol>
<hr />
<h2>The if-else Statement</h2>
<p>Sometimes we want two possible outcomes.</p>
<p>Example:</p>
<ul>
<li><p>If a student passes → show "Passed"</p>
</li>
<li><p>Otherwise → show "Failed"</p>
</li>
</ul>
<p>We use <code>if-else</code>.</p>
<p>Syntax :</p>
<pre><code class="language-javascript">if (condition) {
  // runs if true
} else {
  // runs if false
}
</code></pre>
<p>Example: Pass or Fail</p>
<pre><code class="language-javascript">let marks = 35;

if (marks &gt;= 40) {
  console.log("You passed the exam.");
} else {
  console.log("You failed the exam.");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">You failed the exam.
</code></pre>
<h2>The else if Ladder</h2>
<p>Sometimes we need multiple conditions, not just two.</p>
<p>Example:</p>
<ul>
<li><p>Marks above 90 → Grade A</p>
</li>
<li><p>Marks above 75 → Grade B</p>
</li>
<li><p>Marks above 50 → Grade C</p>
</li>
<li><p>Otherwise → Fail</p>
</li>
</ul>
<p>For this we use else if.</p>
<p>Syntax</p>
<pre><code class="language-javascript">if (condition1) {
}
else if (condition2) {
}
else if (condition3) {
}
else {
}
</code></pre>
<hr />
<p>Example: Student Grades</p>
<pre><code class="language-javascript">let marks = 82;

if (marks &gt;= 90) {
  console.log("Grade A");
}
else if (marks &gt;= 75) {
  console.log("Grade B");
}
else if (marks &gt;= 50) {
  console.log("Grade C");
}
else {
  console.log("Fail");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Grade B
</code></pre>
<p>Step by step:</p>
<ol>
<li><p>Check first condition</p>
</li>
<li><p>If false → check next</p>
</li>
<li><p>Continue until one is true</p>
</li>
</ol>
<p>Only <strong>one block runs</strong>.</p>
<h2>The switch Statement</h2>
<p>The <code>switch</code> statement is another way to make decisions when comparing one value against many options.</p>
<p>It works well when you have many fixed cases.</p>
<p>Syntax</p>
<pre><code class="language-javascript">switch (value) {
  case option1:
    // code
    break;

  case option2:
    // code
    break;

  default:
    // code
}
</code></pre>
<p>Example: Day of the Week</p>
<pre><code class="language-javascript">let day = 3;

switch(day) {
  case 1:
    console.log("Monday");
    break;

  case 2:
    console.log("Tuesday");
    break;

  case 3:
    console.log("Wednesday");
    break;

  case 4:
    console.log("Thursday");
    break;

  case 5:
    console.log("Friday");
    break;

  case 6:
    console.log("Saturday");
    break;

  case 7:
    console.log("Sunday");
    break;

  default:
    console.log("Invalid day");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Wednesday
</code></pre>
<hr />
<h2>Why break Is Important in switch</h2>
<p>The <code>break</code> statement stops the switch from continuing to the next case.</p>
<p>Without <code>break</code>, JavaScript continues executing the next cases.</p>
<p>Example without break:</p>
<pre><code class="language-javascript">let day = 1;

switch(day) {
  case 1:
    console.log("Monday");
  case 2:
    console.log("Tuesday");
}
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Monday
Tuesday
</code></pre>
<p>Because there was no break, both cases ran.</p>
<p>So remember:</p>
<pre><code class="language-plaintext">Always use break in switch cases
</code></pre>
<h2>When to Use switch vs if-else</h2>
<p>Both are useful, but they work best in different situations.</p>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Best Choice</th>
</tr>
</thead>
<tbody><tr>
<td>Range comparisons (marks, age)</td>
<td>if / else if</td>
</tr>
<tr>
<td>Many exact values</td>
<td>switch</td>
</tr>
<tr>
<td>Complex conditions</td>
<td>if-else</td>
</tr>
<tr>
<td>Fixed menu options</td>
<td>switch</td>
</tr>
</tbody></table>
<p>Example:</p>
<p>Checking marks range → use <code>if-else</code></p>
<p>Checking day number → use <code>switch</code></p>
]]></content:encoded></item></channel></rss>