<?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>DEV Community: Shubham Jain</title>
    <description>The latest articles on DEV Community by Shubham Jain (@shubhamjain).</description>
    <link>https://dev.to/shubhamjain</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%2F162248%2Fb73a7de5-68dd-4c61-b755-ecfc809e2d87.jpeg</url>
      <title>DEV Community: Shubham Jain</title>
      <link>https://dev.to/shubhamjain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shubhamjain"/>
    <language>en</language>
    <item>
      <title>I Built a Collection of 100+ Open-Source SVG Spinners</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Thu, 17 Oct 2024 05:45:37 +0000</pubDate>
      <link>https://dev.to/shubhamjain/i-built-a-collection-of-100-open-source-svg-spinners-2975</link>
      <guid>https://dev.to/shubhamjain/i-built-a-collection-of-100-open-source-svg-spinners-2975</guid>
      <description>&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt;: &lt;a href="https://magecdn.com/tools/svg-loaders" rel="noopener noreferrer"&gt;https://magecdn.com/tools/svg-loaders&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Github&lt;/strong&gt;: &lt;a href="https://github.com/shubhamjain/svg-spinners" rel="noopener noreferrer"&gt;https://github.com/shubhamjain/svg-spinners&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s been a lot of great work done with CSS spinners by developers like &lt;a href="https://github.com/Afif13/" rel="noopener noreferrer"&gt;Afif13&lt;/a&gt; and &lt;a href="https://github.com/vineethtrv/css-loader" rel="noopener noreferrer"&gt;Vineeth TRV&lt;/a&gt;. However, I’m personally not a fan of using CSS for this purpose. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;It complicates component creation.&lt;/li&gt;
&lt;li&gt;It clutters your stylesheets.&lt;/li&gt;
&lt;li&gt;It makes using spinners as backgrounds or images impossible. &lt;/li&gt;
&lt;li&gt;Scaling and changing colors are more cumbersome compared to simply tweaking the fill or stroke color in SVG.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SVG-based loaders offer a far more elegant solution. I’ve taken the time to gather spinners from various repositories and Codepens to create a &lt;a href="https://magecdn.com/tools/svg-loaders" rel="noopener noreferrer"&gt;centralized resource&lt;/a&gt;. So far, it's 108 spinners. I plan to keep adding. &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%2Fuploads%2Farticles%2Fh2t27xa71ix4nm4ekico.gif" 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%2Fh2t27xa71ix4nm4ekico.gif" alt="" width="800" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All spinners are &lt;strong&gt;MIT-Licensed&lt;/strong&gt;, meaning you can use them commercially without any restrictions or the need for attribution.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>css</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>I created a free CDN for social media icons</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Sat, 28 Sep 2024 07:43:30 +0000</pubDate>
      <link>https://dev.to/shubhamjain/i-created-a-free-cdn-for-social-media-icons-3kik</link>
      <guid>https://dev.to/shubhamjain/i-created-a-free-cdn-for-social-media-icons-3kik</guid>
      <description>&lt;p&gt;Happy to ship my side project: &lt;a href="https://magecdn.com/tools/social" rel="noopener noreferrer"&gt;https://magecdn.com/tools/social&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I built this side-project out of a personal pain. &lt;/p&gt;

&lt;p&gt;To include social media icons, you either have to use an icon pack (e.g, font-awesome), or copy individual SVGs. &lt;/p&gt;

&lt;p&gt;Icon packs feel like overkill if you only want to use a few icons on your website. And I am not really a fan of hunting SVGs and cluttering my code with it.&lt;/p&gt;

&lt;p&gt;Additionally, if you want to use icons in an email, you're out of options, since the majority of email clients don't support SVGs or web fonts.&lt;/p&gt;




&lt;p&gt;To solve this, I created a free CDN to deliver icons for most social media platforms (if I am missing any, let me know). &lt;/p&gt;

&lt;p&gt;Want to embed an icon? Just copy and paste. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It has icons for 20+ popular social media platforms.&lt;/li&gt;
&lt;li&gt;It is fast, reliable, and 100% free—powered by Cloudflare.&lt;/li&gt;
&lt;li&gt;No attribution is needed.&lt;/li&gt;
&lt;li&gt;Supports: SVG, PNG, and WebP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give &lt;a href="https://magecdn.com/tools/social" rel="noopener noreferrer"&gt;it a try&lt;/a&gt;. Happy to hear your thoughts!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Created a Free Web Tool to Make Beautiful Charts</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Thu, 04 Apr 2024 07:48:39 +0000</pubDate>
      <link>https://dev.to/shubhamjain/i-created-a-free-web-tool-to-make-beautiful-charts-1pf9</link>
      <guid>https://dev.to/shubhamjain/i-created-a-free-web-tool-to-make-beautiful-charts-1pf9</guid>
      <description>&lt;p&gt;I wanted an easy way to create basic charts from the data I have. Both Google Sheets and Excel involve some steps and the results aren't pretty. They haven't changed much for a long time and look completely off when it comes to modern design aesthetics. &lt;/p&gt;

&lt;p&gt;There are some other tools but they either require signup, are too complicated, or require attribution. &lt;/p&gt;

&lt;p&gt;So, I built something that's super-quick and super-easy to use, and the results are still pretty. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the link&lt;/strong&gt;: &lt;a href="https://textquery.app/tools/visualize/" rel="noopener noreferrer"&gt;https://textquery.app/tools/visualize/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two beautiful visualizations I built using this tool:&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%2Fuploads%2Farticles%2F3fi6zzj5s5fi9rk45eop.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%2F3fi6zzj5s5fi9rk45eop.png" alt="cherry blossom warming effect"&gt;&lt;/a&gt;&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%2Fuploads%2Farticles%2F8ijta7h1a804u49g932m.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%2F8ijta7h1a804u49g932m.png" alt="cricket stadiums by capacity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built it using VueJs, echarts, and TailwindCSS. The website is powered by Astro Framework. &lt;/p&gt;

&lt;p&gt;Happy to hear your thoughts! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>datascience</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>CSS is Impossible and That's Okay</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Mon, 19 Feb 2024 07:53:00 +0000</pubDate>
      <link>https://dev.to/shubhamjain/css-is-impossible-and-thats-okay-3kf4</link>
      <guid>https://dev.to/shubhamjain/css-is-impossible-and-thats-okay-3kf4</guid>
      <description>&lt;p&gt;I have been a web developer for more than a decade, and yet, when it comes to CSS, I always feel a bit out of depth. Not only it's enormously complex, its complexity is growing every year.&lt;/p&gt;

&lt;p&gt;In the year 2023 itself, there were a dozen &lt;a href="https://developer.chrome.com/blog/css-wrapped-2023" rel="noopener noreferrer"&gt;new additions to CSS&lt;/a&gt;: style queries, scroll-driven animations, and trigonometric functions, to name a few. &lt;/p&gt;

&lt;p&gt;I hadn't even completely caught up with the intricacies of Grid Layouting, when &lt;a href="https://web.dev/blog/state-of-css-2022" rel="noopener noreferrer"&gt;subgrid and container queries&lt;/a&gt; were shipped. Several of the newly added properties handle cases so specific that I hardly believe I would ever use them (&lt;a href="https://chriscoyier.net/2023/11/27/the-hanging-punctuation-property-in-css" rel="noopener noreferrer"&gt;hanging-punctuation&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-palette" rel="noopener noreferrer"&gt;font-palette&lt;/a&gt;, for example). &lt;/p&gt;

&lt;p&gt;Here's more: there are at least three properties related to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/hyphenate-character" rel="noopener noreferrer"&gt;hyphenating paragraphs&lt;/a&gt;. You might have used the &lt;code&gt;filter&lt;/code&gt; property, but did you know that it supports an entirely different class of &lt;a href="https://stefanjudis.com/today-i-learned/svgs-filters-can-be-inlined-in-css/" rel="noopener noreferrer"&gt;filters using SVG&lt;/a&gt;? Or that you can tweak the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering" rel="noopener noreferrer"&gt;image scaling algorithm&lt;/a&gt;? Or &lt;code&gt;border-radius&lt;/code&gt; support &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius" rel="noopener noreferrer"&gt;elliptical corners&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;The complexity can be gauged by the fact that there were at least &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units" rel="noopener noreferrer"&gt;25 units in CSS&lt;/a&gt;. And with container queries, six more were added. Now, imagine being aware of all those units, how to use them, and more importantly, the best time to use them.&lt;/p&gt;

&lt;p&gt;There was a time when I wanted to catch up with everything CSS had to offer, but soon enough, I realized the enormity of my ambition—and also, how largely unnecessary it would be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Knowing CSS is Okay
&lt;/h2&gt;

&lt;p&gt;CSS is complex for a reason. Its objective is to provide solutions for a wide range of use-cases—from a simple document to dynamic interactive websites. I might never need to bother with how a paragraph is hyphenated, but for news websites, it could be pretty important. &lt;/p&gt;

&lt;p&gt;The trouble stems from feeling the compulsion to know the whole of CSS. Hardcore enthusiasts like &lt;a href="https://chriscoyier.net/" rel="noopener noreferrer"&gt;Chris Coyier&lt;/a&gt; have probably achieved the feat, but the rest of us need to be content with not knowing a large chunk of the language—a desirable constraint, I would argue.&lt;/p&gt;

&lt;p&gt;Because, ultimately, CSS is a toolkit. It's meant to provide tools and solutions for many situations, but not everything is needed at once. You might be proficient with some of the tools, reasonably well with some others, and completely ignorant of the rest. And that's okay!&lt;/p&gt;

&lt;p&gt;If you stumble upon the problem that a CSS feature solves, you will likely learn that feature along the way. And even if you don't, it's okay to solve a problem inefficiently, until you stumble upon a better idea in the future. Trust me, you will!&lt;/p&gt;

&lt;p&gt;You don't need to use container queries until you feel the pinch of the problem. You don't need to know all the &lt;a href="https://gridbyexample.com/examples/" rel="noopener noreferrer"&gt;funky ways&lt;/a&gt; CSS grid can be utilized. You don't need to feel bad about not knowing how an impressive &lt;a href="https://a.singlediv.com/" rel="noopener noreferrer"&gt;CSS demo&lt;/a&gt; works. &lt;/p&gt;

&lt;p&gt;In short, you don't need to be overwhelmed with CSS. Everyone feels a bit lost when it comes to the language—from juniors to &lt;a href="https://news.ycombinator.com/item?id=19021719" rel="noopener noreferrer"&gt;seniors&lt;/a&gt;, but this is mostly from the expectation of knowing everything.&lt;/p&gt;

&lt;p&gt;CSS is hard and in my experience, best learned by practically experiencing problems and deeply understanding the solutions. It's good to be vaguely aware of new additions, but you don't need to start using them right away. Learn them at your own pace; you'll do fine.&lt;/p&gt;

</description>
      <category>css</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
    <item>
      <title>“Print” Is the Only Debug Tool You Need</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Mon, 27 Jun 2022 10:19:40 +0000</pubDate>
      <link>https://dev.to/shubhamjain/print-is-the-only-debug-tool-you-need-27d0</link>
      <guid>https://dev.to/shubhamjain/print-is-the-only-debug-tool-you-need-27d0</guid>
      <description>&lt;p&gt;&lt;em&gt;This blog post was originally published &lt;a href="https://shubhamjain.co/2022/06/27/print-is-the-only-debug-tool/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most basic debugging tool is a print statement. It could be &lt;code&gt;print&lt;/code&gt; function, &lt;code&gt;echo&lt;/code&gt;, &lt;code&gt;console.log&lt;/code&gt;, or &lt;code&gt;alert&lt;/code&gt;. Principle is the same: you display (partial) state of the program on the screen, check what stands out, and try to diagnose the issue. “It seems the loop is running more than it should. Let’s see what’s the value of &lt;code&gt;i&lt;/code&gt;  here”.&lt;/p&gt;

&lt;p&gt;No manual is needed to teach it. The idea just comes naturally to programmers.&lt;/p&gt;

&lt;p&gt;It works wonderfully for a while. But as programmers get more experienced, they discover better tools called debuggers, which allow programmers to add breakpoints and watchers. With breakpoints, the programmer can pause the execution of program at a specific point and inspect the state with a greater flexibility. In case of watchers, they can keep an eye on the state of a variable. &lt;/p&gt;

&lt;p&gt;I have used these tools, too. Over the years, however, I have realized that except for very specific situations, “Print” just works better.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Print is universal&lt;/strong&gt;: Every language has it. After all, putting something on screen is a pretty fundamental feature of any language. Debuggers can vary across different languages/platforms. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print doesn’t need specialized tools&lt;/strong&gt;: &lt;code&gt;print&lt;/code&gt; is part of the code. Setting up debugger can often be a hassle, since the debugger and the program are usually different. Sometimes, the integration is seamless, like Chrome DevTools, but with something like node.js, it’s not as easy to make the setup work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print doesn’t tie you to a particular tool&lt;/strong&gt;: Let’s say you’ve the setup working in VS Code. What if you want to switch your editor? You’ll have to figure out to make it work in that editor too. Print, on the other hand, will work everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print is faster to use&lt;/strong&gt;: Compared to creating multiple breakpoints and watchers, and removing them after use, print is definitely easier. Sure breakpoints give you more flexibility in diagnosing the issue, but often most issues aren’t that complicated to warrant them. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print works on Staging and Production&lt;/strong&gt;: It’s not easy to work with debug tools when you’re dealing with code running on the server. On the other hand, print statements work there too. Even if you don’t have access to STDOUT, you can write statements to a file or send them to a logging server/service  (e.g, &lt;a href="https://loggly.com" rel="noopener noreferrer"&gt;Loggly&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minifying/Compiling code doesn’t break print&lt;/strong&gt;: If you’re compiling/minified your code, there’s extra complexity in mapping original source do to the compiled one. Let’s say you encounter an issue in the final build. With minified variable and function names, it would be exhausting to find the root cause. However, if your original source includes a print statement, it would be compiled as well and the variables you’re interested in will be displayed. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Print statements are powerful, versatile and flexible. They are rudimentary but every time I have tried to upgrade myself to supposedly better tools, I have come back to printing variables. They are “it just works” version of debugging. &lt;/p&gt;

&lt;p&gt;Debuggers have their place. They are useful in places where you don't have the liberty to modify the code or you want to analyse the execution stack better. But in day-to-day work, you'll find print to be a better solution.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What do you think of my HTML5 game?</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Thu, 31 Mar 2022 12:43:49 +0000</pubDate>
      <link>https://dev.to/shubhamjain/what-do-you-think-of-my-html5-game-1oe4</link>
      <guid>https://dev.to/shubhamjain/what-do-you-think-of-my-html5-game-1oe4</guid>
      <description>&lt;p&gt;Past two weeks, I have been working on an HTML5 puzzle game: &lt;a href="https://eightcolors.net/" rel="noopener noreferrer"&gt;Eight Colors&lt;/a&gt;. The rules of the game are pretty simple but it does get a little challenging after the first few levels. It was super-fun to design and implement this game (not so fun though hacking around quirks of iOS Safari 😅)&lt;/p&gt;

&lt;p&gt;Let me know what you folks think. Happy to answer any question if you have. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>discuss</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Simplest Way to Include Icons in Your Project: Using Unpkg</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Tue, 04 May 2021 07:44:44 +0000</pubDate>
      <link>https://dev.to/shubhamjain/simplest-way-to-include-icons-in-your-project-using-unpkg-53op</link>
      <guid>https://dev.to/shubhamjain/simplest-way-to-include-icons-in-your-project-using-unpkg-53op</guid>
      <description>&lt;p&gt;The web has come a long way in the past years, but there are still things that aren't straightforward. Using icons is one of them.&lt;/p&gt;

&lt;p&gt;Icon fonts, inline SVGs, &lt;a href="https://css-tricks.com/svg-symbol-good-choice-icons/" rel="noopener noreferrer"&gt;SVG Symbols&lt;/a&gt;—all have their own issues. Inline SVGs are great, for example, but they make the code messy, and can't be cached. Additionally, copy-pasting the SVG itself is pretty time-consuming and a PITA. &lt;/p&gt;

&lt;p&gt;Using icons should be simpler. Here's what I always wanted: I see an icon I want to use and I am able to use it right away. No copy-paste; only have to know the name of the icon. No struggling to make the Webpack/Grunt pipeline work. No creating a new SVG file/component for every icon I want to use. &lt;/p&gt;

&lt;p&gt;Luckily, I have found a way. Follow along! &lt;/p&gt;

&lt;h2&gt;
  
  
  svg-loader: Load SVGs from a CDN
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/shubhamjain/svg-loader" rel="noopener noreferrer"&gt;svg-loader&lt;/a&gt; is a simple library that allows you to inline SVGs hosted on an external source. Here's a more &lt;a href="https://dev.to/shubhamjain/a-better-way-to-use-svgs-1mg9"&gt;detailed article&lt;/a&gt; I wrote about it, but to put it simply, you use it this way:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/external-svg-loader@1.0.0/svg-loader.min.js"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;data-src=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/assets/logo-white.svg"&lt;/span&gt; 
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; 
    &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"purple"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The library will fetch the SVG using XHR and inject it inline. The benefit? You can now customize the fill, inherit the colors, and use states like hover, which wouldn't have been possible with &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;The concept isn't new as &lt;a href="https://github.com/iconfu/svg-inject" rel="noopener noreferrer"&gt;svg-inject&lt;/a&gt; does something similar. However, svg-loader makes this ultra-convenient. You only have to worry about including the script somewhere in the code. Rest everything is handled. And it's framework-agnostic, too (works with React/Vue/Angular...).&lt;/p&gt;

&lt;h2&gt;
  
  
  svg-loader + unpkg = killer combo
&lt;/h2&gt;

&lt;p&gt;Recently, I discovered that I can use the library and &lt;a href="http://unpkg.com/" rel="noopener noreferrer"&gt;unpkg&lt;/a&gt; to quickly include an icon available on Github. &lt;/p&gt;

&lt;p&gt;Take, for instance, &lt;a href="https://github.com/Templarian/MaterialDesign" rel="noopener noreferrer"&gt;MDI repository&lt;/a&gt;. To my knowledge, it's the most extensive icon repository on Github that has 5k+ icons. &lt;/p&gt;

&lt;p&gt;Since the repo has an NPM package, we can browse it on unpkg: &lt;a href="https://unpkg.com/@mdi/svg/" rel="noopener noreferrer"&gt;https://unpkg.com/@mdi/svg/&lt;/a&gt;.&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%2Fuploads%2Farticles%2Fr4ym8ggdvd4d0gxazzzz.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%2Fr4ym8ggdvd4d0gxazzzz.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click any file and use "View Raw" you'll see that the permalink to any icon is something like this: &lt;code&gt;https://unpkg.com/@mdi/svg@5.9.55/svg/__ICON__.svg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can use this to start using the icon in our project. Example:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/shubhamjainco/embed/rNyBVmY?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Hurray! Now, if you need to use the &lt;code&gt;cog&lt;/code&gt; icon, you don't have to hunt for the SVG code, or download it, you can just use &lt;code&gt;cog.svg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The first load can have a slight delay because Unpkg fetches the package and extracts the file, but after the first request, the file is cached and served from Cloudflare CDN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Q&amp;amp;A About this Approach
&lt;/h2&gt;

&lt;p&gt;There might fair amount of questions about this approach, so I will try to answer the most common of them. &lt;/p&gt;

&lt;h3&gt;
  
  
  What if there are changes in the repo (like, renaming files)? Won't it break my icons?
&lt;/h3&gt;

&lt;p&gt;No. With unpkg, you'll most likely be using versioned URLs (instead of &lt;code&gt;@latest&lt;/code&gt;), which will make sure that the contents remain the same regardless of changes in the repository. &lt;/p&gt;

&lt;h3&gt;
  
  
  Isn't it inefficient to fire XHR for every icon, instead of bundling them?
&lt;/h3&gt;

&lt;p&gt;No. With HTTP2, the cost of making is incredibly low. For non-blocking resources loaded asynchronously, it's almost irrelevant. Here is me loading 50 icons using the same approach.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/shubhamjainco/embed/BaWBowd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Besides, the icons are also cached when loaded first-time, so the subsequent loads are incredibly fast. &lt;/p&gt;

&lt;h3&gt;
  
  
  What if unpkg goes away?
&lt;/h3&gt;

&lt;p&gt;It won't. It's a project &lt;a href="https://developers.cloudflare.com/sponsorships" rel="noopener noreferrer"&gt;supported officially&lt;/a&gt; by Cloudflare and serves 3B+ requests per day. &lt;/p&gt;

&lt;h3&gt;
  
  
  What if I want to use an icon set that doesn't have an npm package?
&lt;/h3&gt;

&lt;p&gt;You can use &lt;a href="https://www.jsdelivr.com/" rel="noopener noreferrer"&gt;jsDeliver&lt;/a&gt; that has a similar API and &lt;a href="https://www.jsdelivr.com/features" rel="noopener noreferrer"&gt;supports raw Github repos&lt;/a&gt; as well. &lt;/p&gt;




&lt;p&gt;I feel this is a pretty nifty approach for icons. You can use icons from &lt;a href="https://unpkg.com/browse/font-awesome-svg-png@1.2.2/black/svg/" rel="noopener noreferrer"&gt;Font Awesome&lt;/a&gt;, &lt;a href="https://unpkg.com/browse/@primer/octicons@13.0.0/build/svg/" rel="noopener noreferrer"&gt;Octicons&lt;/a&gt;, or any of the awesome icon sets hosted on Github.&lt;/p&gt;

&lt;p&gt;It's fast, very reliable, and keeps the code clean. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>webdev</category>
      <category>svg</category>
    </item>
    <item>
      <title>How to Get Better at English: Guide For Developers</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Mon, 26 Apr 2021 06:43:47 +0000</pubDate>
      <link>https://dev.to/shubhamjain/how-to-get-better-at-english-guide-for-developers-3ed4</link>
      <guid>https://dev.to/shubhamjain/how-to-get-better-at-english-guide-for-developers-3ed4</guid>
      <description>&lt;p&gt;&lt;a href="https://magecdn.com/?ref=dev.to"&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%2F67ktjfitpn7c48wbgh1o.png" alt="" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I saw a post recently where a developer raised very valid points on why English isn't a skill they should be measured with: &lt;a href="https://dev.to/russo_programmisto/my-english-is-not-perfect-why-would-you-hire-me-164o"&gt;My English is not perfect. Why would you hire me?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can empathize with the author but sadly, the reality is different. Like it or not, fluency in English is a vital skill for a programmer.&lt;/p&gt;

&lt;p&gt;Most folks, especially in the developed world, are very used to fluent English. Bad grammar sounds off and diverts attention. Even with the best intentions, the listener has to make a conscious effort to ignore it.&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%2Fuploads%2Farticles%2Fetofyo4disnn9u0n7uh4.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%2Fetofyo4disnn9u0n7uh4.png" alt="image" width="690" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In 2013, Facebook ignored multiple bug reports of a serious issue from a security researcher. Why? His English was poor and so the reports weren't taken seriously.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, a plethora of opportunities open up when you're fluent. You can communicate your ideas better. You can reach out to people with confidence. You can get better jobs. You can write posts, guides, and tweets that others will find interesting. &lt;/p&gt;

&lt;p&gt;In all, poor English is a potential hurdle for your career. And it's best to take care of it. I used to find this concept shallow but with time, I have made peace with it. Humans, after all, are imperfect and this is just one of many biases that affect us. &lt;/p&gt;

&lt;p&gt;Fortunately, getting better at English isn't much different from learning a programming language. It just takes practice.&lt;/p&gt;

&lt;p&gt;I wasn't any good at English, too and for a while, I wondered if I'll ever improve. Luckily, the fear was pretty unfounded. I believe that if you're constantly trying to level up, progress is a natural outcome. &lt;/p&gt;

&lt;p&gt;Looking back though, there're obvious ways I could've done it faster, and there were important lessons I learned too late. &lt;/p&gt;

&lt;p&gt;I mean to write this guide so you don't have to go through the same mistakes. I hope that the things I learned will help developers who are going through the same struggle. &lt;/p&gt;

&lt;h2&gt;
  
  
  It's Not Just About Grammar
&lt;/h2&gt;

&lt;p&gt;When we talk about English as a skill, our focus is usually on grammar. It took me a while to understand that grammar is only a part of the equation, and that &lt;strong&gt;memorizing the rules of English isn't that helpful&lt;/strong&gt;. English has tons of nuances in everything, which can only be learned by practice and exposure. Few examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence A&lt;/strong&gt;: The new Software doesn’t fulfill our requirements.&lt;br&gt;
&lt;strong&gt;Sentence B&lt;/strong&gt;: The new Software doesn’t have the things we need.&lt;/p&gt;

&lt;p&gt;Technically, both sentences are grammatically correct, but "fulfill our requirements" is overly formal and awkward. It's more suited for a business document than an everyday conversation. Sentence B is simpler and closer to what a native speaker would say.&lt;/p&gt;

&lt;p&gt;Another example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence A&lt;/strong&gt;: I have invariably loved you.&lt;br&gt;
&lt;strong&gt;Sentence B&lt;/strong&gt;: I have always loved you.&lt;/p&gt;

&lt;p&gt;If I look up &lt;em&gt;invariably&lt;/em&gt; in the dictionary, it'd be defined as "in every case or on every occasion; always." I might conclude that it can be used as a substitute for &lt;em&gt;always&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, the word usually applies to processes and objects (rarely people). If you use the word in the wrong context, it has the potential to sound very off. Understanding where a word fits takes time and a lot of reading (When in doubt, use the simplest word). &lt;/p&gt;

&lt;h2&gt;
  
  
  Three Parts of Fluency
&lt;/h2&gt;

&lt;p&gt;Becoming fluent in English means getting better on three fronts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Getting grammar right&lt;/strong&gt;: Perhaps, the most important part. People are much more forgiving about clumsy sentences but not that much towards getting tenses and verbs wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Knowing words and their appropriate usage&lt;/strong&gt;: Unfortunately, early learners often hold a terrible idea—that vocabulary is about knowing a lot of words. And as I have frequently observed, it creates room for using words poorly. Good vocabulary, as I wrote earlier, is not just about learning fancy words and their meanings, it's also knowing when to use them. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Composition&lt;/strong&gt;: If I had one word to describe good writing, it’ll be “effortless.” Good writing is a breeze to read and causes the fewest interruptions in the reader’s mind. To explain this, look at these two examples:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Macbeth was very ambitious. This led him to wish to become king of Scotland. The witches told him that this wish of his would come true. The king of Scotland at this time was Duncan. Encouraged by his wife, Macbeth murdered Duncan. He was thus enabled to succeed Duncan as king. (55 words.)&lt;/p&gt;

&lt;p&gt;Encouraged by his wife, Macbeth achieved his ambition and realized the prediction of the witches by murdering Duncan and becoming king of Scotland in his place. (26 words.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first sentence has too many interruptions and gives a feeling of being written by a novice. The latter is not just succinct, it’s far easier to read—it uses fewer pronouns and helps the reader avoid context-switching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't start with a grammar book
&lt;/h2&gt;

&lt;p&gt;Grammar books are a waste of time. I can write decent, but if you asked me what is 2nd or 3rd form of some X verb or asked me to explain past participle, I wouldn't have a clue.&lt;/p&gt;

&lt;p&gt;Think about it, when you speak your native language, do you ever think about what verb of what form you'd be using? &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%2Fuploads%2Farticles%2F1u5dka9wm1ocwptvt0zi.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%2F1u5dka9wm1ocwptvt0zi.png" alt="image" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diving into all the theory like these 4x4 tense tables, &lt;a href="http://www.butte.edu/departments/cas/tipsheets/grammar/parts_of_speech.html" rel="noopener noreferrer"&gt;parts of a sentence&lt;/a&gt;, &lt;a href="https://scoop.eduncle.com/active-and-passive-voice-rules" rel="noopener noreferrer"&gt;active/passive conversions&lt;/a&gt; has the potential to make you confused without any added value. No speaker learns by memorizing the rules. They just become a natural part of them. &lt;/p&gt;

&lt;p&gt;This is not to say knowing the rules isn't important. It would help you know the correct usage of certain prepositions, or when to use have/had, will/would, but my beef is with using a grammar book as the starting point.&lt;/p&gt;

&lt;p&gt;They are best suited as a reference. Use them when you're in doubt. &lt;/p&gt;

&lt;p&gt;This isn't much different from learning a programming language. Setting out to learn the syntax and the API—without writing any code—will inevitably become a boring grind with not much to show for it. Coding consistently will lead to much better results. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to actually get better?
&lt;/h2&gt;

&lt;p&gt;There's no magic bullet here. You learn by practice, which here means reading and writing. But here are a few pointers to help you out:&lt;/p&gt;

&lt;h3&gt;
  
  
  Read Everything
&lt;/h3&gt;

&lt;p&gt;Become a reading machine. This is the single most important thing to do. And I don't mean just books. Read everything. Read articles, and essays. Grab a respected online magazine and start reading their columns. Follow your favorite community (like, &lt;a href="https://news.ycombinator.com/" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt; or &lt;a href="https://www.reddit.com/r/AskHistorians/" rel="noopener noreferrer"&gt;Good subreddits&lt;/a&gt;) and see the debates and discussions. See how people communicate. Everything adds to your knowledge of how words can be used, and sentences can be formed.&lt;/p&gt;

&lt;p&gt;It’s okay if you don’t understand everything. Initially, I could only understand 20% of what I read. But pushing yourself to do this every day, it only gets better. &lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Videos and Podcasts
&lt;/h3&gt;

&lt;p&gt;Watch talks, documentaries, live conversations, podcasts, tutorials, they help you understand how people talk in real life. Videos/Podcasts also have an added advantage compared to reading: people communicate as they do every day, which means less fancy words.&lt;/p&gt;

&lt;p&gt;Movies and TV shows might not be the best options here, as the screenplay is often not written to mimic real-life conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Obsessisively
&lt;/h3&gt;

&lt;p&gt;Confused about something? Google it. Not a mighty new trick, but few people do it. I have resolved hundreds of word and grammar questions by searching for their usage. “have vs had,” “always vs invariably,” “simple vs simplistic.” Usually, you’ll get a good article explaining the correct usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Grammarly
&lt;/h3&gt;

&lt;p&gt;Much better than grammar books is a tool that'll correct your grammar and help you avoid the most common errors.&lt;/p&gt;

&lt;p&gt;I haven’t explored all the available options but it’s safe to say Grammarly is the best choice currently—wide support, detects errors reliably well, and offers a handy explanation in the tooltip. &lt;/p&gt;

&lt;p&gt;I would even say that you should get a &lt;a href="https://www.grammarly.com/plans" rel="noopener noreferrer"&gt;premium subscription&lt;/a&gt; (no affiliate link), which is totally worth it. The suggestions made by the premium subscription will help you sound more natural. &lt;/p&gt;

&lt;h3&gt;
  
  
  Have people who will correct you
&lt;/h3&gt;

&lt;p&gt;I was fortunate that I had folks around who would correct me if I made a mistake. Getting corrected might seem a little embarrassing (or even annoying) but trust me, it’s the best way to learn. Encouraging people to correct you is a shortcut to finding out your mistakes.&lt;/p&gt;

&lt;p&gt;Try to get more specific feedback. Usually, people pinpoint that your English has issues, but not knowing where the problem is can leave you scratching your head. Ask them what specific mistakes you've made. Where can you improve?&lt;/p&gt;

&lt;h3&gt;
  
  
  Write Regularly
&lt;/h3&gt;

&lt;p&gt;Write. Write. Write. It can just be a small opinion, or journal entry, or a story (if blogging is not your thing). Writing helps you lay down the idea and communicate clearly. Once you have a draft, go to someone whose opinion in writing you can trust and ask them to correct it without restraint. It could be your good friend, a partner, or a mentor. Don’t be disheartened if the mistakes are far more than you imagined, it’s only helping you improve.&lt;/p&gt;

&lt;p&gt;Revisit what you wrote earlier. Try to see the mistakes you made in your past write-ups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Be Clever
&lt;/h3&gt;

&lt;p&gt;This took me the longest to learn. I tried way too hard to be clever. Instead of writing "he ignored the warning signs", I wrote, "he snubbed the warning signs." Instead of sounding smart, I ended up giving the impression that I was an amateur trying to pretend I know more than I do. &lt;/p&gt;

&lt;p&gt;Most of the good writing I have seen doesn't use novel words frequently. Write simply! &lt;/p&gt;




&lt;p&gt;The biggest mistake you can make is to a) assume you won’t get better, and b) shy away from critical feedback. I made both and it only hampered my progress. The mind is surprisingly efficient at learning if you're constantly pushing yourself.&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>There's nothing wrong with inline styles</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Thu, 22 Apr 2021 04:47:28 +0000</pubDate>
      <link>https://dev.to/shubhamjain/there-s-nothing-wrong-with-inline-styles-26o7</link>
      <guid>https://dev.to/shubhamjain/there-s-nothing-wrong-with-inline-styles-26o7</guid>
      <description>&lt;p&gt;A frequent criticism leveled against TailwindCSS is that it's just a fancy way to write inline styles. Usually, people counter by saying you can't create a design system with inline styles or limit the number of options.&lt;/p&gt;

&lt;p&gt;However, I would say the idea is not far from the truth—TailwindCSS is just a nicer/shorter way to write inline styles, one that supports media queries and pseudo-elements as well.&lt;/p&gt;

&lt;p&gt;The earliest implementation of Tailwind's approach I saw was in &lt;a href="https://acss.io/" rel="noopener noreferrer"&gt;AtomicCSS&lt;/a&gt;. A framework I laughed off when I first came across it.&lt;/p&gt;

&lt;p&gt;Tailwind introduces a way to create a design system over pure inline styles, but overall the underlying ideas are the same. I see no reason why I won't be as productive with AtomicCSS as I am with Tailwind. &lt;/p&gt;

&lt;p&gt;Once you let go off the notion that inline styles are &lt;em&gt;inherently&lt;/em&gt; bad, you will become more accepting of Tailwind's ideas. &lt;/p&gt;

&lt;p&gt;In the ideal world, we will have a frozen set of design components and we will never have to write CSS except on very rare occasions. The components are updated rarely and there's no ambiguity about what belongs where.&lt;/p&gt;

&lt;p&gt;But the real world doesn't work that way. Here's what I have seen happen at companies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You write the same styles again and again (flex, font-sizes, spacing).&lt;/li&gt;
&lt;li&gt;You end up creating tens of container components that do the same thing. &lt;/li&gt;
&lt;li&gt;You try to generalize components, only for a new requirement to come in which throws your assumptions out the window. &lt;/li&gt;
&lt;li&gt;You create a Card component, but having to fulfill more and more requirements, you have made it so generic that in the end, it's just a white box with box-shadows.&lt;/li&gt;
&lt;li&gt;You want to reuse the style of the X component, but realize that your new component is called Y. So, you can't help copying the same styles again. &lt;/li&gt;
&lt;li&gt;The stylesheet has grown to more than a megabyte, most of it is composed of the same styling applied repeatedly.&lt;/li&gt;
&lt;li&gt;You want to use Modal component, but you see that it gives way too much padding. So, you write more styles to override them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These problems are quite universal. Unless your team is really small, writing CSS the way people idolize is extremely hard. Often, it never works. &lt;/p&gt;

&lt;p&gt;If the problem is so universal, maybe we ought to approach things differently.&lt;/p&gt;

&lt;p&gt;Inline styles solve it perfectly. You can use the styles you want without worrying about components. If you see a common component emerging, just extract it. The team won't waste time writing CSS for stupidly simple things, thinking names, and discussing how to modularize the CSS code. The evolution would be organic. &lt;/p&gt;

&lt;p&gt;Is it ideal? No, of course. But, seeing the real-world scenarios, it's much better than alternatives.&lt;/p&gt;

&lt;p&gt;It's just like refactoring. Time and time again, I have seen programmers who write duct-taped code, and try to clean it up later are much more productive than the ones who spend an entirety discussing the right approach. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/davidwalshblog/status/1098960128794128384" rel="noopener noreferrer"&gt;https://twitter.com/davidwalshblog/status/1098960128794128384&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even when I am not using TailwindCSS, I approach building the frontend solely using inline CSS. Once I have everything ready, I start to create the CSS classes. Because then, I have a much better idea of how to organize them.&lt;/p&gt;

&lt;p&gt;Inline styling is a tool that's needlessly been demonized. It's often much better than alternatives. And that's why TailwindCSS is winning. &lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tailwindcss</category>
      <category>opinion</category>
    </item>
    <item>
      <title>I analyzed my six years of food deliveries</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Sat, 17 Apr 2021 10:25:36 +0000</pubDate>
      <link>https://dev.to/shubhamjain/i-analyzed-my-six-years-of-food-deliveries-5fp4</link>
      <guid>https://dev.to/shubhamjain/i-analyzed-my-six-years-of-food-deliveries-5fp4</guid>
      <description>&lt;p&gt;Before food delivery apps came along, ordering food online was a pain. I started using &lt;a href="https://swiggy.com/" rel="noopener noreferrer"&gt;Swiggy&lt;/a&gt;, the Indian food delivery app, in 2016 and because it made it way too easy to get food delivered, my orders just went through the roof. I thought it will be fun to analyze how much and what have I ordered. &lt;/p&gt;

&lt;p&gt;There are two sections of this post: a) How I did it? b) The numbers and my analysis. Depending on your interest, you can skip either.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I did it?
&lt;/h2&gt;

&lt;p&gt;Swiggy doesn't have an API to get your personal data. However, it has a page where it lists your past orders. Trouble is, it will only show five orders at once, and you have to click "Show more orders" to go further back. Naturally, you have to automate it somehow. &lt;/p&gt;

&lt;h4&gt;
  
  
  Figuring out the source of data
&lt;/h4&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%2Fuploads%2Farticles%2F052bkkdlumjx3u2mix7t.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%2F052bkkdlumjx3u2mix7t.png" alt="Order Page XHR" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Order Page XHR&lt;/p&gt;

&lt;p&gt;I first logged in to the web version of the app since it will be comparatively easier to analyze the requests there. It seems the orders page makes an XHR request to the URL &lt;code&gt;/dapi/order/all?order_id=$$ORDER_ID$$&lt;/code&gt; to fetch the orders where &lt;code&gt;$$ORDER_ID$$&lt;/code&gt; is used for pagination.&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%2Fuploads%2Farticles%2Fxrwsotcow316yzf62bj3.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%2Fxrwsotcow316yzf62bj3.png" alt="Order Page Response" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Order Page Response&lt;/p&gt;

&lt;p&gt;The response is an array of JSON objects with a lot of fields.&lt;/p&gt;

&lt;p&gt;We don't need to figure out which parts of response we need to use, because we can store it all and see to that later.  &lt;/p&gt;

&lt;p&gt;I will use Postgres to store this data because a) it just works and b) has great support for querying JSON. Installing Postgres locally is really simple on Macs via the &lt;a href="https://postgresapp.com/" rel="noopener noreferrer"&gt;Postgres app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's the schema I will use: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;swiggy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Why do we just need two columns? Because &lt;code&gt;order_id&lt;/code&gt; is enough to uniquely identify every order and in the &lt;code&gt;data&lt;/code&gt; column we can dump the whole object. As I said earlier, Postgres makes it really easy to query JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the data
&lt;/h3&gt;

&lt;p&gt;Let's get the data! I will be using bash for this. "BASH???? ARGHHH. WHY???", you may ask. I used to have a similar aversion towards bash, but in the past year, I have realized it makes it really easy to do certain things once you get the hang of it. &lt;/p&gt;

&lt;p&gt;It's perfectly fine if you want to use a different approach as the basic ideas would be very much portable. Like, using &lt;code&gt;axios&lt;/code&gt; instead of &lt;code&gt;cURL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, the basic request. We need to figure out if a simple request for getting orders would work at all. The easiest way to do that is to "Copy as cURL" the request from the developer's console and run it in your terminal.&lt;/p&gt;

&lt;p&gt;If it works, that's great! You can start removing the unneeded parameters, like headers, user agent, and tracking cookies. After I did the trimming, the basic request to get orders boiled down to this: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl &lt;span class="nt"&gt;-sL&lt;/span&gt; &lt;span class="s2"&gt;"https://www.swiggy.com/dapi/order/all?order_id=&lt;/span&gt;&lt;span class="nv"&gt;$next_order_id&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"cookie: _session_tid=&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;where &lt;code&gt;$SESSION_ID&lt;/code&gt; is the long parameter visible in the first screenshot. &lt;/p&gt;

&lt;p&gt;Once the request works, we can parse the JSON and iterate over the objects using &lt;a href="https://stedolan.github.io/jq/" rel="noopener noreferrer"&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;order &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$all_orders&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'.data.orders[]'&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Why do we use &lt;code&gt;IFS=$'\n'&lt;/code&gt;? Because by default bash will split tabs and spaces too, and various names in the response (like restaurant, delivery person) can have spaces.&lt;/p&gt;

&lt;p&gt;Now, we just need to store it in the DB. And write code to fetch the next orders. In all, the whole script will be like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Your Swiggy Session ID, check screenshot #1 &lt;/span&gt;
&lt;span class="nv"&gt;SESSION_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"__SESSION_ID__"&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;all_orders&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-sL&lt;/span&gt; &lt;span class="s2"&gt;"https://www.swiggy.com/dapi/order/all?order_id=&lt;/span&gt;&lt;span class="nv"&gt;$next_order_id&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"cookie: _session_tid=&lt;/span&gt;&lt;span class="nv"&gt;$SESSION_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;order &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$all_orders&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'.data.orders[]'&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c"&gt;# We use $$ to wrap $order because it takes cares spaces in the data&lt;/span&gt;
        psql &lt;span class="s2"&gt;"postgres://shubhamjain@localhost/stats"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"
            INSERT INTO swiggy (order_id, data) VALUES (
               '&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.order_id'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;',
                &lt;/span&gt;&lt;span class="se"&gt;\$\$&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="se"&gt;\$\$&lt;/span&gt;&lt;span class="s2"&gt;
            );
        "&lt;/span&gt;
    &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;# Next order id would be order id of the last object in array&lt;/span&gt;
    &lt;span class="nv"&gt;next_order_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$all_orders&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.[-1].order_id'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After running this, you should see something like this:&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%2Fuploads%2Farticles%2Fqqxe8krjenmw6wkj5g59.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%2Fqqxe8krjenmw6wkj5g59.png" alt="Shell Script Execution" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point, it will start failing, which means it has reached the end and you can quit the script then. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: None of this is the ideal way to do things. I wasn't interested in programming properly, only hacking together something cool. &lt;/p&gt;

&lt;h2&gt;
  
  
  Six years in numbers
&lt;/h2&gt;

&lt;p&gt;Cool! Now we have the data. Let's jump to answering questions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Q.1: How much I have ordered?
&lt;/h4&gt;

&lt;p&gt;A LOT! I knew I was ordering a ton of times, but I never put a number on it. Actually doing that, with this project, I was taken aback realizing the number of orders I have made and the money I have spent.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'year'&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'order_time'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;year&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;swiggy&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total orders&lt;/strong&gt;: 915&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%2Fuploads%2Farticles%2Fgshrkscp80qersip6f6h.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%2Fgshrkscp80qersip6f6h.png" alt="image" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Year vs. # of orders&lt;/p&gt;

&lt;p&gt;How much I have spent?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
   &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'order_total_with_tip'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;DOUBLE&lt;/span&gt; &lt;span class="nb"&gt;PRECISION&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
   &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'year'&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'order_time'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="n"&gt;swiggy&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total spent&lt;/strong&gt;: ₹1,84,329&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%2Fuploads%2Farticles%2F0jdr3dwapzlubtc5zcp9.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%2F0jdr3dwapzlubtc5zcp9.png" alt="image" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Restaurant vs. # of orders&lt;/p&gt;

&lt;p&gt;That seems to a lot of money. Enough to buy a decent second-hand car, at least.&lt;/p&gt;

&lt;h4&gt;
  
  
  Q.2: Where do I order from?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Pareto_principle" rel="noopener noreferrer"&gt;Pareto Principle&lt;/a&gt; seems to apply very well here. Most of my orders are for a cafe called &lt;em&gt;Chai Shai&lt;/em&gt;. I love ordering from there—it has good snacks and everything is well-packaged. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
   &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'restaurant_name'&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="n"&gt;swiggy&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuploads%2Farticles%2F2nntbi6flenj7eszaaeg.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%2F2nntbi6flenj7eszaaeg.png" alt="image" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Restaurant vs. money spent on orders&lt;/p&gt;

&lt;h4&gt;
  
  
  Q.3: When do I order?
&lt;/h4&gt;

&lt;p&gt;It seems I order more during the morning and afternoon than in the evening. That can be explained by the fact that I often don't feel that hungry in the evening and I prefer something light for dinner.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
   &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hour'&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="n"&gt;TO_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'order_time'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'YYYY-MM-DD hh24:mi:ss'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="n"&gt;swiggy&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuploads%2Farticles%2F0h5tz1b8epij7u17e3oh.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%2F0h5tz1b8epij7u17e3oh.png" alt="image" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hour of the day vs. # of orders&lt;/p&gt;

&lt;h4&gt;
  
  
  Q.4 What do I order?
&lt;/h4&gt;

&lt;p&gt;It seems I am fond of ordering for a quick bite and desserts than a full meal. Desserts are something I should definitely cut down on. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
   &lt;span class="n"&gt;cuisine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;SELECT&lt;/span&gt;
         &lt;span class="n"&gt;JSONB_ARRAY_ELEMENTS_TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'restaurant_cuisine'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;cuisine&lt;/span&gt; 
      &lt;span class="k"&gt;FROM&lt;/span&gt;
         &lt;span class="n"&gt;swiggy&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;1&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuploads%2Farticles%2Fc246ro5rw9gn6h0utgss.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%2Fc246ro5rw9gn6h0utgss.png" alt="image" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cuisine vs. # of orders&lt;/p&gt;
 

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It was an interesting exercise to understand my habits over the years. There are tons of ways I can dig more into the data but for now, I will stop here. Insight fatigue isn't great either.&lt;/p&gt;

&lt;p&gt;I don't think ordering is necessarily bad but it's lazy. Knowing the scale of my habit, I know it would help me to make a little conscious effort to order less. &lt;/p&gt;

</description>
      <category>coding</category>
      <category>bash</category>
      <category>data</category>
      <category>sql</category>
    </item>
    <item>
      <title>A better way to use SVGs</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Sun, 04 Apr 2021 09:31:43 +0000</pubDate>
      <link>https://dev.to/shubhamjain/a-better-way-to-use-svgs-1mg9</link>
      <guid>https://dev.to/shubhamjain/a-better-way-to-use-svgs-1mg9</guid>
      <description>&lt;p&gt;It's 2021, and we are still not settled on the best way to SVGs. Inline SVGs offer all the benefits—being able to directly modify fill color, use CSS variables, and modify the inner SVG elements—but have the obvious downside that they make the code messy.&lt;/p&gt;

&lt;p&gt;Storing them externally is a better option, but the only reliable way to use them is the &amp;lt;img&amp;gt; tag, which comes with severe limitations. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="c"&gt;&amp;lt;!-- Can't modify the fill color if you want --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/path/to/img.svg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To solve this, I have created a library that offers all the benefits of inline SVGs, while still storing them externally. It's called &lt;a href="https://github.com/shubhamjain/svg-loader" rel="noopener noreferrer"&gt;svg-loader&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check, for example, this logo of &lt;a href="https://svgbox.net" rel="noopener noreferrer"&gt;my project&lt;/a&gt; in SVG.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/assets/logo-white.svg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Preview&lt;/strong&gt;&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%2Fs2.svgbox.net%2Fassets%2Flogo-white.svg" 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%2Fs2.svgbox.net%2Fassets%2Flogo-white.svg" width="100" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the fill color is not defined, it will default to black and there's not much you can do about changing that. There are a few &lt;a href="https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters" rel="noopener noreferrer"&gt;hacks around this using the filter property&lt;/a&gt;, but they are complex and not easy to modify. &lt;/p&gt;

&lt;p&gt;In comes, &lt;a href="https://github.com/shubhamjain/svg-loader" rel="noopener noreferrer"&gt;svg-loader&lt;/a&gt;. You just have to drop the script in and the external SVGs will be fetched and injected inside the element. Like, this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/external-svg-loader@1.0.0/svg-loader.min.js"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:flex;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:black;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;data-src=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/assets/logo-white.svg"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"yellow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:purple;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;data-src=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/assets/logo-white.svg"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:green;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;data-src=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/assets/logo-white.svg"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Preview&lt;/strong&gt;&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%2Fuploads%2Farticles%2Fwqxcuvve6ha4hm0betvr.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%2Fwqxcuvve6ha4hm0betvr.png" alt="Alt Text" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jsfiddle.net/ofd58uve/" rel="noopener noreferrer"&gt;View on JS Fiddle&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The library is very light &amp;lt;2KB (post-compression). The loads are lightning fast and also comes with a way to cache the file for longer. So, the image isn't fetched repeatedly. And pretty much works anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compatible with React, Vue, Angular
&lt;/h2&gt;

&lt;p&gt;svg-loader is framework agnostic and works with most front-end frameworks. You just need to include the library somewhere and everything else will be handled:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;external-svg-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;
        &lt;span class="na"&gt;data-src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://s2.svgbox.net/materialui.svg?ic=mail"&lt;/span&gt;
        &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"currentColor"&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50px"&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50px"&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;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="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/react-playground-forked-x7w1l?file=/index.js" rel="noopener noreferrer"&gt;&lt;strong&gt;View on Codesandbox&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The resources need to be compatible with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener noreferrer"&gt;CORS policy&lt;/a&gt; since XHR is used to fetch them.&lt;/p&gt;

&lt;p&gt;Thoughts? Questions? Feel free to reply here.&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>react</category>
      <category>vue</category>
    </item>
    <item>
      <title>Simpler Way To Conditionally Add Properties to Javascript Object</title>
      <dc:creator>Shubham Jain</dc:creator>
      <pubDate>Sun, 07 Feb 2021 06:20:23 +0000</pubDate>
      <link>https://dev.to/shubhamjain/simpler-way-to-conditionally-add-properties-to-javascript-object-22j</link>
      <guid>https://dev.to/shubhamjain/simpler-way-to-conditionally-add-properties-to-javascript-object-22j</guid>
      <description>&lt;p&gt;&lt;a href="https://magecdn.com/?ref=dev.to"&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%2F67ktjfitpn7c48wbgh1o.png" alt="" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Ever had a situation where you wanted to conditionally add an attribute to a javascript object and you had to use &lt;code&gt;let&lt;/code&gt; instead of &lt;code&gt;const&lt;/code&gt; and add an if condition just because of that? I am talking about this:&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;let&lt;/span&gt; &lt;span class="nx"&gt;userProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rad-coder&lt;/span&gt;&lt;span class="dl"&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;userIsBanned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;userProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;banned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;userProps&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the above code, if there was no conditional attribute, &lt;code&gt;userProps&lt;/code&gt; wouldn't have been needed. If there are multiple attributes like that, that means more if conditions and code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Simpler Alternative
&lt;/h2&gt;

&lt;p&gt;Instead of using the if statement, you can use the spread operator. The idea is simple: the spread operator merges the properties of the target object with the object it's being applied on and if the source object is null, it adds no properties. &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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...{&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; x = { a : 2 }&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; y = {}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we can use the same idea to simplify our code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rad-coder&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;userIsBanned&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;banned&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;And if there are multiple conditions:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;return {&lt;br&gt;
   username: "rad-coder",&lt;br&gt;
   ...(userIsBanned &amp;amp;&amp;amp; {banned: true}),&lt;br&gt;
   ...(userIsOrganic &amp;amp;&amp;amp; {organic: true}),&lt;br&gt;
   ...(userIsPaid &amp;amp;&amp;amp; {paid: true}),&lt;br&gt;
}&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  "Code is Harder to Read!"&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;I know some folks would say that this just makes code harder to read and is needlessly clever. And maybe that's right.&lt;/p&gt;

&lt;p&gt;I personally find it a nifty trick to avoid writing more code than that's needed, but some developers might not feel that way, which makes its usefulness subjective.&lt;/p&gt;

&lt;p&gt;So, use it if only you think it's a good choice. &lt;/p&gt;

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