<?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: Agney Menon</title>
    <description>The latest articles on Forem by Agney Menon (@boywithsilverwings).</description>
    <link>https://forem.com/boywithsilverwings</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%2F225511%2Fffc81a00-ef20-4ca8-bc3f-21be1b8af27e.jpeg</url>
      <title>Forem: Agney Menon</title>
      <link>https://forem.com/boywithsilverwings</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/boywithsilverwings"/>
    <language>en</language>
    <item>
      <title>Please don't overuse optional chaining</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Fri, 21 Aug 2020 20:11:58 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/please-don-t-overuse-optional-chaining-bbb</link>
      <guid>https://forem.com/boywithsilverwings/please-don-t-overuse-optional-chaining-bbb</guid>
      <description>&lt;p&gt;This post is small rant on optional chaining and it's usage.&lt;/p&gt;

&lt;p&gt;If you don't know, optional chaining allows you to use shorten your object reference chain by returning &lt;code&gt;undefined&lt;/code&gt; when it sees a non existent reference in the chain.&lt;/p&gt;

&lt;p&gt;Consider a scenario where a person has his country name specified in the chain: &lt;code&gt;person.location.address.country.name&lt;/code&gt;. Now what if the person doesn't have to specify a whole bunch of this? Location is optional, address is optional if that is present country is optional and so on. You are now either left with shielding your code with lots of &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 🛡 or lodash &lt;a href="https://lodash.com/docs/4.17.15#get" rel="noopener noreferrer"&gt;&lt;code&gt;get&lt;/code&gt;&lt;/a&gt; 🎣 or catch the error yourself 💣.&lt;/p&gt;

&lt;p&gt;Optional chaining understands this pain and can shorten it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countryName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will not hit an error and will just return &lt;code&gt;undefined&lt;/code&gt; if the chain fails. Also, it works with TypeScript 🎩.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is obviously a welcome feature, I do use it myself a lot. But sometimes, we see that it is overused. I have overused it in the example itself, &lt;code&gt;country?.name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Is there a scenario where there would be a &lt;code&gt;country&lt;/code&gt; but the &lt;code&gt;name&lt;/code&gt; is not present? A country without a name?&lt;/p&gt;

&lt;p&gt;If there is not, then it should be written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countryName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's true that you are skipping an error in some case when there would be an error and country name is not present. But then, you might just be delaying the inevitable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// eternities later&lt;/span&gt;
&lt;span class="nf"&gt;plotMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it is mandatory for location to have coordinates, what you are doing here is to move the impact of the error as far from the origin of it. &lt;/p&gt;

&lt;p&gt;When Sentry (error tracking system) says that there is an error in &lt;code&gt;centerMap&lt;/code&gt; function, you know have to trace back till the roots to figure out there is something wrong with your code. Otherwise, it would have straightforward told you that it cannot get &lt;code&gt;coordindates&lt;/code&gt; of &lt;code&gt;undefined&lt;/code&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%2Fi%2Fue0ioti5vxxi2y1l7cwd.jpg" 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%2Fue0ioti5vxxi2y1l7cwd.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't run into an error, the UI is still going to be messed up and you will have the privilege of having to explain to the user that &lt;em&gt;it works on your system&lt;/em&gt; because you aren't looking at the cause, just the effect of it somewhere else.&lt;/p&gt;

&lt;p&gt;In other words, TypeScript or use Optional Chaining responsibly.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Counting React Children</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Wed, 24 Jun 2020 19:29:57 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/counting-react-children-kde</link>
      <guid>https://forem.com/boywithsilverwings/counting-react-children-kde</guid>
      <description>&lt;p&gt;&lt;code&gt;Children.count()&lt;/code&gt; and &lt;code&gt;Children.toArray().length&lt;/code&gt; have different outputs. We are going to explore how and why.&lt;/p&gt;

&lt;p&gt;Consider a React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&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="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Children&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;countArray&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, to render this component we are giving it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Wrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;CodeSandbox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Start&lt;/span&gt; &lt;span class="nx"&gt;editing&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;magic&lt;/span&gt; &lt;span class="nx"&gt;happen&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Wrapper&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, both counts listed in the UI would point to 2. What about if we change the Wrapper children to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Wrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;CodeSandbox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Start&lt;/span&gt; &lt;span class="nx"&gt;editing&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;magic&lt;/span&gt; &lt;span class="nx"&gt;happen&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Wrapper&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;Children.count&lt;/code&gt; will report 2 while &lt;code&gt;Children.toArray().length&lt;/code&gt; will report 1. &lt;/p&gt;

&lt;p&gt;This is because &lt;code&gt;Children.count&lt;/code&gt; is counting the number of slots that children has. Whether it be &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;, it's still a slot and &lt;code&gt;Children.count&lt;/code&gt; does a good job of counting it. From the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;number of times that a callback passed to &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;forEach&lt;/code&gt; would be invoked.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Children.toArray&lt;/code&gt; on the other hand, converts Children it receives to an opaque structure containing only the elements that JSX can render. That's how it reports that there is only a single child inside &lt;code&gt;Wrapper&lt;/code&gt;, the other one is conditionally false.&lt;/p&gt;

&lt;p&gt;You often see people try to weed out invalid children using this property. For eg. &lt;a href="https://github.com/chakra-ui/chakra-ui/blob/master/packages/utils/src/react-helpers.ts#L49-L59"&gt;Chakra UI&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Gets only the valid children of a component,
 * and ignores any nullish or falsy child.
 *
 * @param children the children
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getValidChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&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="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isValidElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&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;Here's a &lt;code&gt;Children.count&lt;/code&gt; usage example from &lt;a href="https://github.com/ant-design/ant-design/blob/7212a9746d9f21933fda26cac21f81604da3738b/components/carousel/index.tsx#L52-L56"&gt;Ant Design&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;componentDidUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CarouselProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If the number of Children (even if something was conditionally rendered) has changed, then go to the first slide.&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;goTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initialSlide&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;I write a once a month newsletter about catching up with the Web and it's ever evolving developer experiences. Feel free to browse the &lt;a href="https://buttondown.email/agney/archive"&gt;archives&lt;/a&gt; and of course, &lt;a href="https://buttondown.email/agney/"&gt;subscribe&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Tailwind CSS &amp; Svelte on Snowpack - Svelte Preprocess</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Tue, 23 Jun 2020 05:41:31 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/tailwind-css-svelte-on-snowpack-svelte-preprocess-3841</link>
      <guid>https://forem.com/boywithsilverwings/tailwind-css-svelte-on-snowpack-svelte-preprocess-3841</guid>
      <description>&lt;p&gt;&lt;a href="https://www.snowpack.dev/"&gt;Snowpack&lt;/a&gt; is a tool for building web applications with less tooling and 10x faster iteration. &lt;a href="https://tailwindcss.com/"&gt;Tailwind CSS&lt;/a&gt; is a utility-first CSS framework for&lt;br&gt;
rapidly building custom designs. Let's explore how to combine both of them. &lt;a href="https://svelte.dev/"&gt;Svelte&lt;/a&gt; is a radical new approach to building user interfaces.&lt;/p&gt;

&lt;p&gt;This article talks about how to use them in combination. This will also interest you if you want to add &lt;code&gt;svelte-preprocess&lt;/code&gt; when using a Snowpack app.&lt;/p&gt;
&lt;h1&gt;
  
  
  Template
&lt;/h1&gt;

&lt;p&gt;Premade template is available on &lt;a href="https://github.com/agneym/svelte-tailwind-snowpack"&gt;Github&lt;/a&gt;. You can use the template with command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-snowpack-app dir-name &lt;span class="nt"&gt;--template&lt;/span&gt; @snowpack/app-template-svelte
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Setup Svelte and Snowpack
&lt;/h2&gt;

&lt;p&gt;Snowpack provides an official template for svelte that can be initialised with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-snowpack-app dir-name &lt;span class="nt"&gt;--template&lt;/span&gt; svelte-tailwind-snowpack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://github.com/pikapkg/create-snowpack-app/tree/master/templates/app-template-svelte"&gt;Template Source&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Svelte Preprocess
&lt;/h2&gt;

&lt;p&gt;If you wanted to add PostCSS to your Svelte application, &lt;a href="https://github.com/sveltejs/svelte-preprocess"&gt;&lt;code&gt;svelte-preprocess&lt;/code&gt;&lt;/a&gt; would probably be the plugin you think of. It functions as an automatic processor for PostCSS, SCSS, Less and a lot more.&lt;/p&gt;

&lt;p&gt;But since we are using Snowpack's custom plugin, none of the usual loaders would work. Luckily, snowpack plugin has a secret hatch to push in plugins. It's a config file named &lt;code&gt;svelte.config.js&lt;/code&gt;. You can create one in your root folder and export your pre-processor.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Preprocess Script&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;To add &lt;code&gt;svelte-preprocess&lt;/code&gt;, you would need to install it with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i svelte-preprocess
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Modify the &lt;code&gt;svelte-config.js&lt;/code&gt; with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="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;sveltePreprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte-preprocess&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sveltePreprocess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// options to preprocess here&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;preprocess&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;h2&gt;
  
  
  Configuring PostCSS
&lt;/h2&gt;

&lt;p&gt;As &lt;a href="https://tailwindcss.com/docs/installation"&gt;suggested on Tailwind docs&lt;/a&gt;, we will use Tailwind CSS with PostCSS. To add this to preprocess:&lt;br&gt;
&lt;/p&gt;
&lt;div class="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;sveltePreprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte-preprocess&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sveltePreprocess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="c1"&gt;// Plugins go in here.&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;preprocess&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;h2&gt;
  
  
  Adding Tailwind
&lt;/h2&gt;

&lt;p&gt;Tailwind is available as a PostCSS plugin, you can add it with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="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;sveltePreprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svelte-preprocess&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sveltePreprocess&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;preprocess&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;After installing &lt;code&gt;tailwindcss&lt;/code&gt; package ofcourse.&lt;/p&gt;



&lt;p&gt;and you are good to go. You can find the complete template on Github:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/agneym"&gt;
        agneym
      &lt;/a&gt; / &lt;a href="https://github.com/agneym/svelte-tailwind-snowpack"&gt;
        svelte-tailwind-snowpack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      TailwindCSS with Svelte and Snowpack v2
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Svelte with TailwindCSS - Snowpack&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;✨ Community template for Svelte and Tailwind.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/9f29a45340e0657e0657f827594aff7c1856ffab/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7376656c74652d7461696c77696e642d736e6f777061636b3f6c6f676f436f6c6f723d253233636433353334267374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/9f29a45340e0657e0657f827594aff7c1856ffab/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7376656c74652d7461696c77696e642d736e6f777061636b3f6c6f676f436f6c6f723d253233636433353334267374796c653d666c61742d737175617265" alt="npm"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/5bfdafb963a919e67f123ddde2417f823910970d/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f61676e65796d656e6f6e3f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/5bfdafb963a919e67f123ddde2417f823910970d/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f61676e65796d656e6f6e3f7374796c653d666c61742d737175617265" alt="Twitter Follow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Create a new project with:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;npx create-snowpack-app dir-name --template @snowpack/app-template-svelte&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Uses &lt;code&gt;svelte-preprocess&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
Available Scripts&lt;/h2&gt;
&lt;h3&gt;
npm start&lt;/h3&gt;
&lt;p&gt;Runs the app in the development mode.
Open &lt;a href="http://localhost:8080" rel="nofollow"&gt;http://localhost:8080&lt;/a&gt; to view it in the browser.&lt;/p&gt;
&lt;p&gt;The page will reload if you make edits.
You will also see any lint errors in the console.&lt;/p&gt;
&lt;h3&gt;
npm test&lt;/h3&gt;
&lt;p&gt;Launches the test runner in the interactive watch mode.
See the section about running tests for more information.&lt;/p&gt;
&lt;h3&gt;
npm run build&lt;/h3&gt;
&lt;p&gt;Builds a static copy of your site to the &lt;code&gt;build/&lt;/code&gt; folder.
Your app is ready to be deployed!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For the best production performance:&lt;/strong&gt; Add a build bundler plugin like "@snowpack/plugin-webpack" or "@snowpack/plugin-parcel" to your &lt;code&gt;snowpack.config.json&lt;/code&gt; config file.&lt;/p&gt;
&lt;h3&gt;
Q: What about Eject?&lt;/h3&gt;
&lt;p&gt;No eject needed! Snowpack guarantees zero lock-in, and CSA strives for the same.&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/agneym/svelte-tailwind-snowpack"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;It is also listed on the page for community templates on Snowpack website.&lt;/p&gt;

&lt;p&gt;Have Fun 🎉&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>tailwindcss</category>
      <category>snowpack</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Conditionally spread into Object/Array - Javascript</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Thu, 11 Jun 2020 19:01:32 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/conditionally-spread-into-object-array-javascript-3h5i</link>
      <guid>https://forem.com/boywithsilverwings/conditionally-spread-into-object-array-javascript-3h5i</guid>
      <description>&lt;p&gt;There comes a time when we want to add more fields/elements into an array or object when it satisfies a certain condition. This blog is an exploration of how and why. &lt;/p&gt;

&lt;h2&gt;
  
  
  Spreading into an Array
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;isWinter&lt;/code&gt; is a boolean variable and you need to add &lt;code&gt;winterEssentials&lt;/code&gt; if it's true and nothing otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;essentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;winterEssentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sweater&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thermals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isWinter&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tripEssentials&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="nx"&gt;essentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;isWinter&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;winterEssentials&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We need an empty array at end because we cannot spread &lt;code&gt;undefined&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; into an array (they are not iterables). Spreading an empty array into another just keeps the array intact.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;initialArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultingArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;initialArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...[]];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resultingArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Have the same elements.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Spreading into an Object
&lt;/h2&gt;

&lt;p&gt;Rest spread into object is a &lt;a href="https://tc39.es/proposal-object-rest-spread"&gt;Stage 4 ECMA proposal&lt;/a&gt; and is &lt;a href="https://caniuse.com/#feat=mdn-javascript_operators_spread_spread_in_object_literals"&gt;implemented in most browsers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It mimics the behavior of existing &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign"&gt;Object.assign&lt;/a&gt; operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hacker = {
  hoodie: true,
}

const isHacker = true;

const person = {
  firstName: '',
  lastName: '',
  ...(isHacker &amp;amp;&amp;amp; hacker)
};

console.log(person);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You will notice here that resorting to a conditional operator isn't necessary. This is because rest spread for objects tries to wrap any primitive it finds to an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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;// {}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// {}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// {}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// {0: "a", 1: "b", 2: "c"}, well an array is also an object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Guide to &lt;a href="http://blog.agney.dev/type-coercion/"&gt;Type Coercion in JavaScript&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the expression &lt;code&gt;(isHacker &amp;amp;&amp;amp; hacker)&lt;/code&gt; returns &lt;code&gt;undefined&lt;/code&gt; which our spread operator converts to &lt;code&gt;{}&lt;/code&gt; and spreading an empty array into an object results in nothing. &lt;/p&gt;

&lt;p&gt;That's conditional spread.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>The Web in May</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Sun, 31 May 2020 14:47:58 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/the-web-in-may-2n8e</link>
      <guid>https://forem.com/boywithsilverwings/the-web-in-may-2n8e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This content is from my monthly newsletter about the Web. Go &lt;a href="https://buttondown.email/agney/"&gt;here to subscribe&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;May I?&lt;/p&gt;

&lt;p&gt;Catching up on remote work, this month saw several large tech companies plan for remote work in the long term. These include the likes of &lt;a href="https://www.nbcnews.com/tech/tech-news/twitter-employees-can-work-home-forever-ceo-says-n1205346"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.theverge.com/2020/5/18/21261798/square-employees-work-from-home-remote-premanent-policy-ceo"&gt;Square&lt;/a&gt;, &lt;a href="https://twitter.com/tobi/status/1263483496087064579"&gt;Shopify&lt;/a&gt; and &lt;a href="https://www.theverge.com/facebook/2020/5/21/21265699/facebook-remote-work-shift-workforce-permanent-covid-19-mark-zuckerberg-interview"&gt;Facebook&lt;/a&gt;. Facebook's announcement included plans to cut down on the salary because these engineers did not work in the saturated Silicon Valley anymore and let to much discussion. Should engineers be paid by location? &lt;/p&gt;

&lt;p&gt;Twitter decided to censor some of tweets of Donald Trump this week and has ensured a expected furore. US has come up with plans to stifle or take away this freedom from Twitter and ensure that it's government property as well. But considering that this does not work out, can we trust a social media company to be a single arbiter of truth? &lt;/p&gt;

&lt;h2&gt;
  
  
  Releases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://blog.chromium.org/2020/03/updates-to-form-controls-and-focus.html"&gt;Chrome 83&lt;/a&gt; - Chrome 83 comes with some form look and accessibility improvements done with the help of Microsoft team. While some of the elements are debatable, the &lt;a href="https://twitter.com/agneymenon/status/1265380608642957312"&gt;date picker is rad&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Microsoft Build saw many interesting announcements including Terminal v1, Window package manager and improved Powertools. But Microsoft is honing in on improving Office as a platform introducing &lt;a href="https://www.theverge.com/2020/5/19/21260005/microsoft-office-fluid-web-document-features-build"&gt;Office Blocks&lt;/a&gt;, which might just get rid of the file. Also, this Airtable competitor - &lt;a href="https://www.youtube.com/watch?v=plshQSoe_OY"&gt;Lists&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://engineering.shopify.com/blogs/engineering/what-is-nix"&gt;Nix&lt;/a&gt; - Nix is Shopify's dependency manager and more. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.blog/2020-05-06-new-from-satellite-2020-github-codespaces-github-discussions-securing-code-in-private-repositories-and-more/"&gt;Github Satellite&lt;/a&gt; - Github's major annoucement was Github discussions introducing a platform alongside issues where users could discuss. This was expected long time from Spectrum's takeover.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://increment.com/frontend/how-to-reevaluate-your-frontend-architecture/"&gt;Increment Magazine - 13&lt;/a&gt; - Stripe's Increment magazine is out and all the articles are a must check out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What am I building?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A recording utility in the Browser - &lt;a href="https://reco.agney.dev/"&gt;https://reco.agney.dev/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Slack bot for reading ad-free articles inside Slack - &lt;a href="https://github.com/agneym/quick-read-slack"&gt;Open Source Repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tutorials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://csswizardry.com/2020/05/the-fastest-google-fonts/"&gt;Fastest way to load Google Fonts&lt;/a&gt; - Harry Roberts on his research to load Google fonts the fastest. Spoiler: self hosting is still the winner, but you also get tips to use the Google CDN faster.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started"&gt;Getting Started with React - MDN&lt;/a&gt; - MDN has a page on React now.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/elliehtml/realistic-css-art-hacks-27pk"&gt;Realistic CSS Art Hacks&lt;/a&gt; - This tutorial dives into some of the tricks to those elusive CSS magic portraits.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dmitripavlutin.com/use-react-memo-wisely/"&gt;Use React memo wisely&lt;/a&gt; - You might think you can plug memo anywhere and get performance improvements (well, at least once you learned to use it). And then, you would be wrong.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kentcdodds.com/blog/tracing-user-interactions-with-react"&gt;Tracing User Interactions with React&lt;/a&gt; - Kent C Dodds talks about Profiling with the Profiler in devtools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What am I watching?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.imdb.com/title/tt2861424/"&gt;Rick and Morty&lt;/a&gt; is back and it's amazing. Hulu's nice little clone of R&amp;amp;M named &lt;a href="https://www.youtube.com/watch?v=5hHoKWE4Vb4"&gt;Solar Opposites&lt;/a&gt; is also a little gem although it isn't Rick and Morty (obviously)&lt;/p&gt;

&lt;h2&gt;
  
  
  In Other News
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://macwright.org/2020/05/10/spa-fatigue.html"&gt;Second Guessing the Modern Web&lt;/a&gt; - This asks What if everone's wrong about the web. We have been wrong before.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://engineering.fb.com/web/facebook-redesign/"&gt;Facebook Redesign&lt;/a&gt; - Facebook on their learnings redesigning the interface the Internet is now familiar with.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://engineering.khanacademy.org/posts/handling-2x-traffic-in-a-week.htm"&gt;How Khan Academy Successfully Handled 2.5x Traffic in a Week&lt;/a&gt; - With everyone stuck at home, online education has seen a great surge. How did free websites like Khan Academy handle it? &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://techcrunch.com/2020/05/06/no-cookie-consent-walls-and-no-scrolling-isnt-consent-says-eu-data-protection-body/"&gt;EU improves on it's GDPR spec&lt;/a&gt; - Websites cannot place cookie walls before users see any content on the page and scrolling does not constitute consent anymore. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://imgflip.com/ai-meme"&gt;This Meme does not exist&lt;/a&gt; - AI Meme generator, enough said.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This content is from my monthly newsletter about the Web. Go &lt;a href="https://buttondown.email/agney/"&gt;here to subscribe&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>The Web in April - Newsletter</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Thu, 30 Apr 2020 06:32:59 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/the-web-in-april-newsletter-e5b</link>
      <guid>https://forem.com/boywithsilverwings/the-web-in-april-newsletter-e5b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is from a monthly newsletter I write about the web. If you like what you are seeing, you can subscribe to the newsletter &lt;a href="https://buttondown.email/agney/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;April is ending and the world is still in quarantine. &lt;em&gt;Hope this email finds you healthy&lt;/em&gt; is now the default first line in any email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://buttondown.email/agney/archive/web-in-march-the-mindless-newsletter-by-agney/"&gt;Everything I said about remote working during a pandemic&lt;/a&gt; still stand, but remote work is certainly gaining momentum in at least some of the companies. TCS, an Indian service company employing 0.5 million people have announced that &lt;a href="https://www.businesstoday.in/current/corporate/post-coronavirus-75-percent-of-3-5-lakh-tcs-employees-permanently-work-from-home-up-from-20-percent/story/401981.html"&gt;75% of their workforce will be going remote by 2025&lt;/a&gt;. FYI has published a report analysing &lt;a href="https://usefyi.com/future-of-remote-work"&gt;The Future of Remote Work&lt;/a&gt; estimating by 2025, 70% of the workforce will work remotely at least five days in a month. In other news, Uber CTO is leaving the company and they might lay off &lt;a href="https://techcrunch.com/2020/04/28/thuan-pham-who-fled-vietnam-as-a-child-and-became-ubers-cto-in-2013-is-leaving-the-company/"&gt;20% of their workforce&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The release for &lt;a href="https://www.npmjs.com/package/is-promise"&gt;is-remote&lt;/a&gt; got people in JavaScript community talking. This library is a one liner that determines if a variable is a promise or not. Everything was fine until one day the maintainer made a minor release for supporting ES Modules for new NodeJS update and &lt;a href="https://github.com/then/is-promise/issues/13"&gt;broke a whole lot of packages&lt;/a&gt;. Apps that broke include Serverless and create-react-app. People have been talking about the heavy reliance of third party libraries and how the number of dependencies can kill your app when maintainers make mistakes. There is a &lt;a href="https://medium.com/javascript-in-plain-english/is-promise-post-mortem-cab807f18dcc"&gt;post mortem for incident on Medium&lt;/a&gt; which is an interesting read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Releases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.blog/2020/04/23/the-final-python-2-release-marks-the-end-of-an-era/?cb=1"&gt;Last Python2 version&lt;/a&gt; - End of an era.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pricing"&gt;Github is free for Teams&lt;/a&gt; - A Microsoft enterprise is waiving off all fees for teams. While this is indeed great for indie programmers there are growing concerns that Github might lose their way with only enterprise customers paying for the product.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gatsbyjs.org/blog/2020-04-22-announcing-incremental-builds/"&gt;Gatsby - Incremental Builds&lt;/a&gt; - As the number of pages increases, it used to becomes painful to build a static app, every page has to get rebuild even if there is only small change. With Netlify's build minutes, this was a question on everyone's minds. GatsbyJS is now introducing a beta into incremental builds on their platform offering 1000x build speeds.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://foundation.graphql.org/news/2020/04/03/web-based-graphql-ides-for-the-win-how-why-playground-graphiql-are-joining-forces/"&gt;GraphQL Playground&lt;/a&gt; - &lt;a href="https://www.prisma.io/"&gt;Prisma&lt;/a&gt; donated Playground to GraphQL foundation and now they are combining GraphiQL and Playground.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Content
&lt;/h2&gt;

&lt;p&gt;If you are looking to learn some computer science during the pandemic, I have &lt;a href="https://www.notion.so/07d80644a8d8485f97cf893bfcd25638"&gt;a list of free courses&lt;/a&gt; for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://blog.agney.dev/effective-meetings/"&gt;Effective Remote Communications&lt;/a&gt; - I wrote about keeping up with meetings.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.agney.dev/10k-reflecting-so/"&gt;10k and reflecting on Stackoverflow&lt;/a&gt; - I have reached a 10k reputation milestone on Stackoverflow and I wrote about things I learned along the way.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.agney.dev/tailwind-on-snowpack/"&gt;TailwindCSS on Snowpack&lt;/a&gt; - I tried out &lt;a href="https://www.snowpack.dev/"&gt;Snowpack&lt;/a&gt; and then learned how to do &lt;a href="https://tailwindcss.com/"&gt;TailwindCSS&lt;/a&gt; with it. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tutorials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://css-doodle.com/"&gt;CSS Doodle&lt;/a&gt; - A web component for drawing patterns with CSS.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jvns.ca/blog/debugging-attitude-matters/"&gt;When debugging attitude matters&lt;/a&gt;  - Julia Evans talks about the right attitude for debugging and I can't agree more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.atrost.com/posts/animating-complex-svg/"&gt;Animating Complex SVGs&lt;/a&gt; - Alex Trost has lots and lots of tips in here that will help you learn a thing or two about SVGs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stripe.com/docs/payments/integration-builder"&gt;Integration Builder - Stripe&lt;/a&gt; - Is this an ad for stripe? Am I talking sponsorships from them? Click on the link and find out how awesome this tutorial is.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What am I watching?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://womenofreact.com/"&gt;Women of React&lt;/a&gt; happened last week and it was amazing. The live stream is still up on YouTube. The talks from &lt;a href="https://www.youtube.com/watch?v=K8MF3aDg-bM&amp;amp;feature=youtu.be&amp;amp;t=13846"&gt;Maggie Appleton on React Mental Models&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=K8MF3aDg-bM&amp;amp;feature=youtu.be&amp;amp;t=15922"&gt;Anusree Subramani's talk on React Developer Tooling&lt;/a&gt; are absolute favourites.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Other News
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/twbs/bootstrap/pull/30377"&gt;Bootstrap dropping IE support for v5&lt;/a&gt; - The sizes will fall by almost 10%, but the debate is still hot on this is a good decision (on HackerNews ofcourse)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apple.stackexchange.com/a/363933"&gt;The right side for a Macbook charger&lt;/a&gt; - USB C meant that you could charge the Macbook on any side. But did you know it had a right side?&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://builtin.com/software-engineering-perspectives/lean-agile-methodology-software-engineering"&gt;Agile’s early evangelists wouldn't mind watching it die&lt;/a&gt; - Agile went from being a manifesto and a corportate bandwagon of keywords really fast. Builtin speaks to Mary Poppendieck on Agile's future.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://thenextweb.com/neural/2020/04/21/watch-fake-elon-musk-zoom-bombs-meeting-using-real-time-deepfake-ai/"&gt;Fake Elon Musk on Zoom&lt;/a&gt; - First came the Zoom backgrounds. Now, deepfake has a hold on the faces. Nothing is real on Zoom anymore.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=BxV14h0kFs0"&gt;It has number of views in the title&lt;/a&gt; - Tom Scott is one of my favourite YouTubers for the topics he picks. This video has the number of views on it's title, literally.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This is from a monthly newsletter I write about the web. If you like what you are seeing, you can subscribe to the newsletter &lt;a href="https://buttondown.email/agney/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>Tailwind CSS with Snowpack</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Sun, 19 Apr 2020 20:30:15 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/tailwind-css-with-snowpack-3c7g</link>
      <guid>https://forem.com/boywithsilverwings/tailwind-css-with-snowpack-3c7g</guid>
      <description>&lt;p&gt;&lt;a href="https://www.snowpack.dev/"&gt;Snowpack&lt;/a&gt; is a tool for building web applications with less tooling and 10x faster iteration. &lt;a href="https://tailwindcss.com/"&gt;Tailwind CSS&lt;/a&gt; is a utility-first CSS framework for&lt;br&gt;
rapidly building custom designs. Let's explore how to combine both of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.snowpack.dev/#tailwind-css"&gt;First resource we come across is on the site for Snowpack&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tailwind works as-expected with Snowpack. Just follow the official Tailwind Install Guide. When you get to step #4 (“Process your CSS with Tailwind”) choose the official Tailwind CLI option to generate your CSS. Import that generated CSS file in your HTML application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But this misses an important part of &lt;em&gt;Process your CSS with Tailwind&lt;/em&gt; step on the Tailwind website:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For simple projects or just giving Tailwind a spin, you can use the Tailwind CLI tool to process your CSS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So it's only for simpler projects or may be even trying out Tailwind. &lt;/p&gt;
&lt;h2&gt;
  
  
  What are we missing with Tailwind CLI?
&lt;/h2&gt;

&lt;p&gt;Tailwind CLI currently does not remove unnecessary classes from Tailwind. This means that without using any of classes required for Tailwind, you would be stuck with a file of size above 1MB. &lt;/p&gt;

&lt;p&gt;Tailwind recommends handling this by adding a &lt;a href="https://purgecss.com/"&gt;PurgeCSS PostCSS Plugin&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps to add PurgeCSS
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Process
&lt;/h3&gt;

&lt;p&gt;There are several ways/plugins for PostCSS that can be used. For build tool we are using, there is even a Rollup plugin for PostCSS. But the reason we are using Snowpack is to get rid of tooling, not to add more of them. So, it would make sense to add PostCSS as it's CLI tool and also run it in production only. &lt;/p&gt;
&lt;h3&gt;
  
  
  Snowpack Init
&lt;/h3&gt;

&lt;p&gt;First, to start of a normal snowpack project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="c"&gt;# Snowpack and a dev server of choice&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; snowpack servor
&lt;span class="c"&gt;# Tailwind CSS. Because.&lt;/span&gt;
npm i tailwind 
npx snowpack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can &lt;a href="https://www.snowpack.dev/#installing-snowpack"&gt;find full guide for installing snowpack on their site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, for our developer tools:&lt;br&gt;
&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;# Our postcss tools&lt;/span&gt;
npm i &lt;span class="nt"&gt;--save-dev&lt;/span&gt; postcss-cli @fullhuman/postcss-purgecss
&lt;span class="c"&gt;# ease of setting env variables and running npm scripts.&lt;/span&gt;
npm i cross-env npm-run-all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Tailwind Init
&lt;/h3&gt;

&lt;p&gt;Setting up tailwind:&lt;/p&gt;

&lt;p&gt;Add a &lt;code&gt;src/style.css&lt;/code&gt; file with Tailwind necessary CSS:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Create &lt;code&gt;tailwind.config.js&lt;/code&gt; by running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tailwindcss init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can edit the file to change theme or add plugins to Tailwind CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailwindcss.com/docs/installation"&gt;Find full guide to installation on Tailwind site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add an HTML file to connect CSS to the HTML.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Snowpack - Simple Example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/src/output.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&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;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/src/app.js"&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;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  NPM Scripts for development
&lt;/h3&gt;

&lt;p&gt;There are two things we want to do on development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start dev server&lt;/li&gt;
&lt;li&gt;Use Tailwind CSS to convert our style file to CSS.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cross-env NODE_ENV=development run-s dev:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev:server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx servor --reload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev:css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tailwindcss build src/style.css -o src/output.css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This pretty much takes care of the development setup. For development, you can run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Setup PostCSS
&lt;/h3&gt;

&lt;p&gt;Add a &lt;code&gt;postcss.config.js&lt;/code&gt; file at root which we will be using as configuration for PostCSS:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purgecss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fullhuman/postcss-purgecss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/**/*.js&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="c1"&gt;// Include any special characters you're using in this regular expression&lt;/span&gt;
  &lt;span class="na"&gt;defaultExtractor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\w&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;:&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;!:&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&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="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&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;purgecss&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We are adding &lt;code&gt;tailwind&lt;/code&gt; and &lt;code&gt;purgeCSS&lt;/code&gt; in our PostCSS configuration and has setup PurgeCSS to run only on Production. (We are using PostCSS only on production so it's not like it's doing anything, simply following Tailwind docs on the same.)&lt;/p&gt;
&lt;h3&gt;
  
  
  NPM Scripts for Production
&lt;/h3&gt;

&lt;p&gt;We will run the same processes for production:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cross-env NODE_ENV=production run-p build:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:styles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx postcss src/style.css -o src/output.css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx snowpack --optimize --clean"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For production, you can run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You will find that I'm building source and development version of CSS to the same file. This is intentional. It is possible to add a &lt;code&gt;dist&lt;/code&gt; folder and move assets and styles and build files into the folder and fix other issues that happen with it. Feel free but remember the reason you chose Snowpack was to lighten tooling.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/agneym"&gt;
        agneym
      &lt;/a&gt; / &lt;a href="https://github.com/agneym/tailwind-snowpack"&gt;
        tailwind-snowpack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple Tailwind Snowpack starter
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Tailwind - Snowpack Starter&lt;/h1&gt;
&lt;p&gt;Find complete blog on &lt;a href="https://blog.agney.dev/tailwind-on-snowpack/" rel="nofollow"&gt;How to setup Tailwind CSS with Snowpack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://buttondown.email/agney/" rel="nofollow"&gt;Subscribe to my monthly web newsletter&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/agneym/tailwind-snowpack"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>snowpack</category>
      <category>webdev</category>
      <category>tailwindcss</category>
      <category>css</category>
    </item>
    <item>
      <title>10k and Reflecting on Stack Overflow</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Sat, 18 Apr 2020 05:07:41 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/10k-and-reflecting-on-stack-overflow-1al1</link>
      <guid>https://forem.com/boywithsilverwings/10k-and-reflecting-on-stack-overflow-1al1</guid>
      <description>&lt;p&gt;About 5 years ago, as I started out on Stack Overflow, I was simply looking for a way to keep track of answers that I see. Then, one day it felt like I could use some validation. If I could get out there and answer few questions from others, I could somehow prove a better developer than them.&lt;/p&gt;

&lt;p&gt;It took few days of sifting through hundreds of questions, I arrived at a JavaScript question I could answer. But then, each time someone else answered it better than me. It is very often through those experiences that I learned that things that sound obvious in my head are not exactly the ones that made sense for everyone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1eS1pa4Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f6m139dvsfdereele7tb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1eS1pa4Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f6m139dvsfdereele7tb.png" alt="Stackoverflow Reputation 10k"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, after over 350 answers and a reputation of 10,000 there is more of a sense of calm in my approach to answers. Here are a bunch of things that I learned along the way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Explain the answer&lt;br&gt;
I'm sure we can all use consistent naming and functions to decorate our codebases. But the case is not the same for someone looking at your answer. If you are only providing a code snippet, them and everyone else looking at it are bound to be confused. Explain what you are doing differently from the OP and why.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link back to the docs&lt;br&gt;
This ties in with the sound of &lt;em&gt;that's obvious&lt;/em&gt; in our heads. Very often, these things are not obvious at all. The documentation would provide upto date examples and explanation of all the options that the user can take in case of changing things up, instead of trying to over explain everything from the docs, quote the important part and link back to the page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Runnable Snippets&lt;br&gt;
Whenever the question or the answer had a runnable snippet, a resolution was reached much faster than the one without it. Nobody likes to read code and it is some sort off validation to see the code actually working. As a web developer, I often relied on platforms like &lt;a href="https://codepen.io/"&gt;codepen&lt;/a&gt;, &lt;a href="https://codesandbox.io/"&gt;codesandbox&lt;/a&gt; and &lt;a href="https://stackblitz.com/"&gt;stackblitz&lt;/a&gt; for my live demos. While this approach surely works and is mostly easier, it starts to wear down on you with time. There are hundreds of snippets that are halfway done, some linked to answer, some not that I have lost track. In case you delete some of these for space, some of your older answers would be broken and cannot help others. Stackoverflow has an &lt;a href="https://meta.stackoverflow.com/questions/338537/how-do-i-create-a-react-stack-snippet-with-jsx-support/338538#338538"&gt;in build snippets tool for web developers&lt;/a&gt; and while it is sometimes a pain to create, it's much easier to maintain. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not all worthy questions&lt;br&gt;
Sometimes the questions are either duplicates or caused by simple typos. While you can go ahead and answer them, may be rack up a few reputation points, it is often unfair both to the person who asked the question and StackOverflow as a platform. There are flagging and closing options for questions, use them wisely. StackOverflow guide to &lt;a href="https://stackoverflow.com/help/how-to-answer"&gt;How to write a good answer&lt;/a&gt; is a good starting point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admit that you may be wrong&lt;br&gt;
Your large reputation or years of experience does not make you all-knowing. There are chances that others might come upto you and make suggestions or sometimes tell you that you are wrong. Being patronising/condescending towards them does not serve your purpose. Evaluate their comment, if you are wrong admit it, learn from it and move on.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Today, it is no longer that sense of validation that I seek from StackOverflow. Answering a question does not make me a better developer than they are. It is often the bravest thing to do to face a crowd and admit that you don't know the answer and the internet only makes it harder. Cheers to everyone who keeps learning 🥂&lt;/p&gt;

</description>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Free Computer Science Courses and Certifications in time of COVID-19</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Mon, 13 Apr 2020 08:51:14 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/free-computer-science-courses-and-certifications-in-time-of-covid-19-4bn7</link>
      <guid>https://forem.com/boywithsilverwings/free-computer-science-courses-and-certifications-in-time-of-covid-19-4bn7</guid>
      <description>&lt;p&gt;The pandemic has everyone stuck at home and it seems like we have a little more time on our hands.&lt;/p&gt;

&lt;p&gt;Lots of companies have come forward offering free courses and certifications during this time and I have been making a list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.notion.so/07d80644a8d8485f97cf893bfcd25638"&gt;https://www.notion.so/07d80644a8d8485f97cf893bfcd25638&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope it can be of help :) Happy Learning.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Effective Remote Communication</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Mon, 06 Apr 2020 16:29:34 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/effective-remote-communication-4h3c</link>
      <guid>https://forem.com/boywithsilverwings/effective-remote-communication-4h3c</guid>
      <description>&lt;p&gt;A lot of people are taking to remote for the first time because of the pandemic. While doing software engineering remote is well and good enough for most people, it's the communication that they struggle with. If you do not see the other person what techniques can we use to get our thoughts through?&lt;/p&gt;

&lt;p&gt;The points in discussion are very valid even for in-person communication. We are just discussing how to make them better in context of Remote.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Meetings
&lt;/h2&gt;

&lt;p&gt;The hardest hit of these are meetings. When there is nobody to laugh at the jokes, how do we measure the impact?&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Make sure you need a meeting
&lt;/h3&gt;

&lt;p&gt;Many meetings happen because they can. If you are not getting feedback from people in the meeting, not allowing them to build off each others ideas, then the meeting could have been an email. &lt;/p&gt;

&lt;p&gt;Atlassian has published a &lt;a href="https://3kllhk1ibq34qk6sp3bhtox1-wpengine.netdna-ssl.com/wp-content/uploads/2018/05/runningeffectivemeetingscheatsheet_atlassian.pdf"&gt;guide&lt;/a&gt; to check if your meeting is necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Make sure all the attendees need to be in the meeting
&lt;/h3&gt;

&lt;p&gt;Many a time we tack on people for meetings, but at the end don't invite the most necessary people. As Julie Zhuo writes in &lt;a href="https://www.amazon.in/Making-Manager-What-Everyone-Looks/dp/0753552892"&gt;Making of a Manager&lt;/a&gt;, if the design team has a meeting to push backward all the dates for engineering team, the result is disharmony. But if representatives from the engineering team themselves are invited and a decision is made with suggestions from both parties, then it gains trust from both departments.&lt;/p&gt;

&lt;p&gt;Harvard Business Review has a calculator for &lt;a href="https://hbr.org/2016/01/estimate-the-cost-of-a-meeting-with-this-calculator"&gt;finding the cost of each meeting&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Always write an agenda for your meeting
&lt;/h3&gt;

&lt;p&gt;It might seem wasteful on the part of the manager.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Oh! I'm going to meet them in person in a few hours, I will explain it then.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But do remember that springing surpises on people isn't the best way to get feedback from anyone. Everyone takes some time to actually understand the graphs and bullet points that are spread on a PowerPoint presentation.&lt;/p&gt;

&lt;p&gt;If you give people an agenda on what is to be discussed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are aware that this is a meeting they should attend&lt;/li&gt;
&lt;li&gt;Allows people to catch up on what has been discussed even in between action items&lt;/li&gt;
&lt;li&gt;Actually prepare points to discuss. &lt;/li&gt;
&lt;li&gt;A prepared person can beat group-think.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NoteJoy has examples and templates for you to write an &lt;a href="https://notejoy.com/resources/meeting-agenda-example"&gt;effective meeting agenda&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Make sure results of the meeting are understood for all attendees.
&lt;/h3&gt;

&lt;p&gt;As a meeting host gathering feedback, it is possible that you understand what the results of the meeting are. But if you do not communicate that with the attendees, then the meaning and ownership are lost on them. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting results are to be actionable. &lt;/li&gt;
&lt;li&gt;Each meeting result has to be under the ownership of a person&lt;/li&gt;
&lt;li&gt;It should be documented through email or any other note service used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn't have to be immediate. Time can be spent after the meeting to calculate costs of alternatives discussed during the meeting and included in the results to reach an effective solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D38le-7g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vro5pokzg8u8rgx3bedx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D38le-7g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vro5pokzg8u8rgx3bedx.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Slack/Teams
&lt;/h2&gt;

&lt;p&gt;Or some other software where employees are divided into channels and predominantly text/image based communication happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use channels
&lt;/h3&gt;

&lt;p&gt;Channels are very useful for general questions. This is primarily because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anyone can answer your query&lt;/li&gt;
&lt;li&gt;Other people might have same query as yours in the future. &lt;/li&gt;
&lt;li&gt;The project manager can collect common questions and add it to documentation FAQ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So many companies outright ban personal communication for work and prefer channels for all communication. &lt;/p&gt;

&lt;p&gt;Arkency has a guide explaning why their teams are asked to stick to &lt;a href="https://blog.arkency.com/use-channels-not-direct-messages/"&gt;channels&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But also know that this is helpful only when the teams are divided into very &lt;strong&gt;small&lt;/strong&gt; channels. Assume the case where an employee wants to discuss if confirmation has to be added in his secuity design. To communicate this in a channel with all employees, they would have to explain the entire context in anticipation that even other employees should 'get' where the alert box is. If it gets too big, no one reads, the only person who could answer in the first place also gets confused. When this happens, you would see that all communication in the channel has been striped down to &lt;em&gt;Can I have a call?&lt;/em&gt; which is more harmful that the original intention of the rule.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Long form communication
&lt;/h3&gt;

&lt;p&gt;Remote Teams communicate mostly through written text (if you don't then, aspire to communicate through written text). This is because unlike videos, text is indexable and searchable for all the employees. Even if you don't show up during a specific time, you can provide feedback to an RFC or go through all the comments as they happened.&lt;/p&gt;

&lt;p&gt;Basecamp &lt;a href="https://basecamp.com/guides/how-we-communicate"&gt;Guide to their Internal Communication&lt;/a&gt; is a great primer on this.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Praise in public, criticise in smaller groups.
&lt;/h3&gt;

&lt;p&gt;Often times we 'see' people only when they make a mistake. Because of the channel rule, this often leads to pointing fingers in a public group. While this is fine, it is a criticism with some feedback, it is still important that it is kept to the people who need to hear it. If you have feedback for a person in the design team, add it to the respective channel, would the others in the company be interested in it? Probably not. &lt;/p&gt;

&lt;p&gt;However the opposite holds true when you want to praise an employee for their work. Choose the largest channel where it does not get annoying and offer praise. It inspires other employees to do better and let's project managers, HRs, business executives to notice the employee. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Over-communicate
&lt;/h2&gt;

&lt;p&gt;Remember that the CEO cannot see you in the elevator ask you about work. People can forget that you are working there unless you tell them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Je03jvKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t9eu86zynjsnq1hoh3fu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Je03jvKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t9eu86zynjsnq1hoh3fu.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Intentional Watercooler
&lt;/h2&gt;

&lt;p&gt;Sometimes you can have anyone can join team meetings/watercooler moments to keep your yourself close to your collegues. Remote companies don't have watercoolers, cafeterias or free gyms. To see other employees, to feel part of a company sometimes, it helps to meetup (virtually) in some zoom coffee shop background. &lt;/p&gt;

&lt;p&gt;You could also have Basecamp (or similar) software setup to ask all the employees social questions so they can communicate amongst themselves on common interests.&lt;/p&gt;

&lt;p&gt;Olark talks about &lt;a href="https://blog.olark.com/creating-remote-watercooler-moments"&gt;their watercooler zoom chats&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Practice Social Distancing and Stay Safe Everyone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I write a &lt;a href="https://buttondown.email/agney"&gt;monthly newsletter on web development&lt;/a&gt;. Also checkout &lt;a href="https://blog.agney.dev"&gt;my blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devrel</category>
      <category>management</category>
    </item>
    <item>
      <title>The Web in March - Mindless Newsletter</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Tue, 31 Mar 2020 18:08:34 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/the-web-in-march-mindless-newletter-gf1</link>
      <guid>https://forem.com/boywithsilverwings/the-web-in-march-mindless-newletter-gf1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Taken from my monthly newsletter. &lt;a href="https://buttondown.email/agney"&gt;Subscribe&lt;/a&gt; to receive in your inbox every month.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;March is coming to an end and it seems like every month is one upping the other on disasters. &lt;/p&gt;

&lt;p&gt;I'm not going to waste &lt;a href="https://www.youtube.com/watch?v=gxAaO2rsdIs"&gt;talking&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=54XLXg4fYsc"&gt;about&lt;/a&gt; &lt;a href="https://www.who.int/health-topics/coronavirus"&gt;flattening&lt;/a&gt; the &lt;a href="https://www.washingtonpost.com/graphics/2020/world/corona-simulator/"&gt;curve&lt;/a&gt; &lt;a href="https://meltingasphalt.com/interactive/outbreak/"&gt;because&lt;/a&gt; &lt;a href="https://twitter.com/marcelsalathe/status/1242430736944201730"&gt;there&lt;/a&gt; are so &lt;a href="https://www.ft.com/coronavirus-latest"&gt;many&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=BtN-goy9VOY"&gt;people&lt;/a&gt; who are &lt;a href="https://www.youtube.com/watch?v=sHP0UIdZyI4"&gt;doing&lt;/a&gt; it &lt;a href="https://twitter.com/gregjames/status/1241838854891622401"&gt;better&lt;/a&gt; than I can.&lt;/p&gt;

&lt;p&gt;But let's talk about something that has left me wondering. The effects of this on the remote working landscape. Absolutely all of the IT service sector companies have gone remote now and it is said that it will help drive more companies remote after this crisis. Well, not so much. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lot of people are feeling negative with the current work scenario which not just puts them remote but also barrs them with social interaction. &lt;/li&gt;
&lt;li&gt;Companies and Managers who have no experience with remote are putting out &lt;a href="https://twitter.com/benyt/status/1238555167932506116"&gt;severe&lt;/a&gt; 
restrictions on people and I have heard friends who are afraid to move from the computer screen for lunch. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wonder if more people will associate remote work with the loneliness that they experience now and seek to move away from it. People have been trying to help though:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.gse.harvard.edu/news/uk/20/03/cultivating-empathy-coronavirus-crisis"&gt;Cultivating Empathy in times of Coronavirus&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;DHH gave their &lt;a href="https://basecamp.com/books/remote"&gt;Remote: Office not Required&lt;/a&gt; book for free&lt;/li&gt;
&lt;li&gt;Shopify have their employees &lt;a href="https://www.cnbc.com/2020/03/12/coronavirus-shopify-gives-employees-1000-stipend-to-work-from-home.html"&gt;1000$&lt;/a&gt; to setup their home systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though these companies would not go fully remote, I'm thinking there would be employees that are currently doing remote who realise the option and decide to go remote when they start their own companies. I'm actually excited at the prospect. &lt;/p&gt;




&lt;p&gt;When the month started, Zoom won everyone over (well, not &lt;a href="https://www.digit.in/news/apps/kids-reportedly-review-bombing-apps-like-zoom-to-get-them-booted-off-the-play-store-53057.html"&gt;&lt;em&gt;everyone&lt;/em&gt;&lt;/a&gt;). People compared it to where Skype stood and how Zoom has taken over. It has been used for online clases, work, meetings, conferences, family talks and even a &lt;a href="https://abcnews.go.com/Business/wireStory/g20-video-call-virus-era-summits-virtual-69811751"&gt;G20 summit&lt;/a&gt;. But then came the (slight) blip! Zoom was sharing data with Facebook and of course your employer and you had no control over it. Lots of alternates in discussion and it seems &lt;a href="https://jitsi.org/"&gt;Jitsi&lt;/a&gt; and &lt;a href="http://whereby.com/"&gt;Whereby&lt;/a&gt; stand clear winners.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;People even go &lt;a href="https://twitter.com/mjnblack/status/1243641637420453889"&gt;fired on Zoom&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.theverge.com/2020/3/30/21199628/zoom-backgrounds-free-virtual-conference-calls-video-remote-work"&gt;Custom backgrounds for your messy remote room&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Releases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://lore.kernel.org/wireguard/CAHmME9qOpDeraWo5rM31EWQW574KEduRBTL-+0A2ZyqBNDeYkg@mail.gmail.com/T/#u"&gt;Linux 5.6&lt;/a&gt; - &lt;a href="https://www.phoronix.com/scan.php?page=article&amp;amp;item=linux-56-features&amp;amp;num=1"&gt;Features&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Everyone released a COVID-19 visualiser. You might not even be a developer if you haven't tried. Here's &lt;a href="https://www.google.com/covid19/"&gt;Google&lt;/a&gt;, &lt;a href="https://www.apple.com/newsroom/2020/03/apple-releases-new-covid-19-app-and-website-based-on-CDC-guidance/"&gt;Apple&lt;/a&gt;, &lt;a href="https://www.bing.com/covid"&gt;Microsoft&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/adobetech/acrobat-on-the-web-powered-by-webassembly-782385e4947e"&gt;Acrobat on the Web&lt;/a&gt; - Adobe now has a version of Acrobat reader on the web powered by Webassembly - At 865kB main module Gzipped that's pretty impressive.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.blog/2020-03-16-npm-is-joining-github/"&gt;NPM is joining Github&lt;/a&gt; - NPM is joining hands with Github and by extension by Microsoft. Microsoft now has VS Code, TypeScript and NPM. Some wild azure extensions with Github and NPM are coming very soon.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=OWVqn2qc2ls"&gt;Apple Macbook Air 2020&lt;/a&gt; - After iPad with a keyboard, Apple comes with a product that closely resembles, the Macbook Air. The Air is a product that has held strong after a 7 years of neglect, even after Apple &lt;a href="https://www.youtube.com/watch?v=EA8vDBY6bCs&amp;amp;feature=youtu.be&amp;amp;t=4478"&gt;on stage admitted&lt;/a&gt; buying a Pro would be better. Like most of the new Macbook products, there is nothing new about it, but hey! at least the keyboard is older.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prettier.io/blog/2020/03/21/2.0.0.html"&gt;Prettier 2.0&lt;/a&gt; - Prettier launched 2.0 with &lt;code&gt;trailingComma: es5&lt;/code&gt; and &lt;code&gt;singleQuotes: true&lt;/code&gt; as default. I can finally use &lt;em&gt;zero-config&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://phabricator.wikimedia.org/T241180"&gt;Wikimedia is adopting VueJS&lt;/a&gt; - After lots of discussion, they have settled on VueJS, while we won't be seeing Wikipedia soon, other stuff could be ported over.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Libraries
&lt;/h3&gt;

&lt;p&gt;I managed to put out two libraries this month.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://agneym.github.io/react-avatar/?path=/docs/"&gt;React Avatar&lt;/a&gt; - For some easy avatars and avatar stacks.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/agneym/ir-toast"&gt;Ionic React - Imperative Toast&lt;/a&gt; - Easier toasts for ionic and react integrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tutorials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://joshwcomeau.com/react/the-perils-of-rehydration/"&gt;Perils of Rehydration&lt;/a&gt; - There are things we miss when write Server side/static rendered react applications. &lt;em&gt;Why does the console say a class name is different and why does it care?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://codepen.io/ivorjetski/full/xxGYWQG"&gt;CSS Landscape&lt;/a&gt; - Out of this world.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[Introduction to MDXJS] - MDX has been a magic component powering my blog for sometime now. Accidentally while pitching an advanced topic on MDX, I got to write the introduction for it and here is it on CSS Tricks. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.agney.dev/theming-on-styled-components/"&gt;Theming with Styled Components&lt;/a&gt; - Tools and Techniques to use for theming your application with Styled Components.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.agney.dev/grid-blowout/"&gt;How things can easily go out of the window with CSS Grid&lt;/a&gt; - Using Grid, I learned something crucial, 1fr does not always mean that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What am I learning?
&lt;/h3&gt;

&lt;p&gt;Don't know, not sure. Do you have something interesting you think I would like? Let me know by replying or tweeting at me at &lt;a href="http://twitter.com/agneymenon/"&gt;@agneymenon&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  In Other News
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://glitch.com/remote/"&gt;Glitch - Remote work&lt;/a&gt; - Glitch wrote a guide for remote work as well as many other people, but this looks good. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=_3loq22TxSc"&gt;Great Impractical Ideas in Computer Science - Powerpoint Programming&lt;/a&gt; - I watched this guy program on Powerpoint for an hour and was absolutely mindblown!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.theregister.co.uk/2020/03/26/corejs_maintainer_jailed_code_release/"&gt;CoreJS maintainer goes to prison&lt;/a&gt; - The guy who was always asking for a job in your terminals is now in jail and the community is pondering over who is to maintain CoreJS from now.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.freecodecamp.org/news/coursera-free-online-courses-6d84cdb30da/"&gt;Free courses&lt;/a&gt; - With Coursera and EDX helping out with COVID, there are lots of free courses out there are interesting, you just have to look. Meanwhile some of the free services like Khan Academy are &lt;a href="https://www.khanacademy.org/donate"&gt;asking for donations&lt;/a&gt; because their servers are at 250% normal load. More people learning is a good thing I suppose.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/aaronshekey/status/1244680796214046721"&gt;Dark mode on Stackoverflow&lt;/a&gt; - SO finally gets in on the act with their most upvoted feature ever. Not as good as I thought, but definitely a good start. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What am I doing?
&lt;/h3&gt;

&lt;p&gt;I watched &lt;a href="https://www.imdb.com/title/tt8788458/"&gt;Promised Neverland&lt;/a&gt; this month. It's about a group of young kids who escape an orphanage only to find life outside isn't as rosy as seems. Comes with my highest recommendations if you like dark stories.&lt;/p&gt;

&lt;p&gt;I have been rewatching &lt;a href="https://www.imdb.com/title/tt1439629/?ref_=nv_sr_srsg_0"&gt;The Community&lt;/a&gt; and I have to say, I'm still impressed by the ingenuity that Russo Brothers and Dan Harmon showed in some of these episodes. I mean, look at &lt;a href="https://community-sitcom.fandom.com/wiki/Remedial_Chaos_Theory"&gt;Remedial Chaos Theory&lt;/a&gt; - who else does that?&lt;/p&gt;




&lt;p&gt;What are some interesting stuff you are reading/writing/watching/building? Let me know your suggestions/improvements by replying to this newsletter or find me on &lt;a href="https://twitter.com/agneymenon"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until next month, &lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.agney.dev"&gt;Agney Menon&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Taken from my monthly newsletter. &lt;a href="https://buttondown.email/agney"&gt;Subscribe&lt;/a&gt; to receive in your inbox every month.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Ionic React &amp; Imperative Toast Messages</title>
      <dc:creator>Agney Menon</dc:creator>
      <pubDate>Sat, 28 Mar 2020 05:55:17 +0000</pubDate>
      <link>https://forem.com/boywithsilverwings/ionic-react-imperative-toast-messages-f8k</link>
      <guid>https://forem.com/boywithsilverwings/ionic-react-imperative-toast-messages-f8k</guid>
      <description>&lt;p&gt;A toast notification is a long standing custom in mobile application used to notify the user of something happening within the system. Sometimes it even has buttons for interaction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WD43I4ea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.hkinfosoft.com/wp-content/uploads/2019/05/toast.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WD43I4ea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.hkinfosoft.com/wp-content/uploads/2019/05/toast.gif" alt="Toast GIFc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is how to use one (straight from the docs):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ToastExample&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowToast&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IonToast&lt;/span&gt;
      &lt;span class="nx"&gt;isOpen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onDidDismiss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setShowToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your settings have been saved.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Well, this is easy 😁I can do that. &lt;/p&gt;

&lt;p&gt;But I normally thinks of toasts more imperatively than this. It might be because of libraries like &lt;code&gt;react-toast&lt;/code&gt; or &lt;code&gt;ant.design&lt;/code&gt; who have these imperative toast messaging systems, or it could even be that Ionic's own Angular part of design has an imperative toast. &lt;/p&gt;

&lt;p&gt;Also, if I needed to a success toast and an error toast, I would need multiple &lt;code&gt;IonToast&lt;/code&gt; components rendered or have states definining toast state.&lt;/p&gt;

&lt;p&gt;In Angular Ionic, you would:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toastController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&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;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;present&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's pretty cool 😎. What if we could do this?&lt;/p&gt;

&lt;p&gt;We could utilise a &lt;a href="https://reactjs.org/docs/context.html"&gt;React Context&lt;/a&gt; and a hook to achieve this functionality at with ease. I wrote out a custom package which does exactly that.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ToastProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useToast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@agney/ir-toast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Wrap you App.tsx with ToastProvider&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IonApp&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ToastProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;// ...rest of your application &lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ToastProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/IonApp&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In your component &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RegisterForm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useToast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Passwords don&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;t match&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Registration Successful&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request failed&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This allows you have to have error messages with a one liner:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Toast.error('Error message');
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;ToastProvider&lt;/code&gt; also takes a &lt;code&gt;value&lt;/code&gt; property that allows you to define defaults for all toasts created in it's children. &lt;/p&gt;

&lt;p&gt;The package also enables creating toast messages with the same Angular API as:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useToast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;present&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// When you want to.&lt;/span&gt;
    &lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dismiss&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To install the package:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @agney/ir-toast
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note that it has a dependency on both React and Ionic React.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/agneym"&gt;
        agneym
      &lt;/a&gt; / &lt;a href="https://github.com/agneym/ir-toast"&gt;
        ir-toast
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Imperative Toast Component for Ionic React
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Ionic React Imperative Toast 🥂
&lt;/h1&gt;
&lt;p&gt;
  &lt;a href="https://www.npmjs.com/package/@agney/ir-toast" rel="nofollow"&gt;
    &lt;img alt="npm" src="https://camo.githubusercontent.com/85daa00310ede2a9f855a27583187eb64d17182a/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4061676e65792f69722d746f617374"&gt;
  &lt;/a&gt;
  &lt;a href="https://github.com/agneym/ir-toast/actions"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u7pjCG8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/agneym/ir-toast/workflows/Node%2520CI/badge.svg"&gt;
  &lt;/a&gt;
  &lt;a href="https://github.com/agneym/ir-toast/blob/master/LICENSE"&gt;
    &lt;img alt="License: MIT" src="https://camo.githubusercontent.com/6da6fbe40ebbe1d53d4e3aa0a7f206c36c40675b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f61676e65796d2f69722d746f617374"&gt;
  &lt;/a&gt;
  &lt;a href="https://www.npmjs.com/package/@agney/ir-toast" rel="nofollow"&gt;
    &lt;img alt="License: MIT" src="https://camo.githubusercontent.com/d81d2d42b56e290c0d4d74eb425e19242f4f2d3d/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f74797065732f73637275622d6a732e737667"&gt;
  &lt;/a&gt;
  &lt;a href="https://prettier.io" rel="nofollow"&gt;
    &lt;img alt="code style: prettier" src="https://camo.githubusercontent.com/c83b8df34339bd302b7fd3fbb631f99ba25f87f8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d70726574746965722d6666363962342e737667"&gt;
  &lt;/a&gt;
  &lt;a href="http://makeapullrequest.com" rel="nofollow"&gt;
    &lt;img src="https://camo.githubusercontent.com/d4e0f63e9613ee474a7dfdc23c240b9795712c96/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e737667"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;This packages enables the use of imperative Toasts as in Angular.&lt;/p&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;div class="highlight highlight-source-ts"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-smi"&gt;ToastProvider&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s1"&gt;useToast&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;"@agney/ir-toast"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-c"&gt;// Wrap you App.tsx with ToastProvider&lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-smi"&gt;App&lt;/span&gt;: &lt;span class="pl-smi"&gt;FC&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-smi"&gt;IonApp&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-smi"&gt;ToastProvider&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="pl-c"&gt;// ...rest of your application &lt;/span&gt;
    &lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;/&lt;span class="pl-smi"&gt;ToastProvider&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;/&lt;span class="pl-smi"&gt;IonApp&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;
&lt;span class="pl-c"&gt;// In your component &lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-smi"&gt;RegisterForm&lt;/span&gt;: &lt;span class="pl-smi"&gt;FC&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-smi"&gt;Toast&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;useToast&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-c"&gt;// ...&lt;/span&gt;
  &lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-en"&gt;validate&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;toast&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-smi"&gt;Toast&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;warning&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'Passwords don\'t match'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;

  &lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-en"&gt;submit&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-k"&gt;try&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;response&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-s1"&gt;api&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;register&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;data&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
      &lt;span class="pl-smi"&gt;Toast&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;success&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'Registration Successful'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;catch&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-smi"&gt;Toast&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;error&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'Request failed'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;npm i @agney/ir-toast&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Requires react 16.8…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/agneym/ir-toast"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



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