<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sunil Chaudhary</title>
    <description>The latest articles on Forem by Sunil Chaudhary (@sunil12738).</description>
    <link>https://forem.com/sunil12738</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F448265%2F60394363-a28d-46cd-b2ef-d22458b052c9.jpeg</url>
      <title>Forem: Sunil Chaudhary</title>
      <link>https://forem.com/sunil12738</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sunil12738"/>
    <language>en</language>
    <item>
      <title>The Art of Parallelization: Why Your Features Take 13 Weeks Instead of 4</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Thu, 04 Dec 2025 13:00:00 +0000</pubDate>
      <link>https://forem.com/sunil12738/the-art-of-parallelization-why-your-features-take-13-weeks-instead-of-4-4n9h</link>
      <guid>https://forem.com/sunil12738/the-art-of-parallelization-why-your-features-take-13-weeks-instead-of-4-4n9h</guid>
      <description>&lt;p&gt;&lt;strong&gt;What to expect in this article&lt;/strong&gt;: This article tackles a pervasive frustration in software delivery: the "Sequential Trap." It argues that one of the biggest bottleneck isn't code execution speed but the organizational friction of handing work off between siloed teams (QA, Security, SRE) in a strictly linear fashion. After reading this article, you should be able to shifts the focus from efficiency (&lt;em&gt;writing code faster&lt;/em&gt;) to efficacy (&lt;em&gt;shipping value faster&lt;/em&gt;).&lt;/p&gt;




&lt;p&gt;As developers, we're obsessed with optimizing our code. We'll spend hours refactoring a function to make it run 50ms faster. Yet, we often ignore the single biggest bottleneck in our process: &lt;strong&gt;The Sequential Handoff compounded by sprint planning&lt;/strong&gt;. I've seen it countless times. A developer finishes a feature, tosses the ticket over to the QA column, and moves on. They've feel they have done their job. But the feature is nowhere near "done." It has just entered a void. It's sitting in a queue, waiting for QA's next sprint planning meeting. The feature languishes in a series of queues, slowly moving from team to team.&lt;/p&gt;

&lt;p&gt;This isn't a process; it's a relay race where each runner decides to start the race two weeks after the baton is handed to them. &lt;strong&gt;This is the Sequential Trap&lt;/strong&gt;, and it's how simple features take an entire quarter to ship.&lt;/p&gt;

&lt;p&gt;What if that "simple" feature could get to production 100% faster, not by coding faster, but by thinking differently?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This isn't a fantasy. It's a skill I call strategic parallelization.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Sequential Trap": A 13-Week Tragedy
&lt;/h2&gt;

&lt;p&gt;Let's look at a common, and painfully slow, delivery process for a single feature. We'll be generous and assume each team's actual work only takes one week. But, we'll add the realistic constraint that each team runs a 2-week sprint and won't pick up unplanned work.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Week&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Development&lt;/td&gt;
&lt;td&gt;The feature is coded. At the end of the week, the ticket is handed to QA.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2, 3&lt;/td&gt;
&lt;td&gt;QA "Planning Gap"&lt;/td&gt;
&lt;td&gt;The QA team's current sprint is already full. The ticket sits in their backlog, "Ready for Planning."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;QA Sprint&lt;/td&gt;
&lt;td&gt;The ticket is finally planned and executed. At the end of the week, it's handed to AppSec.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5, 6&lt;/td&gt;
&lt;td&gt;AppSec "Planning Gap"&lt;/td&gt;
&lt;td&gt;The AppSec team is in the middle of their sprint. The ticket sits in their backlog.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;AppSec Sprint&lt;/td&gt;
&lt;td&gt;The ticket is planned and reviewed. At the end of the week, it's handed to InfoSec.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8, 9&lt;/td&gt;
&lt;td&gt;InfoSec "Planning Gap"&lt;/td&gt;
&lt;td&gt;... (you see the pattern) ...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;InfoSec Sprint&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11, 12&lt;/td&gt;
&lt;td&gt;SRE "Planning Gap"&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;SRE Sprint&lt;/td&gt;
&lt;td&gt;Infrastructure changes are made.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Live! (Finally)&lt;/p&gt;

&lt;p&gt;Total Time: 13 weeks (~ 1 Quarter).&lt;/p&gt;

&lt;p&gt;The problem isn't just the 13 weeks. It's the waste. While the feature sits in the AppSec queue, the QA team has moved on. By the time SRE gets it, the original developer is deep in another project and has lost all context.&lt;/p&gt;

&lt;p&gt;This is a 13-week process for what was probably 4 weeks of actual work. We've spent almost two months (9 weeks) just waiting in queues. This is invisible, soul-crushing waste.&lt;/p&gt;

&lt;p&gt;This model is lazy, expensive, and slow.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Parallel Mindset: A 4-Week Reality
&lt;/h2&gt;

&lt;p&gt;Now, let's re-run that same feature, but this time, the tech lead acts as an orchestrator, not just a coder. The lead's first step is dependency mapping. "What truly blocks what?"&lt;/p&gt;

&lt;h3&gt;
  
  
  Development:
&lt;/h3&gt;

&lt;p&gt;This is the root dependency. Nothing can be fully tested or reviewed until the code exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Review Block:
&lt;/h3&gt;

&lt;p&gt;QA, AppSec, and InfoSec can all maybe review the same final code parallely. They are not dependent on each other.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does AppSec, InfoSec need to wait for QA? Maybe / Maybe Not.&lt;/li&gt;
&lt;li&gt;Does AppSec need to wait for InfoSec? No.&lt;/li&gt;
&lt;li&gt;Does SRE need to wait for InfoSec or AppSec? No.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Release Block:
&lt;/h3&gt;

&lt;p&gt;SRE needs the approvals from all three review teams.&lt;/p&gt;

&lt;p&gt;By identifying this, we can re-plan the entire flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Optimized Plan
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Week 1: Development &amp;amp; Proactive Planning
&lt;/h3&gt;

&lt;p&gt;The dev team codes the feature.&lt;/p&gt;

&lt;p&gt;Parallel Action (The Magic Step): On Day 1 of this week, the tech lead contacts the leads for QA, AppSec, InfoSec, and SRE.&lt;/p&gt;

&lt;p&gt;The Message: "We are starting work on Feature X today. The code will be ready for review by the end of this week. Please reserve capacity in your next sprint (which starts Week 2) for this."&lt;/p&gt;

&lt;h3&gt;
  
  
  Week 2: The QA testing Sprint
&lt;/h3&gt;

&lt;p&gt;The code is merged to a staging/test environment. Because QA teams knows in advance, they can pull the feature into their current sprint and work on it at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Week 3: The parallelization track
&lt;/h3&gt;

&lt;p&gt;Because AppSec and InfoSec teams knows in advance, they can pull the feature into their current sprint and work on it at the same time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Workstream 1: AppSec begins its security review (code scans, logic review).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Workstream 2: InfoSec begins its compliance review.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Week 4: Integration &amp;amp; Release Sprint
&lt;/h3&gt;

&lt;p&gt;Feedback from all the teams comes in (e.g., end of Week 2 / start of Week 3). The dev team makes any required fixes if needed (e.g., a bug from QA, a vulnerability from AppSec). If not, feature can be handed over to SRE. The SRE team (who was also informed in Week 1) has the "Release Feature X" task in their Week 4 sprint. Once the approvals are all green, they execute the release.&lt;/p&gt;

&lt;p&gt;Total Time: 4 weeks.&lt;/p&gt;

&lt;p&gt;We didn't just save 9 weeks. We eliminated the "Planning Gaps" and converted a linear long review process (QA + AppSec + InfoSec) into a parallel process.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Playbook: How to Do It
&lt;/h2&gt;

&lt;p&gt;This shift doesn't just "happen." It requires a different kind of mindset focused on project flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deconstruct at the Start:
&lt;/h3&gt;

&lt;p&gt;Before writing a single line of code, break the feature down. Identify all the "non-dev" tasks: documentation, QA test plans, security reviews, infrastructure needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Map the Critical Path:
&lt;/h3&gt;

&lt;p&gt;Ask the hard questions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Can we write the QA test plan while the code is being written?" (Yes). &lt;/li&gt;
&lt;li&gt;"Can the security team review the design before the code is finished?" (Yes). &lt;/li&gt;
&lt;li&gt;"Can SRE provision the new database before the code is merged?" (Yes). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Identify the longest unbreakable chain of tasks—that's your critical path. Everything else should be moved off it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communicate Proactively (and Beat the Sprint Cycle):
&lt;/h3&gt;

&lt;p&gt;This is the most critical step. Do not use tickets as your primary communication. The moment a developer throws a "done" ticket over the wall is the moment you've already lost 1-2 weeks. Sending a "heads-up" email or Slack message two weeks before you file the ticket is the magic trick. It allows other teams to manage their backlogs and "book" time for you. Your goal is to get your feature into the next sprint of all dependent teams. You transform from an interruption into a predictable partner.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pros and Cons of Parallelism
&lt;/h2&gt;

&lt;p&gt;This approach is powerful, but it's not "free." It trades one kind of work for another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Massive Reduction in Lead Time: This is the obvious win (13 weeks vs. 4). Features get to customers faster, which is the ultimate business goal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased Team Throughput: You can ship more features per quarter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Earlier Risk Discovery: If AppSec finds a fundamental design flaw, you find out in Week 3, not Week 7. This saves enormous amounts of rework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Higher Engagement: Other teams are treated as partners, not as gates. They are involved early, feel respected, and can plan their own work effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Fail Fast" for Architecture: In the sequential model, if InfoSec rejects a fundamental architectural decision in Week 10, you have wasted 10 weeks of Dev and QA effort. In the parallel model, InfoSec reviews the design/code in Week 3. If there is a show-stopping compliance issue, you catch it immediately, preventing weeks of wasted effort on a feature that was never going to be approved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context Retention (The Efficiency Multiplier): When a developer fixes a bug 9 weeks after writing the code, they spend 50% of their time just re-reading their own code to remember how it works. By compressing the feedback loop into 3 weeks, the code remains fresh in the developer's mind, making fixes significantly faster and higher quality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved Stakeholder Trust: Strategic parallelization turns delivery into a predictable, scheduled event. Being able to say, "We have booked the Security and SRE slots for Week 3 and 4," sounds far more professional and reliable than "We will send it to Security when we are done."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Higher Communication Overhead: You (or the tech lead) must spend more time planning, coordinating, and communicating. You can't just put your head down and code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased Management Complexity: You're a circus ringleader juggling multiple acts. If the QA stream finds a blocker, you have to communicate that to the other parallel streams ("Pause your review, a new build is coming").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Risk of Wasted "Pre-Work": If SRE provisions a new server and the feature is then canceled or fails its AppSec review, that work was wasted. (This is a small, manageable risk that is usually outweighed by the time savings).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The "Context Switching" Tax: For the downstream teams (like AppSec), being booked "tentatively" can be annoying if the Dev team slips their deadline. If Dev is late by 3 days, they miss the reservation window in the AppSec sprint, potentially causing similar chaos like sequential model.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: The Code is Only 20% of the Delivery
&lt;/h2&gt;

&lt;p&gt;The "Art of Parallelization" ultimately teaches us one harsh truth: Writing the code is often the fastest part of software development. The real challenge—and the real time-sink—lies in the spaces between the code.&lt;/p&gt;

&lt;p&gt;If we treat development as a linear assembly line, we are destined for the "Sequential Trap." We surrender our timelines to the mercy of other teams' backlogs and sprint cycles, watching helplessly as a 5-day coding task turns into a 9-week waiting game.&lt;/p&gt;

&lt;p&gt;True parallelization isn't about working harder; it's about working wider. It requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualizing the hidden queues before they happen.&lt;/li&gt;
&lt;li&gt;Respecting the planning cycles of your partner teams (QA, Sec, SRE) by alerting them early.&lt;/li&gt;
&lt;li&gt;Orchestrating concurrency so that while one team is working, no one else is waiting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next time you are assigned a feature, look beyond your IDE. Don't just plan your code; plan your dependencies. By mastering this art, you stop being a developer who just "finishes tickets" and become a developer who delivers value.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Off course there is some exaggeration in the post, but you get the gist and understood the art of strategic parallelization which many devs fail to understand)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(co-author: Google Gemini Pro)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>development</category>
      <category>planning</category>
      <category>delivery</category>
    </item>
    <item>
      <title>The CSS Casing Wars: A Survivor's Tale.</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Mon, 06 Oct 2025 12:38:51 +0000</pubDate>
      <link>https://forem.com/sunil12738/the-css-casing-wars-a-survivors-tale-1kb0</link>
      <guid>https://forem.com/sunil12738/the-css-casing-wars-a-survivors-tale-1kb0</guid>
      <description>&lt;h5&gt;
  
  
  Table of contents:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The CSS Casing Chaos: My Beef with CSS Casing&lt;/li&gt;
&lt;li&gt;The Usual Suspects&lt;/li&gt;
&lt;li&gt;Examples&lt;/li&gt;
&lt;li&gt;How Did We Let This Happen?&lt;/li&gt;
&lt;li&gt;My Hero: The Humble Kebab&lt;/li&gt;
&lt;li&gt;Two Pleas for a Tidier Future&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The CSS Casing Chaos: My Beef with CSS Casing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Confession time:&lt;/strong&gt; I'm a developer with a bad case of Code-OCD. For the past decade, I've found a strange sort of peace in the predictable, orderly worlds of different programming languages. I love that Python developers collectively decided snake_case_is_the_way, and the JavaScript community embraced camelCaseLikeThis. It’s clean. It’s uniform. It’s consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And then there's CSS.&lt;/strong&gt;&lt;br&gt;
&lt;a&gt;&lt;/a&gt;&lt;br&gt;
Oh, CSS. The Wild West of the web. It's the one place where every project feels like a new frontier, and the local naming convention is "anything goes." In my travels, I’ve seen them all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kebab-case: the-good-stuff&lt;/li&gt;
&lt;li&gt;camelCase: theWeirdStuff&lt;/li&gt;
&lt;li&gt;PascalCase: TheTitleStuff&lt;/li&gt;
&lt;li&gt;snake_case: the_confusing_stuff&lt;/li&gt;
&lt;li&gt;And my personal nightmare: an unholy mix of all four in the same file. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;😱&lt;/p&gt;

&lt;p&gt;Just peek into the developer tools of a few major websites. It’s often a tangled mess that makes my eye twitch. &lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Below are statistics from various sites on different percentages of css being used by them in their homepage. Key observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facebook and Instagram seem to be most consistent in classname naming convention.&lt;/li&gt;
&lt;li&gt;Amazon seems to be following good old kebab-case.&lt;/li&gt;
&lt;li&gt;LinkedIn seems to be using mix-up of classes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/sunil12738/b9e6fe1eb902d70bfe4f5c18bce88a92" rel="noopener noreferrer"&gt;snippet used to gather this data&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Gmail
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktwx1clgzfap17t5j3k5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktwx1clgzfap17t5j3k5.png" alt=" " width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Facebook
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8umbww49sumfeoqnxan.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8umbww49sumfeoqnxan.png" alt=" " width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Instagram
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy9nmevvk63llep88aw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy9nmevvk63llep88aw9.png" alt=" " width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  LinkedIn
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyq0mf11pmo5e8kvj73qt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyq0mf11pmo5e8kvj73qt.png" alt=" " width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Amazon
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20kotw9npc5o7pv3nkly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20kotw9npc5o7pv3nkly.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Flipkart
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oa7g0ge4onhi8ia4q84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5oa7g0ge4onhi8ia4q84.png" alt=" " width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How did we, an industry obsessed with standards, let this happen?
&lt;/h2&gt;

&lt;p&gt;The short answer is that CSS wasn't designed for the complex world it now lives in, and the community built solutions in fragmented ways before any single standard could emerge.&lt;/p&gt;

&lt;p&gt;Here are the key reasons why we, an industry obsessed with standards, ended up in this naming mess:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Humble Beginnings: It Was for Documents, Not Apps 🌱
&lt;/h3&gt;

&lt;p&gt;When CSS was created in the mid-90s, the web was a collection of static documents. Its primary job was simple: separate content (HTML) from presentation (CSS). No one imagined we'd be building massive, interactive applications with it. The problem of large-scale, maintainable CSS with dozens of developers simply wasn't on the radar. We started with a garden shovel and are now trying to build a skyscraper with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Browser's Forgiving Nature 🧐
&lt;/h3&gt;

&lt;p&gt;Programming languages like JavaScript or Python have strict rules and linters (like ESLint or PEP 8) that yell at you for inconsistent syntax. Browsers, on the other hand, are incredibly lenient with CSS. A browser’s main goal is to render a webpage, not to enforce stylistic purity. As long as a class name doesn't break basic syntax rules, the browser will accept my-class, MyClass, or my_ClAsS without complaint. There's no built-in "gatekeeper" to enforce a single convention.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Community Solutions Created Competing Standards
&lt;/h3&gt;

&lt;p&gt;As web applications grew more complex, developers felt the pain of messy CSS. Instead of a single, top-down standard being created, brilliant developers from the community came up with their own solutions to manage the chaos. This gave us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BEM (Block, Element, Modifier): nav__item--active&lt;/li&gt;
&lt;li&gt;SMACSS (Scalable and Modular Architecture for CSS)&lt;/li&gt;
&lt;li&gt;OOCSS (Object-Oriented CSS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are fantastic methodologies, but they are competing philosophies, not a universal standard. It's like if different groups invented their own traffic rules for the same city—all are trying to solve the problem, but the result is still fragmentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Tooling Revolution Added Another Layer 🤖
&lt;/h3&gt;

&lt;p&gt;Then came the modern tooling era with SASS, LESS, CSS Modules, and CSS-in-JS. These tools were game-changers, solving major problems like variable management and scope leakage. However, they also introduced their own unique ways of working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SASS/LESS allowed nesting, which created its own naming patterns.&lt;/li&gt;
&lt;li&gt;CSS Modules and CSS-in-JS often generate unique, hashed class names (.header_title__a34Bf) to guarantee styles are scoped. This makes the human-written naming convention less critical for preventing conflicts, so the focus shifted away from standardizing it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, it wasn't a single decision that led us here. It was a slow, organic evolution where the problem grew faster than the language's core ability to manage it, and the community patched the gaps with a diverse and brilliant—but ultimately fragmented—set of tools and ideas.&lt;/p&gt;

&lt;p&gt;So, that explains the chaos, but it doesn't excuse it. We're standing in a mess created by historical accidents and competing ideas. While we can't rewrite the past, we can choose a clearer path forward. For me, that path starts with a simple, foundational choice&lt;/p&gt;

&lt;p&gt;Given this complex history of competing methodologies and powerful tools, it’s easy to feel like the problem is too big to solve. But what if the first step toward sanity is much simpler than adopting another framework? What if it begins with looking at the native language itself for guidance?&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Hero: The Humble Kebab
&lt;/h2&gt;

&lt;p&gt;If I had to plant my flag on one hill, it would be for kebab-case (main-navigation-link). It just feels native. CSS properties themselves are written in kebab-case (font-size, background-color, align-items), and so are HTML attributes (data-user-id, aria-label). Using kebab-case for class names creates a beautiful, harmonious flow between your HTML structure and your CSS rules. Everything looks like it belongs together.&lt;/p&gt;

&lt;p&gt;Now, I know what you’re thinking. "But what about BEM!?"&lt;/p&gt;

&lt;p&gt;Sure, methodologies like BEM (&lt;code&gt;block__element--modifier&lt;/code&gt;) are a fantastic effort to bring structure to our stylesheets. They are a godsend for organizing complex components. But here's the catch: BEM tells you how to structure the relationship between classes, not the fundamental way to write the words themselves. You can still end up with &lt;code&gt;MainMenu__Nav-Item--isActive&lt;/code&gt;, which is a stylistic Frankenstein.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Pleas for a Tidier Future
&lt;/h2&gt;

&lt;p&gt;So, where does that leave us in this beautiful, chaotic mess? I believe the path to CSS sanity lies in maybe a two-pronged approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Grassroots Pact: What We Can Do Today
&lt;/h3&gt;

&lt;p&gt;My first plea is to you, my fellow developers, fighting in the trenches of daily code. Let's make a pact. Pick a convention and stick to it with fierce loyalty. My vote is for the humble kebab-case, as it aligns perfectly with CSS's native syntax. But honestly, even if your team chooses camelCase or snake_case, the win is in the consistency. Agree on a style, document it, and enforce it. Future you will be grateful.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Big Picture Plea: A Call to Framework Architects
&lt;/h3&gt;

&lt;p&gt;My second plea goes out to the brilliant minds building the frameworks and tools we love. In the JavaScript world, frameworks like React, Vue, and Svelte don't reinvent the language's syntax; they embrace its standards (camelCase variables, PascalCase components).&lt;/p&gt;

&lt;p&gt;Why can't we have that for CSS?&lt;/p&gt;

&lt;p&gt;I understand that many modern tools auto-generate hashed class names (.cz13b8) to prevent conflicts, making human-readable names less critical in production. However, the source code—the component files and style sheets we actually write—is where the chaos lives. A plea to the framework architects: Promote and adopt a single, consistent naming style for the code we write. Let's build that consistency right into the tools we use every day.&lt;/p&gt;

&lt;p&gt;Until that glorious day arrives, you’ll find me in my projects, acting as the lone sheriff wrangling every stray camelCase and outlaw snake_case I can find. A little consistency, after all, is all a developer with a twitchy eye for clean code can ask for. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is that really too much to ask?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(co-author: Google Gemini Pro)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>namingconvention</category>
      <category>css</category>
      <category>sass</category>
    </item>
    <item>
      <title>Web Development: We're Back Where We Started, and It's a Good Thing!</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Mon, 22 Sep 2025 06:33:02 +0000</pubDate>
      <link>https://forem.com/sunil12738/web-development-were-back-where-we-started-and-its-a-good-thing-2kjl</link>
      <guid>https://forem.com/sunil12738/web-development-were-back-where-we-started-and-its-a-good-thing-2kjl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22q1jp5y43eodbbo9jkj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22q1jp5y43eodbbo9jkj.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever looked at the latest trends in web development and thought, "Wait, haven't we been here before?" It feels like we're on the verge of completing a full cycle, returning right back to where we started.&lt;/p&gt;

&lt;p&gt;But what if it isn't a circle? What if it's a spiral? We're revisiting old ideas, but with all the knowledge and power we gained along the way. Let's look at the journey.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 1: The Age of the Server (Traditional SSR)
&lt;/h2&gt;

&lt;p&gt;In the beginning, the server was king. Technologies like PHP, Ruby on Rails, and Django would build the entire HTML page on the server for every single request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it worked:&lt;/strong&gt; You click a link, your browser sends a request, the server thinks, builds a brand new page, and sends the finished product back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Good:&lt;/strong&gt; The first page load was fast, and since the content was all in the initial HTML, Search Engine Optimization (SEO) was simple and effective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Bad:&lt;/strong&gt; The user experience could feel clunky. Every significant interaction, even clicking a 'like' button, often required a full page reload. It wasn't smooth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 2: The Client-Side Revolution (The SPA Era)
&lt;/h2&gt;

&lt;p&gt;To solve the clunky user experience, we flipped the model entirely. Frameworks like React, Angular, and Vue gave birth to the Single-Page Application (SPA).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it worked:&lt;/strong&gt; The server sends a nearly blank HTML file and a giant bundle of JavaScript. The browser then runs this code to build the page and handle all future interactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Good:&lt;/strong&gt; The user experience became incredibly fluid and fast, feeling more like a native desktop app than a website. No more full page reloads!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Bad:&lt;/strong&gt; This created new problems. The initial load could be very slow (the dreaded "white screen of death" while JavaScript downloads), and SEO became a major challenge because the initial HTML was empty.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 3: The Hybrid Era (The Best of Both Worlds)
&lt;/h2&gt;

&lt;p&gt;This is where we are now, with frameworks like Next.js, Nuxt.js, and SvelteKit. It looks like a return to Stage 1, but it's far more intelligent. This isn't just server rendering; it's a hybrid model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it worked:&lt;/strong&gt; For the initial request, the server pre-renders the page (like Stage 1), sending fully-formed HTML. This gives us a super-fast first load and perfect SEO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Magic Part:&lt;/strong&gt; This HTML also includes the necessary JavaScript to "hydrate" the page in the browser, turning it into a full-fledged SPA (like Stage 2).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Result:&lt;/strong&gt; We get the benefits of the server (fast initial load, great SEO) and the benefits of the client (rich interactivity, no page reloads). This is the "upward turn" in our spiral. We've solved the problems from both previous eras.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 4: Where Do We Go From Here?
&lt;/h2&gt;

&lt;p&gt;So, will we just repeat Stage 2 and go back to pure client-side rendering?&lt;/p&gt;

&lt;p&gt;Highly unlikely. That would mean giving up all the incredible performance and SEO benefits we've just regained. The future isn't about going backward, but continuing up the spiral.&lt;/p&gt;

&lt;p&gt;The next stage is already taking shape with concepts like React Server Components (RSC) and Edge Computing. These aim to blur the line between client and server even further, allowing us to build incredibly complex applications that remain lightning-fast by intelligently deciding where each piece of the application should run.&lt;/p&gt;




&lt;p&gt;So, are monoliths coming back? In a way, yes. But they're not the slow, clunky monoliths of the past. They're smarter, faster, and have learned all the lessons from the client-side revolution.&lt;/p&gt;

</description>
      <category>web</category>
      <category>webdev</category>
      <category>history</category>
      <category>programming</category>
    </item>
    <item>
      <title>Lazy Loading: Do you really know what it is?</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Sat, 06 Sep 2025 11:52:30 +0000</pubDate>
      <link>https://forem.com/sunil12738/lazy-loading-do-you-really-know-what-it-is-3l7g</link>
      <guid>https://forem.com/sunil12738/lazy-loading-do-you-really-know-what-it-is-3l7g</guid>
      <description>&lt;h4&gt;
  
  
  Introduction: Not Your Usual Lazy Loading Blog
&lt;/h4&gt;

&lt;p&gt;If the title intrigued you and you’re expecting a straight answer; this isn’t that blog. But... if you’re here to think, explore, and maybe chuckle a bit, you’re in the right place. 😝&lt;/p&gt;

&lt;p&gt;If you ask a developer (or check &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Guides/Lazy_loading" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;), you’ll get something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is my tongue-in-cheek definition 😝:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lazy loading is a strategy developed by SPA libraries owners to clean the mess created by SPA libraries owners when they thought moving from simple server rendered single pages to heavy client side bundled pages is a good idea.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  A Short History of Web Rendering
&lt;/h4&gt;

&lt;p&gt;Decade(s) ago, a lot of pages and content were server rendered with only the css, js etc related to that page getting downloaded ('MPA' or 'Multi Page Application'). &lt;/p&gt;

&lt;p&gt;Then came SPA. &lt;br&gt;
Why? Some people thought it will make applications and subsequent page loads faster, interactions will be better (which are). But no one thought about the initial load time? or the increasing TTI with large bundle sizes? Here comes Lazy loading to the rescue. &lt;em&gt;(Create a problem, then fix it yourself and get kudos from the community on problem which shouldn't have existed in the first place 🤣🤣)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then comes Code splitting; then comes Lazy Loading; then comes SSR frameworks like NextJs, RedwoodJS; and now we are going back again to MPA style Frameworks from where we started in the first place. With shinier tooling.&lt;/p&gt;

&lt;h4&gt;
  
  
  Moore’s Law question
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;What do you think? Are apps genuinely faster today because of these strategies, or is Moore’s Law doing most of the heavy lifting?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course there are improvements! People will argue that things are faster. But &lt;strong&gt;Are applications really faster due to this?&lt;/strong&gt; I will probably write another blog on this. Try running the current application in a system that’s decades old. And one will realize that improved hardware, RAM, CPU, GPU etc might be playing a more important reason for better performance than these.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Cycle Comes Full Circle
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Isn't it funny, the entire cycle is completed!
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjsbatob3eiwqu6hyo7fk.png" alt="Evolution of Web Applications - A funny take" width="800" height="561"&gt;
&lt;/li&gt;
&lt;li&gt;It is also funny that in grand scheme of life, almost every time "History Repeats Itself" or each generation tries to improve a situation only to land back in same situation and never to realize it. In this case:

&lt;ul&gt;
&lt;li&gt;We started with server-rendered MPAs.&lt;/li&gt;
&lt;li&gt;We moved to client-rendered SPAs.&lt;/li&gt;
&lt;li&gt;We added lazy loading to fix SPA problems.&lt;/li&gt;
&lt;li&gt;SSR and SSGs coming into place.&lt;/li&gt;
&lt;li&gt;Now frameworks are pulling us back to MPA-style rendering.
&lt;strong&gt;And here we are, celebrating the “new” solution that looks suspiciously like the old one.&lt;/strong&gt;
Almost like... history repeating itself.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Maybe lazy loading is brilliant. Maybe it’s a band-aid.&lt;br&gt;
Or maybe it’s just proof that in tech, as in life:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We love solving problems we created ourselves.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thoughts?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Truly speaking, this is just a thought process right now; will dig much deeper into it;)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>web</category>
      <category>ssr</category>
      <category>funny</category>
    </item>
    <item>
      <title>Developing our own cowin slot notifier in 30 mins</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Sun, 16 May 2021 09:04:58 +0000</pubDate>
      <link>https://forem.com/sunil12738/developing-our-own-cowin-slot-notifier-in-30-mins-eg9</link>
      <guid>https://forem.com/sunil12738/developing-our-own-cowin-slot-notifier-in-30-mins-eg9</guid>
      <description>&lt;p&gt;Since the vaccination slots have opened all over the country; getting a slot has become as difficult as booking tatkal ticket on IRCTC. There are many apps now available who notifies when slots are available; I had an idea - Can I code my own cowin slot notifier? Will it be as effective as other apps? Turns out, the answer is yes. Without further waiting, let's jump into the code.&lt;/p&gt;

&lt;p&gt;We will develop a very minimalistic NodeJs application which will notify us when the slots are available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Requisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Cowin Public APIs - &lt;a href="https://apisetu.gov.in/public/api/cowin" rel="noopener noreferrer"&gt;https://apisetu.gov.in/public/api/cowin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Some knowledge of a NodeJs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Part 1: Fetching the data
&lt;/h2&gt;

&lt;p&gt;The API which we need to target are Appointment Availability APIs. Following APIs are exposed by Cowin:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4epjn69q4yhxty3u4aqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4epjn69q4yhxty3u4aqd.png" alt="Appointment Availability APIs"&gt;&lt;/a&gt;&lt;br&gt;
We will use &lt;code&gt;/v2/appointment/sessions/public/findByDistrict&lt;/code&gt; but one can use other API as well and the logic will be same. This API takes in 2 query parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;district_id&lt;/strong&gt; - To get the district_id, we need to hit the meta APIs from the swagger. Open the swagger &lt;a href="https://apisetu.gov.in/public/api/cowin" rel="noopener noreferrer"&gt;link&lt;/a&gt; and hit get states API under Meta APIs - &lt;em&gt;/v2/admin/location/states&lt;/em&gt;. Pick the state_id for your state. Then using this state_id hit, get list of districts under Meta APIs - &lt;em&gt;/v2/admin/location/districts/{state_id}&lt;/em&gt;. Pick the &lt;code&gt;district_id&lt;/code&gt; for your state. We will hardcode this value for out main API. For sample reference, we will use state as &lt;em&gt;Delhi&lt;/em&gt; and district as &lt;em&gt;South Delhi&lt;/em&gt;. The relevant &lt;code&gt;state_id is 9&lt;/code&gt; and &lt;code&gt;district_id is 149&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;date&lt;/strong&gt;   - The date in &lt;code&gt;DD-MM-YYYY&lt;/code&gt; format for which we want slots.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We won't send any header value (I think the APIs are not consuming this header properly and giving incorrect response if you use them).&lt;/p&gt;

&lt;p&gt;Now we have all data to get the slots. Using the https node module we will make a GET call to &lt;code&gt;https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByDistrict?district_id={district_id}&amp;amp;date={date}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sample Code for the same is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByDistrict?district_id=149&amp;amp;date=16-05-2021&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will give us the API response in &lt;code&gt;data&lt;/code&gt; variable which we will pass to another function for processing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; We need to call the api regularly at frequent intervals so as to get the slots as soon as they are available. The Cowin doc says API have limit of 100 calls per 5 minutes = One call per 3 second. We will use setInterval function for the same and clearInterval as soon as the slots are found.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part 2: Processing the data
&lt;/h2&gt;

&lt;p&gt;The response we have got is for all the centres of the district. Here is one sample response:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"centers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"center_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;701523&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"P. SKV School Fatehpurberi S-4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"4 Church Wali Gali Fatehpur Beri New Delhi Delhi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"state_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Delhi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"district_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"South Delhi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"block_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Not Applicable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pincode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;110074&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"long"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"09:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"17:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fee_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Free"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sessions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"23e393ea-a06e-42d7-860f-83ecd45edb5f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"16-05-2021"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"min_age_limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"vaccine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"COVISHIELD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"slots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"09:00AM-11:00AM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"11:00AM-01:00PM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"01:00PM-03:00PM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"03:00PM-05:00PM"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"available_capacity_dose1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"available_capacity_dose2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The response contains a lot of info and we will write few conditions to filter the data. Note that each object under sessions array, contains &lt;code&gt;available_capacity&lt;/code&gt; key which tells the availability of the slots and &lt;code&gt;min_age_limit&lt;/code&gt; key tells the age limit for which slots are open. Based on these 2 keys and other factors such as pincode, let's filter out the results&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pincodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;110030&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110062&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;centers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;centers&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pincodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;pincode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;available_capacity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;slotFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Slots Found:
            Pincode: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;pincode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
            Centre Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
            Centre Address: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;centers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
            Capacity Remaining: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;available_capacity&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once we have filtered out the results, we need a mechanism to notify us. &lt;/p&gt;
&lt;h2&gt;
  
  
  Part 3: The Notification
&lt;/h2&gt;

&lt;p&gt;Since, I will be running this application locally in my laptop, I thought of using my Mac's audio player &lt;code&gt;afplay&lt;/code&gt; to notify me (Ubuntu equivalent for afplay is ffplay). We just need one audio file in our system and &lt;code&gt;exec&lt;/code&gt; from &lt;code&gt;child_process&lt;/code&gt;. Using exec, we can run bash commands in node. As soon as any slot is found, we can run the following command. It will start to play the music in our system thus alerting us (:D).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;afplay ./audio.mp3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Stitching everything together, here is the full code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Go ahead, save this file and run it in your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;This is a working POC done in 30 mins and can be improved a lot. There are a lot of improvements that can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove the hardcoding at various places and make the application generic for all states and districts&lt;/li&gt;
&lt;li&gt;Support to search for slots by different APIs&lt;/li&gt;
&lt;li&gt;Create UI and deploy the same on a website (and change the notification mechanism) to make it suitable for all users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please comment for any valuable feedback, comment or criticism.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>node</category>
      <category>covid</category>
      <category>javascript</category>
      <category>cli</category>
    </item>
    <item>
      <title>Amazon Virtual Interview Experience - Frontend Engineer II</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Mon, 28 Dec 2020 10:02:17 +0000</pubDate>
      <link>https://forem.com/sunil12738/amazon-virtual-interview-experience-frontend-engineer-ii-284c</link>
      <guid>https://forem.com/sunil12738/amazon-virtual-interview-experience-frontend-engineer-ii-284c</guid>
      <description>&lt;p&gt;About a few months ago I was looking out for a job when I got the opportunity to be interviewed at Amazon. As I started my research online (or &lt;em&gt;googling&lt;/em&gt; as others would say), I found less articles for frontend interviews and that too for virtual processes were close to none. So, after the interview process was over, I thought of writing down an article of my own experience at Amazon.&lt;/p&gt;

&lt;p&gt;Hoping that a lot of people will be benefitted by this!&lt;/p&gt;

&lt;p&gt;Even if you are not a frontend/UI developer, do have a look as a lot of processes are common for both frontend and backend engineers.&lt;/p&gt;

&lt;p&gt;This will be a detailed article going in depth of the entire process from start to end. I will be covering the entire virtual process, online tools, interview rounds (including questions summary) and their timelines as well as will be attaching the relevant docs provided by Amazon. So without further waiting, let's start.&lt;/p&gt;




&lt;h2&gt;
  
  
  Brief Summary about me
&lt;/h2&gt;

&lt;p&gt;(at the time of interview process)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total Experience: 4 years&lt;/li&gt;
&lt;li&gt;Relevant frontend experience: 3 years&lt;/li&gt;
&lt;li&gt;Core Expertise: Javascript (ReactJs + Redux and other relevant libraries in React ecosystem), HTML, CSS, NodeJs&lt;/li&gt;
&lt;li&gt;Companies worked till now: &lt;a href="https://www.practo.com" rel="noopener noreferrer"&gt;Practo&lt;/a&gt; and &lt;a href="https://www.goomo.com" rel="noopener noreferrer"&gt;Goomo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Role - Frontend Engineer II (FE2)
&lt;/h2&gt;

&lt;p&gt;The Role I interviewed for was for a &lt;code&gt;Frontend Engineer II (FE2)&lt;/code&gt; role (&lt;em&gt;JD attached at bottom&lt;/em&gt;). Now, Amazon do have multiple categories of roles even in frontend development. There is one Web Development Engineer (WDE) role and other type is Frontend Engineer (FE) role. As per the interviewers, FE role is more senior in terms of responsibilities and work compared to WDE. So even for same level (e.g. FE2, WDE2); FE2 will have more responsibilities and salary than WDE2.&lt;/p&gt;




&lt;h2&gt;
  
  
  Process
&lt;/h2&gt;

&lt;p&gt;Do note that Amazon is a very big firm and sometimes, it takes a lot of time to get the process done. Process was relatively longer for me. From applying till the final selection/rejection it took about 3 months.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shortlisting
&lt;/h3&gt;

&lt;p&gt;My profile went through third party recruitment firm &lt;a href="https://www.linkedin.com/company/careernet-consulting/" rel="noopener noreferrer"&gt;CareerNet Technologies&lt;/a&gt;. Kiran from Careernet and their team helped a lot in the overall process. I used to get constant and timely updates from them. All the info related to interviews, shortlisting was conveyed properly. My resume was submitted in early week of March 2020 and took a few weeks to get shortlisted for next rounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Number of rounds:
&lt;/h3&gt;

&lt;p&gt;There were 6 rounds in total (including one screening round). All the rounds were done virtually. Most of the rounds were scheduled 1 hour rounds (but few got extended to 2 hours in my case).&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrangements/Logistics for Virtual Interview
&lt;/h3&gt;

&lt;p&gt;So, the way interviews are happening now will be very different from how they used to happen onsite (pre-covid era). The rounds happened over video call (except for screening which was over chat). I used to get mails few days before the interview. It contained the link for the chat, the online editor as well as white board tool. The mail also contained various other links for me to read and get to know about the company, interview tips and preparation docs etc. The links for documents have been added at bottom.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For white boards, there was invision link shared where both interviewer and interviewee can draw the diagrams etc (Do get used to it as it might slow you down). Though the tool is intuitive to use, it needs a lot of practice to draw things. (&lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;Excalidraw&lt;/a&gt; is also another similar tool which you can use to practice)&lt;/li&gt;
&lt;li&gt;Then there was a tool where you can write code as the interview proceeds. The link was something like: &lt;a href="https://livecode.amazon.jobs/session/xxxx-xxxx-xxxxxxxxx-xxxx" rel="noopener noreferrer"&gt;https://livecode.amazon.jobs/session/xxxx-xxxx-xxxxxxxxx-xxxx&lt;/a&gt;.
&lt;em&gt;Note:&lt;/em&gt; There is no functionality to run the code. It was some sort of plain text editor. So, you just have to go with the gut feeling of code being correct/incorrect.&lt;/li&gt;
&lt;li&gt;For video calling, the tool was Chime (similar to Google meet or Hangouts).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Timelines
&lt;/h2&gt;

&lt;p&gt;I started to look for a job in mid February 2020 and had started to apply for Amazon via referral as well as third party recruitment firms.&lt;/p&gt;

&lt;p&gt;Here is also a timeline of the various rounds. As far as I know, this can vary for individuals depending upon the requirements. The interviews happened as per my convenience and even some interviews happened on Saturdays as my week days were occupied with my work. So, amazon was very much flexible with it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Resume submitted&lt;/td&gt;
&lt;td&gt;1st week of March 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screening Round&lt;/td&gt;
&lt;td&gt;17th April 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 1&lt;/td&gt;
&lt;td&gt;12th June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 2&lt;/td&gt;
&lt;td&gt;12th June 2020*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 3&lt;/td&gt;
&lt;td&gt;13th June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 4&lt;/td&gt;
&lt;td&gt;15th June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 5&lt;/td&gt;
&lt;td&gt;18th June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round 6&lt;/td&gt;
&lt;td&gt;18th June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Result&lt;/td&gt;
&lt;td&gt;23rd June 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*This round was interrupted and postponed due to internet issues. So it wasn’t evaluated.&lt;/p&gt;

&lt;p&gt;I wasn’t expecting the process to take so long. So, somewhere around screening, I had already joined another firm. But, when the interview call came, I just thought of giving interviews so as to get an experience which will help me in future.&lt;/p&gt;




&lt;h2&gt;
  
  
  Interview Rounds
&lt;/h2&gt;

&lt;p&gt;There were about 6 interview rounds (including screening round). The pattern was very standard with the only exception being that this was more related to frontend perspective. The questions were mostly restricted to html/css/javascript and the basic principles. No framework specific questions were asked.&lt;/p&gt;

&lt;p&gt;Briefly summing up the interview rounds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screening: Was asked to write code (html/css/javascript) for a navigation menu bar following all good practices and conventions. Then a lot of counter questions on the solution I presented. This round was a chat only round. There was an online editor where I can write code and a chat window where we can type and interact with the interviewer. No audio/video feedback was there.&lt;/li&gt;
&lt;li&gt;Round 1: This round was a mix of DS/Algorithm and UI. Was asked to design a search bar (using trie like data structure) with good caching mechanism (browser side caching). And then there were some other questions related to arrays in Javascript.&lt;/li&gt;
&lt;li&gt;Round 2: It was pure Data Structure and Algorithm round. A question to find the lowest common ancestor for 2 nodes in a tree was asked (&lt;a href="https://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/" rel="noopener noreferrer"&gt;read more here&lt;/a&gt;). Discussed multiple approaches with the interviewer. And then was asked to present a working solution with best time and space complexity covering edge cases. However, this round was interrupted in the middle due to some internet issues and a new round was scheduled for the same.&lt;/li&gt;
&lt;li&gt;Round 3: It was more of a culture fit/leadership principles round. A lot of questions of the pattern “Tell me about a time when you did this/that” were asked.&lt;/li&gt;
&lt;li&gt;Round 4: I was asked to design the Amazon search page. Users should be able to search and see results. Mostly targeted how will UI components be designed, what will be the API design, What kind of data structure to be used. How optimization/caching etc can be done and a lot more grilling around this. This round went to about 2 hours. This round involved a lot of white board drawing (and due to time constraint, interviewer asked me to submit a flowchart diagram of my solution post interview).&lt;/li&gt;
&lt;li&gt;Round 5: Was asked to write optimized solution for problems such as:

&lt;ol&gt;
&lt;li&gt;Given an array, find all pairs of numbers which sum to n with best time and space complexity. &lt;/li&gt;
&lt;li&gt;Write javascript code to deeply clone an object.&lt;/li&gt;
&lt;li&gt;Create a circle of radius 200px with some text in the center.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Round 6: This was a mixed questions round. It involved 2-3 questions like “Tell me about time when conflict between you and your team mates arose and how you resolved”. Then there was a algorithm related question on finding the correct order of execution for a set of libraries where some libraries have dependency on other libraries and I was supposed to write the code for the same.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In almost all rounds, the solution expected was to be perfect covering all the edge cases and with best practices. A lot of discussion happened on why certain approaches were better or why this has been done or how can you improve this. This is why it sometimes becomes difficult to crack the interview.&lt;/p&gt;




&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;My profile wasn’t shortlisted. This was the mail sent by their HR team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fywgauj6rg3t5kgvllzfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fywgauj6rg3t5kgvllzfw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Post this mail, it took about 10 days for HR to get me the detailed feedback. It was mainly the Data Structure and Algorithms implementation where they felt I need to work a bit more and HR asked me to reapply after some months (the usual stuff 😀).&lt;/p&gt;

&lt;p&gt;Also, an interesting point to note here is that during the course of interview Amazon also tries to move the profile between various other job profiles they have if the candidate is not suitable for current applied position which is a pretty good thing on their part. So, they themselves will recommend other positions and will change the course of interviews.&lt;/p&gt;




&lt;h2&gt;
  
  
  Some useful links:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sunil12738.github.io/AmazonInterview/Front%20End%20Engineer%20II.pdf" rel="noopener noreferrer"&gt;Job Description - Front End Engineer II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sunil12738.github.io/AmazonInterview/About%20Amazon.pdf" rel="noopener noreferrer"&gt;About Amazon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sunil12738.github.io/AmazonInterview/Amazon%20Candidate%20Preparation%20Document.doc" rel="noopener noreferrer"&gt;Amazon Candidate Preparation Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sunil12738.github.io/AmazonInterview/Interview%20Tips%20-%20Tech.docx" rel="noopener noreferrer"&gt;Interview Tips - Tech&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Overall it was a nice interview experience. Got to learn a lot of things.&lt;/p&gt;

&lt;p&gt;Note: I haven’t included a very detailed description of all the interview questions as the article was getting really long. But do let me know in the comments and I will write a separate article on that. Additionally, I have dumped all the interview questions (even from other companies as well) in &lt;a href="https://github.com/sunil12738/frontend-developer-interview-questions" rel="noopener noreferrer"&gt;&lt;strong&gt;this Github Repository&lt;/strong&gt;&lt;/a&gt;. Do check that out as well and contribute by practising and submitting your solutions :-). &lt;/p&gt;

&lt;p&gt;Please share it amongst your colleagues, friends and others who might get benefitted from it.&lt;/p&gt;

&lt;p&gt;Thanks! &lt;/p&gt;




</description>
      <category>javascript</category>
      <category>react</category>
      <category>frontend</category>
      <category>interview</category>
    </item>
    <item>
      <title>Choose a CMS (Content Management System)</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Tue, 22 Dec 2020 09:13:43 +0000</pubDate>
      <link>https://forem.com/sunil12738/choose-a-cms-content-management-system-26g3</link>
      <guid>https://forem.com/sunil12738/choose-a-cms-content-management-system-26g3</guid>
      <description>&lt;p&gt;Hey folks,&lt;/p&gt;

&lt;p&gt;Need some recommendation around good &lt;code&gt;CMS&lt;/code&gt; options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;One of my clients (based in India) is looking out for &lt;code&gt;a full-fledged CMS Solution similar to AEM or DotCMS&lt;/code&gt;. They already have &lt;code&gt;django-cms&lt;/code&gt; as their CMS solution but it is not as good as it seems. It has very basic CMS capabilites but to incorporate anything new requires a lot of coding and python expertise. Anything new means integrate a new plugin and a lot of plugins are outdated. &lt;/p&gt;

&lt;p&gt;For example, they needed headless support (which many CMS support) but in django-cms; the plugin for the same is not maintained. I also asked a &lt;a href="https://stackoverflow.com/questions/61360674/facing-issues-while-converting-django-cms-into-headless-cms"&gt;question&lt;/a&gt; for the same on stackoverflow but got no positive response (&lt;a href="https://stackoverflow.com/questions/61360674/facing-issues-while-converting-django-cms-into-headless-cms"&gt;link to question&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Now, my client is re-thinking the options and here is I need help from you all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;p&gt;Looking out for CMS which supports feature like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-tenant/Multi-site support&lt;/li&gt;
&lt;li&gt;Granular Permissions for sections/pages/documents&lt;/li&gt;
&lt;li&gt;Article Versioning&lt;/li&gt;
&lt;li&gt;Backup and Restore&lt;/li&gt;
&lt;li&gt;Google SSO Integration&lt;/li&gt;
&lt;li&gt;Multi language support&lt;/li&gt;
&lt;li&gt;Multi environment support (testing/production)&lt;/li&gt;
&lt;li&gt;Analytics, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And can be quickly used to onboard multiple tenants/sites with zero or limited developer support.&lt;/p&gt;

&lt;p&gt;They are fine with both Paid or Open source versions. We are exploring AEM, dotcms, sitefinity, wagtail etc but recommendation from you folks will really help us finalizing one. We also looked at wordpress, joomla but felt they have more security concerns and hence dropped off those.&lt;/p&gt;

&lt;p&gt;Any secure, reliable CMS recommendations will really help. Or if any of your companies is currently using CMS Solution, feedback on the same will be highly appreciated.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>cms</category>
      <category>contentmanagement</category>
      <category>django</category>
    </item>
    <item>
      <title>Using request/success/failure pattern in Redux to handle async actions</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Sun, 20 Dec 2020 10:39:50 +0000</pubDate>
      <link>https://forem.com/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0</link>
      <guid>https://forem.com/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0</guid>
      <description>&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request/Success/Failure Pattern in Redux (2 Part series)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0"&gt;&lt;strong&gt;Part 1: Using request/success/failure pattern in Redux to handle async actions&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g"&gt;Part 2: Simplifying request/success/failure model for async action in Redux for large applications&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A lot of times while making the API calls, we face the challenge; where based on different points of time of API call, we need to show different UI or handle other scenarios in a project. There are a lot of approaches to do the same. However, there is one which is the best and is widely used in many organizations. We will discuss about the same in this article.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;This is a 2 part article&lt;/code&gt; where we will see what is this pattern and how by using capabilities of javascript we can modify this pattern to scale our project easily and keep the code clean in the longer run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern!
&lt;/h2&gt;

&lt;p&gt;When any async action or API call is made, there are mainly 3 states:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request State - The async action or API call is in process&lt;/li&gt;
&lt;li&gt;Success State - The async action or API call is successful and gets some data&lt;/li&gt;
&lt;li&gt;Failure State - The async action or API call is errored/failed due to some reasons&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Based on these 3 states, we create functions and follow certain conventions etc to achieve the desired result.&lt;/p&gt;

&lt;p&gt;Things needed here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;action functions&lt;/li&gt;
&lt;li&gt;type strings&lt;/li&gt;
&lt;li&gt;reducer function(s)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We pick the main action verb here and append request/success/failure at the end to follow consistent naming convention.&lt;/p&gt;

&lt;p&gt;Let's take an example where we will be making an API call to get a list of users. For each of above listed cases, we will create an action and a type each. Corresponding to cases in above list for get list of users, we have now the following actions and types now:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And the corresponding reducer and the initial state will look something like this&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;When we need to make an api call we will dispatch the request action. It will make isLoading to true and we can use it to show an appropriate message/loader in the screen. As soon as the api call is finished; it will either be in successful or failure state. For each of these, we will dispatch either success or failure which will update the data in the reducer (in data or error variables respectively) as well as make isLoading to false and loaded to true.&lt;/p&gt;

&lt;p&gt;The various variables such as isLoading, loaded etc can be now be used in our component for the desired interactions or functionalities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why to stick to this pattern
&lt;/h2&gt;

&lt;p&gt;There are several advantages for this pattern and it closely follows all the good practices recommended in any software development. Few of them are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Readability and Maintainability&lt;/em&gt;: Since we are following a fixed pattern for naming, code becomes a lot more readable. request/success/failure model communicates properly the state in which API is and reduces mental overhead.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Code Scalability&lt;/em&gt;: This structure is highly scalable. We will see &lt;em&gt;how&lt;/em&gt; in our next article where we will reuse this structured format to extend this pattern for multiple API calls and avoid a lot of code repetition.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Control and Precise Hooks&lt;/em&gt;: This pattern also gives us more control. Once implemented, we have hooks at various point in API call to update the UI. Variables like isLoading and loaded give us control over UI whereas actions give control over how to save data in reducer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Integrating the pattern with middlewares
&lt;/h2&gt;

&lt;p&gt;The pattern also fits in very nicely which libraries such as redux-thunk or redux-saga.&lt;/p&gt;

&lt;p&gt;An example here will demonstrate on how to use the same with redux-saga&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;and the same can be done easily with thunk as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding additional actions/types (if needed)
&lt;/h2&gt;

&lt;p&gt;There could be some scenarios where devs might need to reset the data to initial state. In that case, we can add additional action accordingly.&lt;/p&gt;

&lt;p&gt;That's it about the pattern. So simple and sleek and yet so powerful!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending the pattern for multiple API calls
&lt;/h2&gt;

&lt;p&gt;The same approach can be extended now for multiple API calls. The only issue is that if one have a lot of api calls, there will be 3 actions, 3 types and 1 reducer per API call. It means that there will be a lot of repetitive code involved and there will be multiple reducers and logic to merge them.&lt;/p&gt;

&lt;p&gt;Well, not to worry about; we can simplify this by using the functional nature of javascript.&lt;/p&gt;

&lt;p&gt;For now, Part 1 of the article ends here. Keep following this space and I will update the link for Part 2 in here shortly!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; &lt;a href="https://dev.to/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g"&gt;Part 2 of the article is published here.&lt;/a&gt;&lt;/p&gt;




</description>
      <category>javascript</category>
      <category>react</category>
      <category>redux</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Simplifying request/success/failure model for async action in Redux for large applications</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Fri, 18 Dec 2020 18:14:00 +0000</pubDate>
      <link>https://forem.com/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g</link>
      <guid>https://forem.com/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g</guid>
      <description>&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request/Success/Failure Pattern in Redux (2 Part series)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0"&gt;Part 1: Using request/success/failure pattern in Redux to handle async actions&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/sunil12738/simplifying-request-success-failure-model-for-async-action-in-redux-for-large-applications-1n9g"&gt;&lt;strong&gt;Part 2: Simplifying request/success/failure model for async action in Redux for large applications&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now that we have learnt the pattern to skillfully handle the async actions in redux, let's dive deeper into how to simplify the same to make code more cleaner and scalable. For those who missed the Part 1, &lt;a href="https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0"&gt;please read here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why to simplify?
&lt;/h2&gt;

&lt;p&gt;Notice that, we have written a lot of boilerplate code just to handle one API call. Also, code will become repetitive in nature for multiple calls which contradicts with DRY and other software writing methodologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process of simplification
&lt;/h2&gt;

&lt;p&gt;We will pick each of our actions, types, reducer(s) and simplify them one by one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions and Types
&lt;/h3&gt;

&lt;p&gt;This is how we write our actions and types in this approach&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Observe here that there are 3 actions and 3 types. And the same pattern will be repeated for each API call. Imagine if there are 10 API calls. It means there will be 30 actions and 30 types to be manually written. To avoid this, we will write a helper function that will take one input string and return all the these. The function will look something like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If we use the above function then the entire logic for actions and types will be reduced to just one single line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getUsersList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actionCreator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_USERS_LIST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will give all the required actions and types.&lt;br&gt;
Next question is how to use all these. The answer is pretty simple. getUsersList is an object, so the relevant actions and types will be following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getUsersList.request &lt;em&gt;instead of&lt;/em&gt; getUsersListRequest&lt;/li&gt;
&lt;li&gt;getUsersList.success &lt;em&gt;instead of&lt;/em&gt; getUsersListSuccess&lt;/li&gt;
&lt;li&gt;getUsersList.failure &lt;em&gt;instead of&lt;/em&gt; getUsersListFailure&lt;/li&gt;
&lt;li&gt;getUsersList.REQUEST &lt;em&gt;instead of&lt;/em&gt; GET_USERS_LIST_REQUEST&lt;/li&gt;
&lt;li&gt;getUsersList.SUCCESS &lt;em&gt;instead of&lt;/em&gt; GET_USERS_LIST_SUCCESS&lt;/li&gt;
&lt;li&gt;getUsersList.FAILURE &lt;em&gt;instead of&lt;/em&gt; GET_USERS_LIST_FAILURE&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Reducer
&lt;/h2&gt;

&lt;p&gt;This is how current reducer looks like and it is only usable for one api call.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The reducer will now be modified to this&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note we have done 2 things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have clubbed the relevant switch cases together and transferred the logic to update store to a new &lt;strong&gt;reducerHandler&lt;/strong&gt; function.&lt;/li&gt;
&lt;li&gt;We have added a key &lt;code&gt;usersList&lt;/code&gt; which will contain entire state for that particular API. This will make sure that same reducer can be used for multiple API calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let see the definition of &lt;code&gt;reducerHandler&lt;/code&gt; function (helper function to be written only once) now:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Though we have added few functions which might seem that code is increased but observe that the task of creating multiple actions, types and reducers is reduced to few lines. Now if we have to do a new API call, just one line is added to create actions &amp;amp; types and few lines added in reducers instead of writing about 50 lines and adding a new reducer. This simplifies the code a lot. &lt;/p&gt;

&lt;h3&gt;
  
  
  Integrating with middlewares
&lt;/h3&gt;

&lt;p&gt;The other part of calling from sagas and dispatching actions will remain same. Let's see an example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This will help to keep code clean and help developers to increase productivity and focus on other areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exhaustive example
&lt;/h2&gt;

&lt;p&gt;Just to show, how this approach works here is an example with just 3 API calls:&lt;/p&gt;

&lt;h3&gt;
  
  
  Old approach (&lt;a href="https://dev.to/sunil12738/using-request-success-failure-pattern-in-redux-to-handle-async-actions-4d0"&gt;read more here&lt;/a&gt;)
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Simplified new approach
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
If you see, effort is almost reduced to 1/3rd with same desired effect.

&lt;p&gt;Are we done? Yes! At this point, a lot of repetitive logic is reduced and code is simplified. Can we simplify this further? Maybe, but I won't advice it. We can even write a wrapper to avoid writing actions and reducers at all but it has chances of doing more harm than good. &lt;/p&gt;

&lt;h2&gt;
  
  
  Are there any libraries which can provide these utilities?
&lt;/h2&gt;

&lt;p&gt;Yes, there are a few libraries which can do this for you but one should always think before adding extra libraries. Libraries increase the bundle size and then one has to maintain dependencies etc. That's why for simpler parts like this, writing our own logic seems preferable.&lt;/p&gt;

&lt;p&gt;Hope, you like this article. Please like, share and comment to discuss anything which can make this approach better.&lt;/p&gt;




</description>
      <category>javascript</category>
      <category>react</category>
      <category>redux</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Determining real data types in Javascript using Object.prototype.toString</title>
      <dc:creator>Sunil Chaudhary</dc:creator>
      <pubDate>Mon, 07 Dec 2020 08:57:57 +0000</pubDate>
      <link>https://forem.com/sunil12738/determining-real-data-types-in-javascript-using-object-prototype-tostring-245k</link>
      <guid>https://forem.com/sunil12738/determining-real-data-types-in-javascript-using-object-prototype-tostring-245k</guid>
      <description>&lt;p&gt;Is there an alternative (and maybe better way) to determine data type of variables in javascript other than typeof? Turns out there is one.&lt;/p&gt;

&lt;p&gt;Recently, I was looking at some code and found a different way some developers were using to determine the data types using Object.prototype.toString instead of typeof. On further exploration, I found that Object.prototype.toString gives much better results as compared to typeof and can be useful at a lot of places.&lt;/p&gt;

&lt;p&gt;Let’s look at some of the results it gives:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Application
&lt;/h1&gt;

&lt;p&gt;Though typeof works fine for most of the cases, toString will come in handy covering cases such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we need to differentiate between various types in objects (such as arrays, null, object, date)&lt;/li&gt;
&lt;li&gt;we need to get correct data type for primitive variables created using their respective object wrappers (e.g. new Number(10) is a number but typeof will give object)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Syntax
&lt;/h1&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;One can also write a wrapper around it or even modify the function prototype to remove the unnecessary characters in the output and get only datatypes&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Pros vs Cons
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;It seems typeof is more compact than toString in its usage as well as the result it returns but toString is more accurate.

&lt;ul&gt;
&lt;li&gt;toString gives more accurate data types which are useful when differentiating between various types of objects (arrays, null, objects, date)&lt;/li&gt;
&lt;li&gt;toString gives more accurate results in cases if someone has used object wrapper for primitive data types such as new Number/String.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;toString function can be overriden but typeof can’t which seems the only major drawback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more about the mechanism and working of the function over &lt;a href="https://medium.com/better-programming/what-is-object-object-in-javascript-object-prototype-tostring-1db888c695a4"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Overall, Object.prototype.toString is a pretty good method to determine the datatypes correctly in lot of cases.&lt;/p&gt;




</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
