<?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: Yash Soni</title>
    <description>The latest articles on Forem by Yash Soni (@iyashsoni).</description>
    <link>https://forem.com/iyashsoni</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%2F138880%2F15ef483d-36d6-4598-9208-8184b41e9dc6.jpg</url>
      <title>Forem: Yash Soni</title>
      <link>https://forem.com/iyashsoni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/iyashsoni"/>
    <language>en</language>
    <item>
      <title>JavaScript - debounce vs throttle ⏱</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Fri, 02 Oct 2020 04:27:31 +0000</pubDate>
      <link>https://forem.com/iyashsoni/javascript-debounce-vs-throttle-392i</link>
      <guid>https://forem.com/iyashsoni/javascript-debounce-vs-throttle-392i</guid>
      <description>&lt;p&gt;There's been a lot of confusion around what is debouncing and throttling, where to use it, and how it exactly works.&lt;/p&gt;

&lt;p&gt;We are going to demystify all of the above in the simplest possible way through this article.&lt;/p&gt;

&lt;p&gt;It is important to know both of these, it will make our lives easier in certain scenarios. (Bonus: This is a common interview question too) 🥳&lt;/p&gt;




&lt;p&gt;Simply put,&lt;br&gt;
&lt;code&gt;Throttling&lt;/code&gt; is a way to limit the number of times a function can be called. Perform a function, then drop all the function calls until a certain period of time, &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Debouncing&lt;/code&gt; is a way to delay the execution of a function to a later period until there is some ongoing action.&lt;/p&gt;

&lt;p&gt;These both might seem confusing, overlapping, almost the same thing - but they are not! We will sort this out.&lt;/p&gt;

&lt;p&gt;There's no better way to learn something than learning by example. 👩‍💻👨‍💻&lt;/p&gt;


&lt;h3&gt;
  
  
  Throttling:
&lt;/h3&gt;

&lt;p&gt;Imagine there's a button "Fetch Quote". When you click it, it triggers an asynchronous API call to fetch the quote and render it on the screen.&lt;/p&gt;

&lt;p&gt;Now, what will happen if some nutjob keeps clicking it furiously - like a million clicks till his/her fingers give up. 😑&lt;/p&gt;

&lt;p&gt;In that case, without any controlling mechanism, it will trigger a million API calls (intentionally over-exaggerated!)&lt;br&gt;
This would cause a performance drop. &lt;/p&gt;

&lt;p&gt;You can avoid this if you had some kind of click rate-limiter in place. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Throttle swaggers-in&lt;/strong&gt; 😎&lt;/p&gt;

&lt;p&gt;How does it work?&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%2Ffxyumhcu7zjebje8gmaa.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%2Ffxyumhcu7zjebje8gmaa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the CodePen for the "Fetch Quote" example. Play around this a bit.&lt;/p&gt;

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




&lt;h3&gt;
  
  
  Debouncing:
&lt;/h3&gt;

&lt;p&gt;Remember how the search-suggestions work? Like, when you start typing into the Google search bar it keeps on updating its suggestion list.&lt;/p&gt;

&lt;p&gt;These suggestions are actually brought from an API call. So, the question is, should you make a fresh API call every time the text changes in the input box?&lt;/p&gt;

&lt;p&gt;No, right? That would be super-bad for Google. Imagine you type "How to write better JavaScript" - 30 characters itself, leading to 30 API calls. Now imagine, millions and billions of Googlers around the world typing their queries every second - BAMMMMM!!! 💥&lt;/p&gt;

&lt;p&gt;So how do you handle this? &lt;/p&gt;

&lt;p&gt;Before we answer that, do we really need to make an API call if the user is still typing? No. We should wait till the user has halted typing for at least some amount of time before we make an API call.&lt;/p&gt;

&lt;p&gt;This can be achieved using, yeah you guessed it right, &lt;strong&gt;Debouncing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As we stated earlier, debouncing is a way to delay the execution of a function to a later period until there is some ongoing action.&lt;/p&gt;

&lt;p&gt;The following CodePen illustrates exactly the same.&lt;/p&gt;

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




&lt;h3&gt;
  
  
  Bonus part: Understanding the nitty-gritty 💸
&lt;/h3&gt;

&lt;p&gt;Let's see the function definitions of &lt;code&gt;debounce&lt;/code&gt; and &lt;code&gt;throttle&lt;/code&gt; in detail.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Throttle&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const throttle = (func, delay) =&amp;gt; { 
  let toThrottle = false;
  return function() { 
    if(!toThrottle) {
      toThrottle = true;
      func.apply(this,arguments)
      setTimeout(() =&amp;gt; {
        toThrottle = false
      }, delay);
    }
  }; 
};

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Debounce&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const debounce = (func, delay) =&amp;gt; { 
  let timerId; 
  return function() { 
    clearTimeout(timerId) 
    timerId = setTimeout(() =&amp;gt; func.apply(this,arguments), delay)
  }; 
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the definition, we can clearly see that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Throttle allows execution &lt;strong&gt;immediately&lt;/strong&gt; if the &lt;code&gt;toThrottle&lt;/code&gt; flag is false. After the execution, this function will not be called until the &lt;code&gt;delay&lt;/code&gt; period has lapsed.&lt;/li&gt;
&lt;li&gt;Debounce &lt;strong&gt;postpones&lt;/strong&gt; execution until there is no input change for the &lt;code&gt;delay&lt;/code&gt; period of time. If a change occurs, cancel the previously scheduled execution and create a new schedule.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;P.S. This article requires a prior understanding of closures, this, call, apply in JavaScript. I'm dropping a recommended reading list below to help sharpen this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.taniarascia.com/this-bind-call-apply-javascript/" rel="noopener noreferrer"&gt;Understanding Bind, Call, Apply in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.taniarascia.com/this-bind-call-apply-javascript/" rel="noopener noreferrer"&gt;Understanding setTimeout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.skay.dev/understanding-closures" rel="noopener noreferrer"&gt;Understanding Closures&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Share this article if you liked it! &lt;br&gt;
Follow on Twitter for more posts, quizzes and articles on Tech. 😃👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JavaScript Promise Combinators - in 3 mins!</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Tue, 01 Sep 2020 09:35:59 +0000</pubDate>
      <link>https://forem.com/iyashsoni/javascript-promise-combinators-in-3-mins-52b3</link>
      <guid>https://forem.com/iyashsoni/javascript-promise-combinators-in-3-mins-52b3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In Software Development, &lt;strong&gt;Parallelism&lt;/strong&gt; is the key to better performance. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It means to carry out long-running asynchronous operations in parallel rather than serially (whenever possible). &lt;/p&gt;

&lt;h3&gt;
  
  
  Preface:
&lt;/h3&gt;

&lt;p&gt;Imagine you have to fetch quotes using a REST API, and there are 7 different categories of quotes you want to have (eg. life, love, inspirational, etc). Assume each API call takes 1 sec to give back a response. &lt;/p&gt;

&lt;p&gt;Now let's say, you want to have all 7 quotes before you show it on UI. How would you address this?&lt;/p&gt;

&lt;p&gt;If you call it serially, it will take 7 seconds total (1 for each category).&lt;/p&gt;

&lt;p&gt;But these tasks are not related, meaning the order of their execution is not important, hence they can be carried out in parallel. &lt;/p&gt;

&lt;p&gt;JavaScript has a fun way to deal with such scenarios using &lt;strong&gt;Promise Combinators&lt;/strong&gt;. &lt;/p&gt;




&lt;h3&gt;
  
  
  What are Promise Combinators?
&lt;/h3&gt;

&lt;p&gt;Promise Combinators, as I understand, are utility methods to deal with multiple promises that need to be executed in parallel. &lt;/p&gt;

&lt;p&gt;Each combinator method takes in an array of promises as an argument.&lt;/p&gt;

&lt;p&gt;Each combinator method in-turn returns a Promise.&lt;/p&gt;

&lt;p&gt;Let's explore them one-by-one. 🤓&lt;/p&gt;




&lt;h3&gt;
  
  
  Promise.all()
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is the most used kind of combinator. An example scenario will be the one discussed above - get multiple Quotes in parallel.&lt;/li&gt;
&lt;li&gt;IMPORTANT: all() will &lt;strong&gt;settle&lt;/strong&gt; if &lt;em&gt;all&lt;/em&gt; the supplied promises have &lt;strong&gt;fulfilled&lt;/strong&gt;, or if &lt;em&gt;any&lt;/em&gt; of them is &lt;strong&gt;rejected&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Always surround call to Promise.all() by &lt;code&gt;try { ... } catch(e) { ... }&lt;/code&gt; blocks.&lt;/li&gt;
&lt;li&gt;When we &lt;code&gt;await&lt;/code&gt; Promise.all(), the result will be an array of objects returned for each promise supplied.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Promise.race()
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is mostly used in conditions where we want to race the execution of promises against time. An example would be, "Get me all the quotes within 500ms or you fail".&lt;/li&gt;
&lt;li&gt;This is not at all limited to just race against time, it can also be a race between many asynchronous operations.&lt;/li&gt;
&lt;li&gt;IMPORTANT: race() will &lt;strong&gt;settle&lt;/strong&gt; if &lt;em&gt;any&lt;/em&gt; of the supplied promises have &lt;strong&gt;fulfilled&lt;/strong&gt; or &lt;strong&gt;rejected&lt;/strong&gt;. Meaning, the race will terminate after first success or failure.&lt;/li&gt;
&lt;li&gt;Always a good practice to surround Promise.race() call by &lt;code&gt;try { ... } catch(e) { ... }&lt;/code&gt; blocks.&lt;/li&gt;
&lt;li&gt;When we &lt;code&gt;await&lt;/code&gt; Promise.race(), the result will be the return value of the first settled promise.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Tip: Play around with the timeout value in &lt;code&gt;raceToGetData(500);&lt;/code&gt; to see a different result. Try 10 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  Promise.allSettled()
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introduced in ES2020, &lt;code&gt;allSettled&lt;/code&gt; combinator should be used when the result of each promise supplied doesn't matter (either fulfilled or rejected), but still want to execute each one of it.&lt;/li&gt;
&lt;li&gt;IMPORTANT: allSettled() will &lt;strong&gt;settle&lt;/strong&gt; when &lt;em&gt;all&lt;/em&gt; the supplied promises are &lt;strong&gt;settled&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When we &lt;code&gt;await&lt;/code&gt; Promise.allSettled(), the result will be an array of result values of all the settled promises.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Promise.any()
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introduced in ES2021, &lt;code&gt;any&lt;/code&gt; combinator should be used when you want the result of the first fulfilled promise.&lt;/li&gt;
&lt;li&gt;The only difference from race combinator is that the promise rejections are neglected here.&lt;/li&gt;
&lt;li&gt;IMPORTANT: any() will &lt;strong&gt;settle&lt;/strong&gt; when &lt;em&gt;any&lt;/em&gt; of the supplied promise is &lt;strong&gt;fulfilled&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When we &lt;code&gt;await&lt;/code&gt; Promise.any(), the result will be the result of the first fulfilled promise. If all promises are rejected, then an error will be thrown.&lt;/li&gt;
&lt;li&gt;Hence, it becomes important to surround Promise.any() call by &lt;code&gt;try { ... } catch(e) { ... }&lt;/code&gt; blocks.&lt;/li&gt;
&lt;/ul&gt;

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




&lt;p&gt;P.S.: Check the browser support for any() and allSettled() combinators as they are relatively new. all() and race() are widely supported across all major browser platforms.&lt;/p&gt;

&lt;p&gt;Let me know what you guys think! 💬&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="http://twitter.com/iYash_Soni"&gt;Twitter&lt;/a&gt; for some awesome JavaScript tips and quizzes. Likes &amp;amp; Shares are highly appreciated! ❤️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/i6hulbv7glgFq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/i6hulbv7glgFq/giphy.gif" alt="" width="300" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building Web Extensions with Reactjs - from 0 to publish!</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Mon, 29 Jun 2020 08:08:33 +0000</pubDate>
      <link>https://forem.com/iyashsoni/building-web-extensions-with-reactjs-from-0-to-publish-54no</link>
      <guid>https://forem.com/iyashsoni/building-web-extensions-with-reactjs-from-0-to-publish-54no</guid>
      <description>&lt;p&gt;Web Extensions - you might have heard of it, most probably you're already using it - example? AdBlock, Grammarly, Save to Pocket, etc. In this article, we will build a Web Extension from scratch using Reactjs.&lt;/p&gt;

&lt;p&gt;We are going to bake a &lt;strong&gt;New Tab Greeting Extension&lt;/strong&gt; and publish it on &lt;code&gt;Chrome Web Store&lt;/code&gt; and &lt;code&gt;Firefox Addon Dashboard&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/64aBXTVfd90zyUH2da/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/64aBXTVfd90zyUH2da/giphy.gif" alt="" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1 - Creating the App:
&lt;/h3&gt;

&lt;p&gt;Let's create a React app with &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html"&gt;CRA&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app greetings-web-extension&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd greetings-web-extension&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's do some quick cleanup:&lt;br&gt;
Under the &lt;code&gt;src&lt;/code&gt; folder, remove everything else other than &lt;code&gt;App.js&lt;/code&gt;, &lt;code&gt;index.js&lt;/code&gt;, and &lt;code&gt;index.css&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From the &lt;code&gt;public&lt;/code&gt; folder - remove everything else other than &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;favicon.ico&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the end, we should have the following directory structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;greetings-web-extension

&lt;ul&gt;
&lt;li&gt;node_modules&lt;/li&gt;
&lt;li&gt;public

&lt;ul&gt;
&lt;li&gt;favicon.ico&lt;/li&gt;
&lt;li&gt;index.html&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;src

&lt;ul&gt;
&lt;li&gt;App.js&lt;/li&gt;
&lt;li&gt;index.css&lt;/li&gt;
&lt;li&gt;index.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;.gitignore&lt;/li&gt;
&lt;li&gt;package.json&lt;/li&gt;
&lt;li&gt;README.md&lt;/li&gt;
&lt;li&gt;others&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2 - Preparing the App:
&lt;/h3&gt;

&lt;p&gt;Quickly modify a few files as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/src/index.js
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

ReactDOM.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
  document.getElementById("root")
);

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;/src/index.css
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html,
body,
#root {
  height: 100%;
}

body {
  margin: 0;
  text-align: center;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.App {
  height: 100%;
  background: linear-gradient(to bottom right, #7b4397, #dc2430);
  color: white;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;/src/App.js
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const greetings = {
  morning: "Good morning",
  noon: "Good afternoon",
  evening: "Good evening",
  night: "Good night",
};
class App extends React.Component {
  constructor() {
    super();
    this.state = {
      greeting: greetings.morning,
    };
    this.startTime = this.startTime.bind(this);
  }

  componentDidMount() {
    this.startTime();
  }

  startTime() {
    let today = new Date();
    let h = today.getHours();
    let greeting;
    if (h &amp;gt; 6 &amp;amp;&amp;amp; h &amp;lt; 12) {
      greeting = greetings.morning;
    } else if (h &amp;gt;= 12 &amp;amp;&amp;amp; h &amp;lt; 17) {
      greeting = greetings.noon;
    } else if (h &amp;gt;= 17 &amp;amp;&amp;amp; h &amp;lt; 20) {
      greeting = greetings.evening;
    } else {
      greeting = greetings.night;
    }
    this.setState({ greeting });
    setTimeout(this.startTime, 1000);
  }

  render() {
    return (
      &amp;lt;div className="App"&amp;gt;
        &amp;lt;h1&amp;gt;{this.state.greeting}&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;/public/index.html
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset="utf-8" /&amp;gt;
  &amp;lt;link rel="icon" href="%PUBLIC_URL%/favicon.ico" /&amp;gt;
  &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1" /&amp;gt;
  &amp;lt;meta name="theme-color" content="#000000" /&amp;gt;
  &amp;lt;meta name="description" content="Web site created using create-react-app" /&amp;gt;
  &amp;lt;title&amp;gt;Greetings&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;noscript&amp;gt;You need to enable JavaScript to run this app.&amp;lt;/noscript&amp;gt;
  &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 3 - Testing React App:
&lt;/h3&gt;

&lt;p&gt;Let's do a quick test of what we have at hand. &lt;br&gt;
Fire it up with &lt;code&gt;npm start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should see something like this in your browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vUdAnHMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/z4e4a86335psnh4qo9qy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vUdAnHMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/z4e4a86335psnh4qo9qy.png" alt="Greetings Screenshot" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4 - preparing the Web Extension:
&lt;/h3&gt;

&lt;p&gt;The first thing we need is a &lt;code&gt;manifest.json&lt;/code&gt; file - which is a descriptor file for the web extension we are building.&lt;/p&gt;

&lt;p&gt;Create a directory &lt;code&gt;extras&lt;/code&gt;, create a new file &lt;code&gt;manifest.json&lt;/code&gt; under it and Copy/Paste the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "greetings",
  "offline_enabled": true,
  "short_name": "greetings",
  "description": "Everyday greetings",
  "version": "1.0.0",
  "chrome_url_overrides": {
    "newtab": "index.html"
  },
  "manifest_version": 2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;offline_enabled: duh!&lt;/li&gt;
&lt;li&gt;chrome_url_overrides: we want this extension to override our &lt;code&gt;newtab&lt;/code&gt; with the &lt;code&gt;index.html&lt;/code&gt;. Hence...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's create a build for our react-app:&lt;br&gt;
&lt;code&gt;INLINE_RUNTIME_CHUNK=false react-scripts build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why &lt;code&gt;INLINE_RUNTIME_CHUNK=false&lt;/code&gt;?&lt;br&gt;
Because if we don't do this, the final &lt;code&gt;index.html&lt;/code&gt; will contain an inline script as a result of the build process. Extension recommends using external scripts and discourages using the inline script. With &lt;code&gt;INLINE_RUNTIME_CHUNK&lt;/code&gt; env variable, we will bypass the above-mentioned issue.&lt;/p&gt;

&lt;p&gt;The above command will result in a &lt;code&gt;build&lt;/code&gt; folder generated at the root of our project.&lt;/p&gt;

&lt;p&gt;Now, Copy/Paste the &lt;code&gt;manifest.json&lt;/code&gt; file we created into this new build folder. (Why didn't we create the file inside the build folder directly? Because the build folder is purged and re-created every time you run the build commands. Hence keeping it under &lt;code&gt;extras&lt;/code&gt;.)&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 5 - testing the Extension:
&lt;/h3&gt;

&lt;p&gt;Now fire up Chrome Browser, go to &lt;code&gt;chrome://extensions/&lt;/code&gt; and enable Developer mode.&lt;/p&gt;

&lt;p&gt;Now click on the &lt;code&gt;Load unpacked&lt;/code&gt; Button and point to the build folder of our project.&lt;/p&gt;

&lt;p&gt;Test by opening a new tab in Chrome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Y3RqktJpqtVl9bs4Ee/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Y3RqktJpqtVl9bs4Ee/giphy.gif" alt="" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 6 - packaging for Chrome and Firefox:
&lt;/h3&gt;

&lt;p&gt;Chrome packaging is simply a zip command. &lt;br&gt;
Firefox packaging can be done using a recommended tool called &lt;a href="https://www.npmjs.com/package/web-ext"&gt;web-ext&lt;/a&gt;. Install this globally using &lt;code&gt;npm i -g web-ext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To help you eliminate the manual steps of copying/pasting manifest.json file, running commands for Firefox and Chrome packaging, etc. I have created a small &lt;code&gt;node.js&lt;/code&gt; script that does the job. &lt;/p&gt;

&lt;p&gt;Create a new file at the root of the project, let's call it &lt;code&gt;buildPackage.js&lt;/code&gt;. Put the following content into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { execSync } = require("child_process");

// FILENAMES
const manifestFileName = "manifest.json";

// DIRECTORIES
const buildDir = "./build/";
const extensionDir = "./extras/";
const outputs = "./";

// OUTPUTS
const chromeOutput = "greetings-chrome.zip";

console.log("Building Extension Packages");

console.log("***COPYING MANIFEST FILE***\n\n");
execSync(
  `cp ${extensionDir}${manifestFileName} ${buildDir}${manifestFileName}`
);

execSync(`zip -r ${outputs}${chromeOutput} ${buildDir}`);
console.log("***CHROME BUILT SUCCESSFULLY***\n\n");

execSync(`web-ext build -s ${buildDir} -a ${outputs} --overwrite-dest`);
console.log("***FIREFOX BUILT SUCCESSFULLY***");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;code&gt;package.json&lt;/code&gt; to run this script as a part of build process. In &lt;code&gt;package.json&lt;/code&gt; under &lt;strong&gt;scripts&lt;/strong&gt; tag, modify as shown:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"build": "INLINE_RUNTIME_CHUNK=false react-scripts build &amp;amp;&amp;amp; node buildPackage.js",&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now trigger the build script using &lt;code&gt;npm run build&lt;/code&gt; and you should see 2 new files created at the root of the project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;greetings-chrome.zip // for Chrome&lt;/li&gt;
&lt;li&gt;greetings-1.0.0.zip // for Firefox&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 7 - Publishing:
&lt;/h3&gt;

&lt;p&gt;Chrome:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://chrome.google.com/webstore/devconsole/"&gt;Google Chrome Developer Dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sign in with your Google account or create a new one&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;+ New Item&lt;/strong&gt; Button&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;greetings-chrome.zip&lt;/code&gt; file created in the previous step&lt;/li&gt;
&lt;li&gt;Fill up the required details and submit for review&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(Usually takes around 12 hours to publish)&lt;/p&gt;

&lt;p&gt;Firefox:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://addons.mozilla.org/en-US/developers/addons"&gt;Mozilla Add-ons Dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sign in with your Mozilla account or create a new one&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Submit a New Add-on&lt;/strong&gt; Button&lt;/li&gt;
&lt;li&gt;For distribution, select &lt;code&gt;On this site&lt;/code&gt; and continue&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;greetings-1.0.0.zip&lt;/code&gt; file created in the previous step&lt;/li&gt;
&lt;li&gt;Fill up the required details and submit for review&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(Usually takes around 6-10 mins to publish)&lt;/p&gt;




&lt;p&gt;Final notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need an icon for your extension, create one icon of size 128x128 (name it icon_128.png), and put it in the build directory. Add the following to &lt;code&gt;manifest.json&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "icons": {
    "128": "icon_128.png"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In some cases, your Web Extension might need to store and retrieve data. Though you can use browser localStorage, it is highly discouraged for Web Extension. Instead, you should use a designated DB storage area for extensions which is more reliable. Read more &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;This is a very basic extension that we created, generally, it can be a bit more complicated - with API calls, Storage, Background scripts, etc. All of this is possible!&lt;/li&gt;
&lt;li&gt;Try and keep the Web Extension light - meaning an Extension should load fast, should serve a single purpose, should be accessible, etc.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I've created a Web Extension for Chrome and Firefox - &lt;a href="https://minimylist.netlify.app"&gt;minimylist&lt;/a&gt;. Do check it out and share it if you liked.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O3twk0Og--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/media/EaYPEj1UYAE9n1o.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--k4UumEs5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/profile_images/1266589776909647884/e1AzhmZi_normal.jpg" alt="Yash Soni profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Yash Soni
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @iyash_soni
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kDgU_xDI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Is Dark Mode your poison?&lt;br&gt;minimylist - new update live. 👨‍💻👩‍💻&lt;br&gt;&lt;br&gt;Download now:&lt;br&gt;Chrome: &lt;a href="https://t.co/d057Lrts3p"&gt;rb.gy/vdhlo2&lt;/a&gt;&lt;br&gt;Firefox: &lt;a href="https://t.co/kD6vJmg0yd"&gt;rb.gy/ot5bba&lt;/a&gt; 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      08:26 AM - 13 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1271720528428974080" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OXOJJiQT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1271720528428974080" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--foTp-unf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1271720528428974080" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SFHqU4bF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;





&lt;p&gt;Until next time, Ciao! 👋🏻&lt;br&gt;
&lt;a href="https://i.giphy.com/media/l4Ki0UwC89tEUahnW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4Ki0UwC89tEUahnW/giphy.gif" alt="" width="546" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introducing minimylist - productivity assistant! 👨‍💻👩‍💻</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Thu, 11 Jun 2020 20:05:40 +0000</pubDate>
      <link>https://forem.com/iyashsoni/introducing-minimylist-productivity-assistant-kde</link>
      <guid>https://forem.com/iyashsoni/introducing-minimylist-productivity-assistant-kde</guid>
      <description>&lt;p&gt;Every developer, literally every developer, dreams of building something that will help boost their productivity. &lt;/p&gt;

&lt;p&gt;Well, last weekend I made that. Hopefully, it will make me (and other users) productive. 👻&lt;/p&gt;




&lt;h3&gt;
  
  
  Requirement Analysis 🤪
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It should be easy to use - most important! 😇&lt;/li&gt;
&lt;li&gt;Design should be !ugly - wait, this is most important! 🎨&lt;/li&gt;
&lt;li&gt;Should have DARK theme - I'm a fan 🖤&lt;/li&gt;
&lt;li&gt;Simple Notes feature - to hold phone numbers, web links, adresses, etc 📝&lt;/li&gt;
&lt;li&gt;Simple Task list - Quickly create, check, delete tasks from the list ✅&lt;/li&gt;
&lt;li&gt;Should give me a daily inspirational quote - just in case I'm running low on fuel some day 😔&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;Reactjs - because I wanted to learn it 🙈&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Options on what to build
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Website &lt;/li&gt;
&lt;li&gt;Web Extension&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Website is good option, but several constraints would creep in. Of which, following 2 bothered me the most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where to store user data&lt;/li&gt;
&lt;li&gt;is a website an accessible option to serve the purpose?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After giving in some thought, I decided to build a Web Extension instead.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data is stored in Browser (syncing across multiple browsers is taken care of)&lt;/li&gt;
&lt;li&gt;Web Extension can be a "New Tab" replacement. It cannot get easier than this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hence, &lt;strong&gt;minimylist&lt;/strong&gt; was born! &lt;br&gt;
&lt;a href="https://i.giphy.com/media/116seTvbXx07F6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/116seTvbXx07F6/giphy.gif" alt="" width="480" height="371"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Screenshots?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wPsTvL5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/rkzmx2e0rkvtp3bbzclp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wPsTvL5e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/rkzmx2e0rkvtp3bbzclp.png" alt="Light Theme" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MatwSVEh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qirkub5nbdkwozg54bgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MatwSVEh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qirkub5nbdkwozg54bgx.png" alt="Dark Theme" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Here are links to the plugin: &lt;br&gt;
&lt;a href="https://rb.gy/vdhlo2"&gt;Chrome&lt;/a&gt;&lt;br&gt;
&lt;a href="https://rb.gy/ot5bba"&gt;Firefox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;minimylist&lt;/strong&gt; just serves the right purpose for me, hoping you guys will like it. Please share your thoughts in comments and all suggestions are welcome. Ciao! 👋🏻&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The best way to learn anything in Tech is by building something!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>react</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Competitive programming - is it really important?</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Sat, 30 May 2020 17:43:46 +0000</pubDate>
      <link>https://forem.com/iyashsoni/competitive-programming-is-it-really-important-2e2f</link>
      <guid>https://forem.com/iyashsoni/competitive-programming-is-it-really-important-2e2f</guid>
      <description>&lt;p&gt;Before you jump to conclusion, I was never in favour of Competitive Programming. I used to be mad at companies who used Comptetive Programming as a first round to scrutinize interview candidates.&lt;/p&gt;

&lt;p&gt;I've gone to the extent and said out loud many times, "If they want to hire someone for Developing - Mobile Apps, Web Apps, Backend servers, etc. then why ask &lt;code&gt;inverse a binary tree in O(god_knows_what_time)&lt;/code&gt;." &lt;/p&gt;

&lt;p&gt;I was like where/how/when am I going to apply this in developing stuff that they are hiring for?? &lt;/p&gt;

&lt;p&gt;But, after almost 3 years into Developing Software - I stand corrected.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://i.giphy.com/media/cYaBD8kxE4PZudHBRA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/cYaBD8kxE4PZudHBRA/giphy.gif" alt="" width="480" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It is important!
&lt;/h2&gt;




&lt;h4&gt;
  
  
  Why do companies like Google, Facebook, Amazon include this in their hiring process?
&lt;/h4&gt;

&lt;p&gt;It's very simple, they want to know how do you &lt;strong&gt;THINK!&lt;/strong&gt; Given a problem, how do you deduce (or try to come to) a solution. No, you are not going to directly use this solution in the Software - like ever! But what they are looking for is - a skill of problem solving. &lt;/p&gt;

&lt;p&gt;There's a concrete reason why parents buy puzzle games for their children - they want them to develop problem solving skill. &lt;/p&gt;

&lt;p&gt;This competitive round helps companies filter out candidates that lack this skill. I have also noticed a common practice to put this round as the very first one - it must be damn important!&lt;/p&gt;

&lt;p&gt;Now, almost every company in India looks for this skill - this has become a general process. The first round of an interview is most likely Competitive Programming round. &lt;/p&gt;




&lt;h4&gt;
  
  
  How does it help me - a developer?
&lt;/h4&gt;

&lt;p&gt;We spend most of our time developing something or the other. Most Softwares that we work on often requires us to write logic of some kind, handle different cases and scenarios, etc. P.S. I'm talking about more than just if-else. &lt;/p&gt;

&lt;p&gt;Being good at problem solving generally helps you construct solutions faster, consider all possible scenarios - giving better coverage and lesser bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt; - I'm not saying you're a bad developer if you are not doing this. As I said, I too have recently started this. You can still be a great developer by experience, or just naturally - I've seen some myself who are great at what they do and they don't know anything about Competitive Programming!&lt;/p&gt;




&lt;h4&gt;
  
  
  But I'm not looking for a change, so why should I learn?
&lt;/h4&gt;

&lt;p&gt;This is definitely a skill addition - at least. Plus, solving puzzles keeps you sharp. It's like a workout for your brain. And what's so special about this workout is that you can do it with what you are already in love with - &lt;code&gt;coding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to pick up a new language?&lt;/strong&gt; Try solving coding challenges with that language and see how quickly you pick it up!&lt;/p&gt;

&lt;p&gt;In fact, even if you continue with already known language, you'll have a better grip now than before - guaranteed. Personal experience.&lt;/p&gt;

&lt;p&gt;You will uncover the potential of some &lt;strong&gt;Data Structures&lt;/strong&gt; that you have already worked with - get ready to be surprised.&lt;/p&gt;




&lt;h4&gt;
  
  
  Am I too old to start now?
&lt;/h4&gt;

&lt;p&gt;There's one good thing about these coding puzzles, they don't come with a tag &lt;code&gt;suited for age 6-14&lt;/code&gt; 😝 You can start any time, literally. Besides, one solve puzzles for fun - and you are never late to do &lt;br&gt;
something fun.&lt;/p&gt;




&lt;h4&gt;
  
  
  How and Where do I start?
&lt;/h4&gt;

&lt;p&gt;There are plenty of platforms available that you can get started with. Listing down some for you to start:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://practice.geeksforgeeks.org/"&gt;GeeksForGeeks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codechef.com/"&gt;CodeChef&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hackerearth.com/"&gt;HackerEarth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hackerrank.com/"&gt;HackerRank&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://leetcode.com/"&gt;LeetCode&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of these platforms comes with a decent learning material and a solid community to help you out if needed! &lt;br&gt;
Pick a language you love and get started. It's addictive and you're going to ❤️ it.&lt;/p&gt;




&lt;h2&gt;
  
  
  This can very well be your fun new hobby in this pandemic - learning is cherry on the top. 🥳
&lt;/h2&gt;

&lt;p&gt;If you have any other questions, please fire it up in the comments section. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>computerscience</category>
      <category>career</category>
    </item>
    <item>
      <title>Web Push Notifications - explained!</title>
      <dc:creator>Yash Soni</dc:creator>
      <pubDate>Mon, 25 May 2020 12:58:43 +0000</pubDate>
      <link>https://forem.com/iyashsoni/web-push-notifications-explained-141i</link>
      <guid>https://forem.com/iyashsoni/web-push-notifications-explained-141i</guid>
      <description>&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%2Fa3d9y59ylehdcyx6xj8i.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%2Fa3d9y59ylehdcyx6xj8i.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello humans of Dev.to 🙌🏻 This is my first post here. Let's go! 🎢&lt;/p&gt;

&lt;p&gt;In this article, we are targeting 3 major Browser Platforms for understanding Push Notifications in Web - Chrome, Firefox &amp;amp; Safari .&lt;/p&gt;

&lt;p&gt;Functionally, Chrome &amp;amp; Firefox are very similar. Safari is an odd one because of restrictions from Apple (We know how Apple is when it comes to Security Standards overall) 😜&lt;/p&gt;

&lt;p&gt;Let's understand the basic flow of how the Notification works in Chrome/Firefox and Safari.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chrome/Firefox Notifications:
&lt;/h2&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%2Fde9d64322c3ala1nj7ax.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%2Fde9d64322c3ala1nj7ax.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Understanding a couple of terms here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service Worker: A worker for your Website that keeps listening for background events, like "Push Notification Received". An example of a Push service worker:&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Subscription Token: A unique per Browser Token which is later used to target a Notification. This token has an expiry, so you might need to request a new one after some time. An example of what a token looks like:&lt;/li&gt;
&lt;/ul&gt;

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

{ 
"endpoint": "https://fcm.googleapis.com/fcm/send/ckjznRm-rKg:APA91bEs6ZqaooqA5CWnd9LXI1VwpfmQzUFdS_mpNYl8qaSF4WwvCe1h2QVrTYDINEPC0oZIQlYpnYBXx2BiPkORIA4U27pze1JkS0dz7o1kfzWkc5_md5uYnZUvwpyFyvPkoeIlYtMj",
"userAuth": "gpq2UFvdWkyomEWdbJ6n3w==",
"userPublicKey": "BNUOw0iXWjfGaIb7Q77jQaWAra72ga1Y1QHZ+g3TuBuwSr0gS0GMtP2BS/lYNGMwku8sJ4e3esChQHigVKFHnsY="
}


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

&lt;/div&gt;

&lt;p&gt;This all may look a bit complicated to implement if you are new to all this. Worry not, I have created a helper plugin for making your lives simpler- here's the link to the &lt;a href="https://www.npmjs.com/package/easy-web-notifications" rel="noopener noreferrer"&gt;easy-web-notifications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just do &lt;code&gt;npm install easy-web-notifications&lt;/code&gt; and follow the instructions in the README and you're all set - from requesting User for Notification Permission to getting the Subscription Token.&lt;/p&gt;




&lt;h2&gt;
  
  
  Safari Notifications:
&lt;/h2&gt;

&lt;p&gt;In the case of Safari, there is no notion of Service Workers. Rather, Safari handles the delivery of Notifications on its own.&lt;/p&gt;

&lt;p&gt;But here's is the weird part, you cannot directly request for Notification Permission from Safari. No no no no no…&lt;/p&gt;

&lt;p&gt;Let's see how it goes:&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%2Fi%2Fw5wru0r52ncavh8b0qon.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%2Fw5wru0r52ncavh8b0qon.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Understanding vocabulary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website Push ID: It is an identifier for your Web App. If your Web App is hosted as &lt;code&gt;https://www.mywebapp.com&lt;/code&gt; then your Website Push ID will be &lt;code&gt;web.com.mywebapp&lt;/code&gt;. This is a convention and not a rule. Please note, you cannot test Safari Notifications on the local environment, it needs to be published with HTTPS enabled.&lt;/li&gt;
&lt;li&gt;Server URL: This is the URL of your Backend Server. It needs to be HTTPS and it also needs a valid certificate from a trusted authority (Self Signed certificates won't work)&lt;/li&gt;
&lt;li&gt;Registration Params: This is the extra params that you need to pass to your backend server to register the device.&lt;/li&gt;
&lt;li&gt;Push Package: Check this &lt;a href="https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html" rel="noopener noreferrer"&gt;official doc&lt;/a&gt; on building Push Package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can notice, Safari notifications are stricter and enforce better security, but of course at the cost of difficulty in implementation.&lt;/p&gt;




&lt;h4&gt;
  
  
  Does it mean Chrome and Firefox are not secured?
&lt;/h4&gt;

&lt;p&gt;Not really, Chrome and Firefox are now enforcing the use of VAPID keys.&lt;/p&gt;

&lt;h4&gt;
  
  
  Wait, what VAPID now?
&lt;/h4&gt;

&lt;p&gt;VAPID is Voluntary Application Server Identification. In short, it is a way of authenticating the communication between your browser clients and your Backend Server. It is a set of key {public, private}. &lt;/p&gt;

&lt;p&gt;As you would guess, the public key and private key both are kept on the server-side, while only the public key is shared with the client.&lt;br&gt;
When the client is trying to subscribe to pushManager, it will carry this VAPID_PUBLIC_KEY as well. So the token that is generated is only usable from the server that has a matching pair of the VAPID key present.&lt;/p&gt;

&lt;p&gt;See the following flow to understand using VAPID:&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%2Fi%2Fjjmnelb2eorrlax0nuh0.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%2Fjjmnelb2eorrlax0nuh0.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  How to generate VAPID keys? What library to use for sending Push Notifications?
&lt;/h4&gt;

&lt;p&gt;Google official docs suggest using &lt;a href="https://github.com/web-push-libs/" rel="noopener noreferrer"&gt;these libs&lt;/a&gt; for implementing Web Push in your backend. The same library can be used for generating VAPID keys.&lt;br&gt;
In Nodejs, it is super easy to generate keys. &lt;br&gt;
Just do &lt;code&gt;npm i -g web-push&lt;/code&gt;&lt;br&gt;
followed by &lt;code&gt;web-push generate-vapid-keys&lt;/code&gt;&lt;br&gt;
You should see something like this:&lt;/p&gt;

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

=======================================
Public Key:
BAbNusaoI2KTIogWMlnpZ8nL93ne8GSHXTOxlqxG19Py8V9m9bIarlzIN8PErAsy1NUEahfyLdDuPV7OwFdJYYA
Private Key:
cun3E7GjoCvfmD1NCcIpjYtG4TmZq-0awKtBlPOX3Cc
=======================================


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

&lt;/div&gt;

&lt;p&gt;These libraries are available for almost all major backend platforms and are actively maintained. I recommend using &lt;a href="https://github.com/web-push-libs/web-push" rel="noopener noreferrer"&gt;npm plugin&lt;/a&gt; for its ease of use.&lt;/p&gt;




&lt;h4&gt;
  
  
  Lastly, what's Web Push Mediator?
&lt;/h4&gt;

&lt;p&gt;We do not send notifications directly to Browser Clients, we built up the notification with all the required data (most importantly Token) and send it to the Browser platform handler - the mediator! This Platform then takes care of routing the notification to the correct client based on the token. &lt;br&gt;
Also, we don't get to see immediate delivery of notifications across all platforms because this is solely dependant on the mediator. Generally I've found Chrome to give timely notifications.&lt;/p&gt;




&lt;p&gt;It's been a long read I know, but I've tried to address every problem that I faced when I developed the Push Notification feature for both Client and Server-side. I hope this read helps you in some way! Ciao. 👋🏻&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%2Fen4ls4vpepbcofv2dd3e.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%2Fen4ls4vpepbcofv2dd3e.gif"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webpush</category>
      <category>notifications</category>
      <category>pushnotifications</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
