<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Belev</title>
    <description>The latest articles on DEV Community by Martin Belev (@martinbelev).</description>
    <link>https://dev.to/martinbelev</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%2F129964%2Fd881e04f-2c2a-490b-b7d2-1bd677dee97c.jpg</url>
      <title>DEV Community: Martin Belev</title>
      <link>https://dev.to/martinbelev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/martinbelev"/>
    <language>en</language>
    <item>
      <title>How to keep cleaner React components with object map?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sun, 26 Jul 2020 15:45:29 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-keep-cleaner-react-components-with-object-map-2k7c</link>
      <guid>https://dev.to/martinbelev/how-to-keep-cleaner-react-components-with-object-map-2k7c</guid>
      <description>&lt;p&gt;We will see one way to refactor our React components by replacing conditionals with object map. This is a favorite refactoring of mine because it makes the components easier to understand and extend, groups the logic in a single place, and requires fewer lines of code.&lt;/p&gt;




&lt;h3&gt;
  
  
  Simple conditionals example
&lt;/h3&gt;

&lt;p&gt;A lot of times based on some input we want to display different information to our users. Let's see an example which should make things clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;errorField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&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;const&lt;/span&gt; &lt;span class="nx"&gt;ErrorMessageWithSwitch&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;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;errorField&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="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid name.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid email address.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid password.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid date of birth.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Invalid field.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ErrorMessageWithIf&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;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;errorField&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid name.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid email address.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid password.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&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;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please enter valid date of birth.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Invalid field.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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 have a component that should show the appropriate message for a certain &lt;code&gt;errorField&lt;/code&gt;. It is a very simple one but by reading it we got some unpleasant feeling. A lot of writing and syntax which is making the code noisy and takes more time to go through. Not to speak about the fact that some tiny details can be missed as well.&lt;/p&gt;

&lt;p&gt;By having a deeper look at the code, we can see that after all this is a simple mapping between one value to another. Doesn't this seem like a key/value structure? Here comes the object map, so let's see the refactored example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;errorField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&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;const&lt;/span&gt; &lt;span class="nx"&gt;errorFields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter valid name.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter valid email address.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter valid password.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter valid date of birth.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid field.&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;ErrorMessage&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;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;errorField&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errorFields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;errorField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;errorFields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Such simple examples are easier to identify and start using object instead of &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;switch&lt;/code&gt;. However, this kind of refactoring/technique is pretty powerful for a lot more complex cases where the benefits are bigger.&lt;/p&gt;

&lt;h3&gt;
  
  
  More complex example
&lt;/h3&gt;

&lt;p&gt;Let's say we have a button component for connecting our account with Twitter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="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;const&lt;/span&gt; &lt;span class="nx"&gt;ConnectTwitterButton&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;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;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="c1"&gt;// Connect Twitter&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Connect with &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TwitterIcon&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Twitter
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  );
};

export default ConnectTwitterButton;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is great, but now imagine we need to extend the current button's functionality to connect with more providers like Twitch/Facebook/.etc and we end up with something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;providerType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fb&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;const&lt;/span&gt; &lt;span class="nx"&gt;ConnectAccountButton&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;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;providerType&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;getProviderName&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="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Twitch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Facebook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unknown&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getProviderIcon&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="c1"&gt;// return SVG icon&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;providerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getProviderName&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;icon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getProviderIcon&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;connectWithTwitter&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="c1"&gt;// Connect Twitter&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;connectWithTwitch&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="c1"&gt;// Connect Twitch&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;connectWithFacebook&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="c1"&gt;// Connect Facebook&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter&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;return&lt;/span&gt; &lt;span class="nx"&gt;connectWithTwitter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitch&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;return&lt;/span&gt; &lt;span class="nx"&gt;connectWithTwitch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fb&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;return&lt;/span&gt; &lt;span class="nx"&gt;connectWithFacebook&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Connect with &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;providerName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ConnectAccountButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We have a couple of things per provider - name, icon and connect function. So what we can do about it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ProviderType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;providerType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProviderType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;icon&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="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;connect&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="k"&gt;void&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;providers&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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ProviderType&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;Provider&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="na"&gt;twitter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TwitterIcon&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectWithTwitter&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;twitch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TwitchIcon&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Twitch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectWithTwitch&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;fb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FacebookIcon&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Facebook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connectWithFacebook&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;ConnectAccountButton&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;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;providerType&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;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Connect with &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ConnectAccountButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The important part is the refactoring itself - &lt;code&gt;providers&lt;/code&gt; object and &lt;code&gt;ConnectAccountButton&lt;/code&gt; component. Now we look at our component it is very easy to understand what is happening and we have the logic centralized in a simple object.&lt;/p&gt;

&lt;p&gt;Maybe it would be a bit harder to identify similar cases if you haven't done similar refactoring but ones you have done a couple it becomes easier and more obvious.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus round using array
&lt;/h3&gt;

&lt;p&gt;This one can be helpful with array usage as well. I think the most common example would be a navigation menu where the items are displayed based on some conditions - feature flags, simple checks based on the user data, .etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navigationItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nav 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Some visibility logic&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="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nav 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Some visibility logic&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;// Then we can simply use filter and map to construct our navigation&lt;/span&gt;
&lt;span class="nx"&gt;navigationItems&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;item&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/* The mapped item */&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;We saw a simple and a more complex example of how we can use object map and avoid using conditionals. Hopefully, the code looks much cleaner and easier to understand and extend for everyone.&lt;/p&gt;

&lt;p&gt;A pattern can be noticed for cases where we can apply the object map usage - when we have data that is mapped to other data or behavior.&lt;/p&gt;

&lt;p&gt;This is a refactoring that is not related specifically to React and JavaScript/TypeScript. It can be used in other languages as well when you see fit.&lt;/p&gt;

&lt;p&gt;Of course, this is not a silver bullet and not every &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;switch&lt;/code&gt; statements can be converted to such configuration object.&lt;/p&gt;

&lt;p&gt;Thank you for reading this to the end. I hope you enjoyed it and learned something new. If so, you can support me by following me on &lt;a href="https://twitter.com/BelevMartin"&gt;Twitter&lt;/a&gt; where I will share other tips, new articles, and things I learn. If you would like to learn more, have a chat about software development, or give me some feedback, don't be shy and drop me a DM.&lt;/p&gt;

</description>
      <category>react</category>
      <category>refactoring</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to use pattern matching in JavaScript - an alternative?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sun, 19 Jul 2020 09:53:48 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-use-pattern-matching-in-javascript-an-alternative-3a7l</link>
      <guid>https://dev.to/martinbelev/how-to-use-pattern-matching-in-javascript-an-alternative-3a7l</guid>
      <description>&lt;p&gt;We are going to quickly see what is pattern matching, see basic examples of it in &lt;a href="https://www.scala-lang.org/"&gt;Scala&lt;/a&gt; and make an analogy with one less known usage of JavaScript switch statement.&lt;/p&gt;

&lt;p&gt;There is no native support for pattern matching in JavaScript. However, there is an open &lt;a href="https://github.com/tc39/proposal-pattern-matching"&gt;proposal&lt;/a&gt; which is great and it would be nice to have support and use it in the future if it gets approved and goes through all of the stages.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: this isn't a tutorial about Scala pattern matching and the given examples will be simple ones without going into details.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;




&lt;h3&gt;
  
  
  What is pattern matching?
&lt;/h3&gt;

&lt;p&gt;It is a mechanism for checking/testing a value against a given pattern. The match should be exact. The logic for the first pattern that matches the value is executed. The patterns can vary and the functional programming languages support a variety of different usages.&lt;/p&gt;

&lt;p&gt;Based on the &lt;a href="https://docs.scala-lang.org/tour/pattern-matching.html"&gt;Scala docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is a more powerful version of the switch statement in Java and it can likewise be used in place of a series of if/else statements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They are far more powerful than the usual &lt;code&gt;switch&lt;/code&gt; statement. We will see how we can make an analogy with JavaScript &lt;code&gt;switch&lt;/code&gt; statement though and use it in a way that gives us more control to write complicated expressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scala pattern matching examples
&lt;/h3&gt;

&lt;p&gt;One of the simplest cases is match by value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def getMonthName(month: Int): String = month match {
  case 1 =&amp;gt; "January"
  case 2 =&amp;gt; "February"
  // .etc
  case _ =&amp;gt; "Unknown"
}
getMonthName(13)  // Unknown
getMonthName(1)  // January
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;JavaScript version:&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;getMonthName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;month&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="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;January&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;February&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// .etc&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unknown&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="nx"&gt;getMonthName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Unknown&lt;/span&gt;
&lt;span class="nx"&gt;getMonthName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// January&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can have matching on type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Device
case class Phone(model: String) extends Device {
  def screenOff = "Turning screen off"
}
case class Computer(model: String) extends Device {
  def screenSaverOn = "Turning screen saver on..."
}

def goIdle(device: Device) = device match {
  case p: Phone =&amp;gt; p.screenOff
  case c: Computer =&amp;gt; c.screenSaverOn
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are a lot of other different usages of pattern matching that Scala supports but this is not the focus of this blog post. If you are interested in seeing them you can check out &lt;a href="https://docs.scala-lang.org/tour/pattern-matching.html"&gt;pattern matching&lt;/a&gt; and &lt;a href="https://docs.scala-lang.org/overviews/scala-book/match-expressions.html"&gt;match expressions&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript switch statement quick overview
&lt;/h3&gt;

&lt;p&gt;From my experience in almost all of the places I have worked, &lt;code&gt;switch&lt;/code&gt; is used in its traditional form as &lt;code&gt;switch (someValue)&lt;/code&gt; and then &lt;code&gt;case&lt;/code&gt; statements with simple numbers or strings.&lt;/p&gt;

&lt;p&gt;Let's see an example from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch"&gt;MDN docs&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Papayas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Oranges&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Oranges are $0.59 a pound.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mangoes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Papayas&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mangoes and papayas are $2.79 a pound.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// expected output: "Mangoes and papayas are $2.79 a pound."&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;default&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="s2"&gt;`Sorry, we are out of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is great but it feels like we are limited to simple values only. What if we want to add additional conditions or we want to use more complex data structures like lists, dictionaries, .etc?&lt;/p&gt;

&lt;h3&gt;
  
  
  One less known usage of switch statement in JavaScript
&lt;/h3&gt;

&lt;p&gt;If we try to formulate a question of what we want to do, it would be - what should we do if we want to write whatever expressions we want in the &lt;code&gt;case&lt;/code&gt; statements and if one is true execute some logic?&lt;/p&gt;

&lt;p&gt;By asking the question we have already answered it by &lt;strong&gt;&lt;em&gt;if some of them is true&lt;/em&gt;&lt;/strong&gt;. We can pass &lt;code&gt;true&lt;/code&gt; as value for our &lt;code&gt;switch&lt;/code&gt; statement and then the logic for the first case expression that evaluates to true will be executed.&lt;/p&gt;

&lt;p&gt;Let's take a look at an example:&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;getCompactAmount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;M`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;K`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&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;amount&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;getCompactAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2M&lt;/span&gt;
&lt;span class="nx"&gt;getCompactAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 5K&lt;/span&gt;
&lt;span class="nx"&gt;getCompactAmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We want to match our expressions to &lt;code&gt;true&lt;/code&gt; which gives us the power to write whatever expressions we would like with whatever complicated conditions we need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This, of course, can be achieved by using &lt;code&gt;if/else if/else&lt;/code&gt; statements and I guess it is a matter of preference what to use. I am not saying that this should be always used but it gives some nice opportunities and I think is a less known usage which I haven't seen much. As someone who isn't a big fan of &lt;code&gt;switch&lt;/code&gt; statements and tried to avoid using them, I would say that after I have used &lt;code&gt;switch (true)&lt;/code&gt; for a while I am more than happy with it. I find it much easier to read than multiple &lt;code&gt;if/else if&lt;/code&gt; statements and less error-prone.&lt;/p&gt;

&lt;p&gt;Thank you for reading this to the end. I hope you enjoyed it and learned something new. If so, please follow me on &lt;a href="https://twitter.com/BelevMartin"&gt;Twitter&lt;/a&gt; where I will share other tips, new articles, and things I learn. If you would like to learn more, have a chat about software development, or give me some feedback, don't be shy and drop me a DM.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>What are you using for your documentation?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Tue, 30 Jun 2020 10:51:48 +0000</pubDate>
      <link>https://dev.to/martinbelev/what-are-you-using-for-your-documentation-4iib</link>
      <guid>https://dev.to/martinbelev/what-are-you-using-for-your-documentation-4iib</guid>
      <description>&lt;p&gt;Hi everyone,&lt;/p&gt;

&lt;p&gt;I am sure there is no "best" tool for it but what are your recommendations for documentation. It should support MDX.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gatsby has some nice themes for documentation&lt;/li&gt;
&lt;li&gt;there is &lt;a href="https://www.docz.site/"&gt;Docz&lt;/a&gt; which is built on top of Gatsby&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dokz.site/"&gt;Dokz&lt;/a&gt; which is powered by NextJS&lt;/li&gt;
&lt;li&gt;I am sure there are a lot more tools out there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is your preferred choice? What would you use if you have to start writing documentation today?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>documentation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to effectively use git rebase --onto?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sat, 20 Jun 2020 15:39:37 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-effectively-use-git-rebase-onto-5b85</link>
      <guid>https://dev.to/martinbelev/how-to-effectively-use-git-rebase-onto-5b85</guid>
      <description>&lt;p&gt;This post was originally published on &lt;a href="https://belev.dev/how-to-effectively-use-git-rebase-onto"&gt;https://belev.dev/how-to-effectively-use-git-rebase-onto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are going to get a step further and explore the &lt;code&gt;git rebase --onto&lt;/code&gt; command. What is it, how to use it to fix Git branches after rebase, how to change a branch's base, and a bit more? We will learn those things by exploring real-world scenarios in which &lt;code&gt;git rebase --onto&lt;/code&gt; is really useful.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;




&lt;h3&gt;
  
  
  Quick &lt;code&gt;git rebase&lt;/code&gt; recap
&lt;/h3&gt;

&lt;p&gt;Visiting the &lt;a href="https://git-scm.com/docs/git-rebase"&gt;docs&lt;/a&gt;, we will see the following explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reapply commits on top of another base tip&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most important bit here is what &lt;em&gt;base&lt;/em&gt; means/refers to? This is the previous/parent commit. Let's see an example so that it can become clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        f--g--h  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;h&lt;/code&gt;'s previous commit is &lt;code&gt;g&lt;/code&gt;. This means that &lt;code&gt;h&lt;/code&gt;'s base is &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;g&lt;/code&gt;'s base is &lt;code&gt;f&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;f&lt;/code&gt;'s base is &lt;code&gt;c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;d&lt;/code&gt;'s base is &lt;code&gt;c&lt;/code&gt; as well. This shows us that one commit can be the base of multiple commits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The current &lt;code&gt;feature&lt;/code&gt;'s base is &lt;code&gt;c&lt;/code&gt;. By checking out the &lt;code&gt;feature&lt;/code&gt; branch and executing &lt;code&gt;git rebase master&lt;/code&gt;, we are going to change the &lt;code&gt;feature&lt;/code&gt; branch's base to &lt;code&gt;e&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
             \
              f'--g'--h'  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Mentioned in a &lt;a href="https://belev.dev/git-merge-vs-rebase-to-keep-feature-branch-up-to-date"&gt;previous blog post&lt;/a&gt; this is creating new commits and the Git history is changed. With the &lt;code&gt;'&lt;/code&gt; after &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;h&lt;/code&gt; we are showing that those are different commits. They contain the same set of changes though.&lt;/p&gt;

&lt;p&gt;When we have only two branches which we want to keep in sync one on top of the other, &lt;code&gt;git rebase&lt;/code&gt; is working perfectly. However, this is not enough when we need to make our changes based on the old base. Here &lt;code&gt;git rebase --onto&lt;/code&gt; comes in help.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is &lt;code&gt;git rebase --onto&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;We can say that this is a more precise way of changing a parent branch. It accepts three arguments - &lt;code&gt;&amp;lt;new-base&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;old-base&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;end-inclusive&amp;gt;&lt;/code&gt; where the third one is optional. This gives us complete control over what and where we want to rebase.&lt;/p&gt;

&lt;p&gt;Let's take the previous example and achieve the same result using &lt;code&gt;--onto&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        f--g--h  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We want &lt;code&gt;feature&lt;/code&gt; to be rebased off of &lt;code&gt;master&lt;/code&gt;. So we know what our new base is, it is &lt;code&gt;master&lt;/code&gt;. The old base is the base of our first commit in the branch which means it is going to be &lt;code&gt;c&lt;/code&gt;. Now we know both the new and old base, and we can run the command: &lt;code&gt;git rebase --onto master c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will lead us to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
             \
              f'--g'--h'  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The result is the same as using &lt;code&gt;git rebase master&lt;/code&gt;. This shows us that they are doing the same thing. &lt;code&gt;git rebase&lt;/code&gt; master is just a shorthand syntax for &lt;code&gt;git rebase --onto master &amp;lt;old-base&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to rebase with skipping not needed commits?
&lt;/h3&gt;

&lt;p&gt;We have already seen the easiest case of using &lt;code&gt;--onto&lt;/code&gt;. Let's take the previous example again but say that we don't want commit &lt;code&gt;f&lt;/code&gt; to be present after the rebase because it is not relevant anymore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        f--g--h  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;git rebase --onto master f&lt;/code&gt; gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
             \
              g--h  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Be careful with the value provided for &lt;code&gt;&amp;lt;old-base&amp;gt;&lt;/code&gt;. It is a common mistake to think that it is inclusive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is important to remember/understand that we are working with bases, not a certain commit. &lt;code&gt;g&lt;/code&gt;'s base is &lt;code&gt;f&lt;/code&gt; so when we say &lt;code&gt;&amp;lt;old-base&amp;gt;&lt;/code&gt; is &lt;code&gt;f&lt;/code&gt; this is going to be changed by the provided &lt;code&gt;&amp;lt;new-base&amp;gt;&lt;/code&gt; and we are going to loose commit &lt;code&gt;f&lt;/code&gt; this way.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to fix branch from a branch after rebase
&lt;/h3&gt;

&lt;p&gt;Working with multiple people or in a large codebase, it is almost certain that at some point you will need to create a branch from a branch. For example, you need to start a new feature but it depends on another one so you need to start your branch from your previous branch. Or you have automation QAs which are creating a branch from your feature branch.&lt;/p&gt;

&lt;p&gt;Let's see a visual representation of the problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        f--g--h  feature-1
               \
                i--j--k--l  feature-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Being in this situation, you would like to move the entire tree to be based on &lt;code&gt;master&lt;/code&gt;. Meaning &lt;code&gt;feature-1&lt;/code&gt; is going to be rebased on top of &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;feature-2&lt;/code&gt; on top of &lt;code&gt;feature-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's checkout &lt;code&gt;feature-1&lt;/code&gt; and run &lt;code&gt;git rebase master&lt;/code&gt;. This will lead to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
      |      \
      |       f'--g'--h'  feature-1
       \
        f--g--h--i--j--k--l  feature-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you have opened PR from &lt;code&gt;feature-2&lt;/code&gt; to &lt;code&gt;feature-1&lt;/code&gt; branch, you are going to see the commits from &lt;code&gt;feature-1&lt;/code&gt; in your PR. There is no need to worry because as we can see from the visual representation above and the image below this is expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5TBdDaKV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xxoe6h7ggwbm0eppp79s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TBdDaKV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xxoe6h7ggwbm0eppp79s.png" alt="Rebase feature-1 result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now checkout &lt;code&gt;feature-2&lt;/code&gt; and run &lt;code&gt;git rebase --onto h' h&lt;/code&gt;. This gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
             \
              f'--g'--h'  feature-1
                       \
                        i'--j'--k'--l'  feature-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Keep in mind that sometimes simple &lt;code&gt;git rebase feature-1&lt;/code&gt; is going to work if f/g/h is the same as f'/g'/h'. Git is smart enough and when we use rebase, it is going to/can remove the commits that are with the same set of changes. However, it is hard and annoying to check if everything is the same in another branch, and using &lt;code&gt;--onto&lt;/code&gt; is the better option here because otherwise, it can lead to a branch with commits that don't belong in it.&lt;/p&gt;

&lt;p&gt;You should give &lt;code&gt;--onto&lt;/code&gt; a try. However, if you are not feeling ready or you don't want to use it and end up in the described situation above, there is a solution with an interactive rebase. Rebase &lt;code&gt;feature-2&lt;/code&gt; from &lt;code&gt;feature-1&lt;/code&gt;. Check if there are commits that don't belong in the branch and drop those commits by doing an interactive rebase. If you are not familiar with how to do that, have a look at the previous blog post &lt;a href="https://belev.dev/some-of-the-most-used-git-interactive-rebase-options"&gt;Some of the most used Git interactive rebase options&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This was a problem that we had for a few months. People were surprised by the changes that they have been seeing in open PRs. After all, you are not doing anything and all of a sudden you see some commits in your PR which don't belong there. It seems strange but hopefully, with this article, this will be cleared out and it won't be strange anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to change Git branch's base?
&lt;/h3&gt;

&lt;p&gt;From time to time we need to change the base of a branch. Two examples would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we haven't started our branch from the right branch&lt;/li&gt;
&lt;li&gt;we started working on something from &lt;code&gt;master&lt;/code&gt; but a colleague made some changes in his/her branch that are going to make our life easier. Then maybe we would like to change &lt;code&gt;master&lt;/code&gt; as a base and use the colleague's branch changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's have a visual representation for a better understanding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
             \
              f--g  feature-1
                  \
                   h--i  feature-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We started our branch &lt;code&gt;feature-2&lt;/code&gt; from &lt;code&gt;feature-1&lt;/code&gt; but we did that by mistake. The features turned out to be not connected at all and we would like our &lt;code&gt;feature-2&lt;/code&gt; branch to start from &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is not a surprise that we are going to use &lt;code&gt;--onto&lt;/code&gt;. So we have &lt;code&gt;git rebase --onto &amp;lt;new-base&amp;gt; &amp;lt;old-base&amp;gt;&lt;/code&gt;. Our old base is &lt;code&gt;feature-1&lt;/code&gt;, we started our branch from there. Our new base should be &lt;code&gt;master&lt;/code&gt; because we want our branch to start from it. We are going to execute &lt;code&gt;git rebase --onto master feature-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
            | \
            |  f--g  feature-1
             \
              h--i  feature-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are using &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/"&gt;Git flow&lt;/a&gt; at work and changing the base of a branch comes up from time to. In our case, it is mostly when the hotfix branch is not created from the proper branch. For example, the hotfix branch is opened, but we started our branch with a fix from the release branch. Then we would need to change the base from release to hotfix.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use the third argument of &lt;code&gt;git rebase --onto&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git rebase --onto&lt;/code&gt; takes up a third argument which is used as an end stop inclusive.&lt;/p&gt;

&lt;p&gt;Let's have the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        f--g--h--i--j--k--l  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We want to rebase &lt;code&gt;feature&lt;/code&gt; from &lt;code&gt;master&lt;/code&gt; but take only certain commits - from &lt;code&gt;h&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt;. We have seen how to skip redundant commits by using &lt;code&gt;--onto&lt;/code&gt;. If we only want to do that, we would need to execute &lt;code&gt;git rebase --onto master g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we want a specific commit for the last one. The third argument of &lt;code&gt;--onto&lt;/code&gt; is exactly what we want. So we would need only to say which is the last commit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: it is taken inclusively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run &lt;code&gt;git rebase --onto master g j&lt;/code&gt; and this gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a--b--c--d--e  master
       \
        h--i--j  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;We dived deeper into &lt;code&gt;git rebase --onto&lt;/code&gt;. It is one of the more advanced commands with which we can easily solve certain Git problems with our branches. Even if we don't know about it, we can solve our problems with a combination of commands - normal and interactive rebase, cherry-pick, .etc. As developers, we should try to automate our work as most as possible, so using less number of commands is a sufficient condition to learn about &lt;code&gt;--onto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We covered a lot of things so let's quickly summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A quick recap about &lt;code&gt;git rebase&lt;/code&gt;, what it &lt;em&gt;base&lt;/em&gt; and what does rebase do&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;git rebase --onto&lt;/code&gt; give us by using it&lt;/li&gt;
&lt;li&gt;How to use &lt;code&gt;--onto&lt;/code&gt; to rebase a branch and skip not needed commits&lt;/li&gt;
&lt;li&gt;How to fix our branches after rebase when we have a deeper branch structure - branch from a branch from a branch&lt;/li&gt;
&lt;li&gt;How to change Git branch's base and why would it be useful&lt;/li&gt;
&lt;li&gt;Use the complete form of &lt;code&gt;git rebase --onto&lt;/code&gt; with 3 arguments which allows us to take only certain commits from start to end provided&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading this to the end. I hope you enjoyed it and learned something new. If so, please follow me on &lt;a href="https://twitter.com/BelevMartin"&gt;Twitter&lt;/a&gt; where I will share other tips, new articles, and things I learn. If you would like to learn more, have a chat about software development, or give me some feedback, don't be shy and drop me a DM.&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Some of the most used Git interactive rebase options</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sat, 13 Jun 2020 21:23:06 +0000</pubDate>
      <link>https://dev.to/martinbelev/some-of-the-most-used-git-interactive-rebase-options-2383</link>
      <guid>https://dev.to/martinbelev/some-of-the-most-used-git-interactive-rebase-options-2383</guid>
      <description>&lt;p&gt;This post was originally published on &lt;a href="https://belev.dev/some-of-the-most-used-git-interactive-rebase-options"&gt;https://belev.dev/some-of-the-most-used-git-interactive-rebase-options&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the previous blog post &lt;a href="https://belev.dev/git-merge-vs-rebase-to-keep-feature-branch-up-to-date/"&gt;Git merge vs rebase to keep feature branch up to date&lt;/a&gt; we learn about the differences between &lt;code&gt;merge&lt;/code&gt; and &lt;code&gt;rebase&lt;/code&gt;. If you aren't very familiar with the basics of those commands and haven't read it yet, it is a good idea to do so before diving into this one.&lt;/p&gt;

&lt;p&gt;The idea of this blog post is to show with examples some of the most used options of &lt;code&gt;git rebase&lt;/code&gt; command. In my experience, I observed that this is one of the most misunderstood commands, especially for less experienced Git users. Hopefully, this article will provide useful information and things are going to be clearer after you read it. We will go through the following things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;amend the last commit&lt;/li&gt;
&lt;li&gt;interactive rebase&lt;/li&gt;
&lt;li&gt;squash several commits into a single commit&lt;/li&gt;
&lt;li&gt;fix older commit&lt;/li&gt;
&lt;li&gt;reorder commits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mastering &lt;em&gt;interactive&lt;/em&gt; &lt;code&gt;git rebase&lt;/code&gt; is a good thing because it enables us to keep a clean and linear history of our changes. This is a great benefit especially when a regression has to be discovered. It is making the work of other people more pleasant as well by quicker and easier orientation.&lt;/p&gt;

&lt;p&gt;Before we begin, we should know that all of the examples which we are going to explore from now on are changing Git history. So, please, if you are working on a public branch be extremely careful with it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In general, we shouldn't change history for public branches like &lt;code&gt;master&lt;/code&gt;/&lt;code&gt;develop&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's get started now.&lt;/p&gt;




&lt;h3&gt;
  
  
  Amend the last commit
&lt;/h3&gt;

&lt;p&gt;The provided examples will be with simple text files but they are completely valid in real-life scenarios. Let's start by creating and committing a file with a typo in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "Helo world." &amp;gt; ./hello-world.txt
git add hello-world.txt
git commit -m "Add hello world"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---amend"&gt;git commit --amend&lt;/a&gt; is the command which we are going to use. It is a convenient way to change the latest commit. But what is it doing really?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It creates a new commit which means it changes the history as noted above.&lt;/li&gt;
&lt;li&gt;It has the same parents and author. &lt;code&gt;--reset-author&lt;/code&gt; can be used to change the author.&lt;/li&gt;
&lt;li&gt;It is using the current commit as a base and the commit message is reused if one is not passed through the &lt;code&gt;-m "Message"&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;All staged changes are applied to the commit.&lt;/li&gt;
&lt;li&gt;Provide a way to change the commit message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's fix the typo and execute &lt;code&gt;git commit --amend&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "Hello world." &amp;gt; ./hello-world.txt
git add hello-world.txt
git commit --amend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is going to open your Git editor - mine is Vim and the examples will be with it. We will see something similar to the snippet below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add hello world

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Jun 10 19:48:04 2020 +0300
#
# On branch master
# Changes to be committed:
#       new file:   hello-world.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We didn't provide &lt;code&gt;-m "Message"&lt;/code&gt; but Git allows us to change the message if we want. By click &lt;code&gt;i&lt;/code&gt; to enter &lt;code&gt;insert&lt;/code&gt; mode, we can change the commit message. If we are happy with the changes, click &lt;code&gt;Esc&lt;/code&gt; and enter &lt;code&gt;:wq + &amp;lt;Enter&amp;gt;&lt;/code&gt; to save and exit. With this, the amend is completed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interactive rebase
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/docs/git-rebase#_name"&gt;git rebase&lt;/a&gt; re-applies one-by-one the commits from your current branch onto another. The &lt;code&gt;--interactive&lt;/code&gt; (&lt;code&gt;-i&lt;/code&gt; for short) option provides additional commands for altering individual commits - edit, re-word, squash, .etc. The syntax is the following &lt;code&gt;git rebase -i &amp;lt;after-which-commit&amp;gt;&lt;/code&gt; where &lt;code&gt;&amp;lt;after-which-commit&amp;gt;&lt;/code&gt; is exclusive. Below we can see a part of how it will look and the options from which we can choose to alter certain commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
pick f1a75f4 Add hello world

# Rebase 6995ded..f1a75f4 onto 6995ded (2 commands)
#
# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message
# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
# f, fixup &amp;lt;commit&amp;gt; = like "squash", but discard this commit's log message
# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop &amp;lt;commit&amp;gt; = remove commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Squash several commits into a single commit
&lt;/h3&gt;

&lt;p&gt;I was asked to squash my commits into one in my &lt;a href="https://github.com/opencv/opencv/pull/3967#issuecomment-96981919"&gt;first PR&lt;/a&gt; ever. It was 2015 and I had just started my first job. I didn't know much about Git back then. The only commands I have used were &lt;code&gt;git commit&lt;/code&gt; and &lt;code&gt;git push&lt;/code&gt;. When I received that comment I didn't know how to do it so my only option was to just search and learn something new.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Consider contributing to open source projects as soon as possible. You will only benefit from it. Don't think that fixing a typo or contributing to documentation is a small thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While working we can make a lot of small commits, WIP commits, have commits for fixing PR comments or whatever we decide basically. However, when it comes to merging our branch into &lt;code&gt;master&lt;/code&gt; we couldn't allow everything to get into it. Most of the time, those commits are not bringing much value and there is no need to have them in our &lt;code&gt;master&lt;/code&gt; branch after merging. Especially if you are using &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; and generate a Changelog from the commits. Squashing commits into one is there for us to achieve this.&lt;/p&gt;

&lt;p&gt;Let's see an example of what we want to achieve in the following diagram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Current state
A  master
 \
  B--C--D  feature

* 367eb93 (HEAD -&amp;gt; master) Update text
* 30c1d6a Add hello world
* 70228b2 update master.txt

// Wanted state
A  master
 \
  B'

* 30c1d6a (HEAD -&amp;gt; master) update master.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Count how many commits you would like to squash and execute &lt;code&gt;git rebase -i HEAD~&amp;lt;commit-count&amp;gt;&lt;/code&gt;. In our example it will be 3 commits, so we are going to execute &lt;code&gt;git rebase -i HEAD~3&lt;/code&gt; which will open our Git editor (most of the options will be removed for the sake of brevity):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you are using Vim after every prompt of the Git editor enter &lt;code&gt;:wq + &amp;lt;Enter&amp;gt;&lt;/code&gt; to save and exit which will complete the Git command.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
pick 30c1d6a Add hello world
pick 367eb93 Update text

# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An &lt;strong&gt;important&lt;/strong&gt; thing to keep in mind is that the commits shown in the list are in &lt;strong&gt;reverse&lt;/strong&gt; order. This means the oldest commit will be first on the list. In our example, we will see them as &lt;code&gt;D-C-B&lt;/code&gt;. We will pick the oldest commit and squash the other two into it. The &lt;code&gt;squash&lt;/code&gt; command has a short form that can be used by changing &lt;code&gt;pick&lt;/code&gt; to &lt;code&gt;s&lt;/code&gt;. This is saving us from writing a couple of characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
s 30c1d6a Add hello world  // short version
squash 367eb93 Update text // full version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After this we are going to see a pretty explanatory confirmation screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This is a combination of 3 commits.
# This is the 1st commit message:

update master.txt

# This is the commit message #2:

Add hello world

# This is the commit message #3:

Update text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By using &lt;code&gt;squash&lt;/code&gt; we are keeping all of our previous commit messages. They will be added in the description of the commit in which they were squashed. By using &lt;code&gt;git log&lt;/code&gt; we can see it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 1f4f780510181de87dd4358a1df1bb51f99e8c44 (HEAD -&amp;gt; master)
Author: Martin Belev &amp;lt;martinbelev93@gmail.com&amp;gt;
Date:   Wed Jun 10 19:48:04 2020 +0300

    update master.txt

    Add hello world

    Update text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Discard a commit message
&lt;/h4&gt;

&lt;p&gt;If you don't want the message of a commit consider using &lt;code&gt;fixup&lt;/code&gt; (&lt;code&gt;f&lt;/code&gt; for short) instead. It will discard the commit message but keep the changes from the commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
squash 30c1d6a Add hello world
fixup 367eb93 Update text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will result in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 1f4f780510181de87dd4358a1df1bb51f99e8c44 (HEAD -&amp;gt; master)
Author: Martin Belev &amp;lt;martinbelev93@gmail.com&amp;gt;
Date:   Wed Jun 10 19:48:04 2020 +0300

    update master.txt

    Add hello world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Drop a commit
&lt;/h4&gt;

&lt;p&gt;If you don't want some commits' changes, then you can consider using &lt;code&gt;drop&lt;/code&gt; (&lt;code&gt;d&lt;/code&gt; for short) which will remove the commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
drop 30c1d6a Add hello world
d 367eb93 Update text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will result in removing the added &lt;code&gt;hello-world.txt&lt;/code&gt; file and those two commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 1f4f780510181de87dd4358a1df1bb51f99e8c44 (HEAD -&amp;gt; master)
Author: Martin Belev &amp;lt;martinbelev93@gmail.com&amp;gt;
Date:   Wed Jun 10 19:48:04 2020 +0300

    update master.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this, we have completed the squashing several commits into one example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix older commit
&lt;/h3&gt;

&lt;p&gt;We will look at an example of how to fix older commit. Let's say we have made a couple of commits which we want to keep but we found out that in one of the older commits we missed something. In this case, we want to go back in history and make additional changes to some older commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Mistake in commit D
A--B--C--D--E  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The commit where we made a mistake is 2nd one (counting from the last one inclusive). We will execute the already familiar command &lt;code&gt;git rebase -i HEAD~2&lt;/code&gt; from our previous example. This will lead to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 30c1d6a Add hello world
pick 367eb93 Update text

# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As mentioned previously, we are seeing the commits in reverse order. This means that the 2nd commit which we want to edit is displayed as first in the list. We will use the &lt;code&gt;edit&lt;/code&gt; (&lt;code&gt;e&lt;/code&gt; for short) command to fix our mistake.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;e 30c1d6a Add hello world
pick 367eb93 Update text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By saving and existing Git editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git rebase -i HEAD~2
Stopped at 30c1d6a...  Add hello world
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can see that we stopped at the commit which we want to edit. Git is providing us some helpful tips on what we can do.&lt;/p&gt;

&lt;p&gt;Doesn't &lt;em&gt;You can amend the commit now, with &lt;code&gt;git commit --amend&lt;/code&gt;&lt;/em&gt; look familiar? This was our first example where we learn how to make a change to the last commit. We stopped on a specific commit which is making it last for the time being. Everything we should do now is making our changes and use &lt;code&gt;git commit --amend&lt;/code&gt; like in the first example.&lt;/p&gt;

&lt;p&gt;The only thing left to do, as Git suggested to us, is executing &lt;code&gt;git rebase --continue&lt;/code&gt; with which we successfully fix a mistake in an older commit.&lt;/p&gt;

&lt;p&gt;We went back only to the commit that we need to fix. This is not required specifically. We can rebase more commits and use the &lt;code&gt;edit&lt;/code&gt; command which will stop us on the specified commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reorder commits
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;git rebase -i&lt;/code&gt; we can reorder commits as well. If the commits which we want to reorder don't depend on each other and don't have changes in the same files, it is as simple as cutting the commit we want to move and pasting it before or after some other commit.&lt;/p&gt;

&lt;p&gt;The use case I have when I needed reordering is to squash a commit into a specific one in history. An example would be having &lt;code&gt;A--B--C&lt;/code&gt; and the need to squash &lt;code&gt;A&lt;/code&gt; into &lt;code&gt;C&lt;/code&gt;. Which can occur when we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fix for commit 1&lt;/li&gt;
&lt;li&gt;useful commit 2&lt;/li&gt;
&lt;li&gt;useful commit 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, we want to keep &lt;code&gt;useful commit 1&lt;/code&gt; and &lt;code&gt;useful commit 2&lt;/code&gt; but it doesn't make sense to have &lt;code&gt;fix for commit 1&lt;/code&gt; squashed into &lt;code&gt;useful commit 2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we can have a look at an example. Let's try and move &lt;code&gt;70228b2 update master.txt&lt;/code&gt; before &lt;code&gt;367eb93 (HEAD -&amp;gt; master) Update text&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 367eb93 (HEAD -&amp;gt; master) Update text
* 30c1d6a Add hello world
* 70228b2 update master.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We want to change the history for 3 commits, so we are going to execute &lt;code&gt;git rebase -i HEAD~3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 70228b2 update master.txt
pick 30c1d6a Add hello world
pick 367eb93 Update text

# These lines can be re-ordered; they are executed from top to bottom.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are going to cut &lt;code&gt;pick 70228b2 update master.txt&lt;/code&gt; and paste it after &lt;code&gt;pick 367eb93 Update text&lt;/code&gt; which is going to make it our latest commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 30c1d6a Add hello world
pick 367eb93 Update text
pick 70228b2 update master.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Save and exit the editor with which we have completed the commit reordering. By executing &lt;code&gt;git log --oneline&lt;/code&gt; we can make sure that everything is as expected and &lt;em&gt;update master.txt&lt;/em&gt; is the last commit in our history.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* c8502f8 (HEAD -&amp;gt; master) update master.txt
* ba137dd Update text
* 08497a9 Add hello world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If the commits which you want to reorder depend on each other - for example, we use the changes from commit &lt;code&gt;A&lt;/code&gt; in commit &lt;code&gt;B&lt;/code&gt; but we want to reorder &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;, I would strongly suggest reconsidering reordering. It is very likely to not need reordering but something else instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;My initial idea for this blog post was to be an in-depth, step-by-step tutorial of &lt;code&gt;git rebase&lt;/code&gt;. However, writing it and thinking about the time when I started using Git I realized there is a bunch of stuff going on here and it can be difficult to grasp all at once. At least it was for me, a lot of going and practicing this command until I learned it. So I decided to split it and continue the other part in a separate one which will be about &lt;em&gt;properly rebasing our branches&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's recap what we go through and why/how it can be useful in our day-to-day work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making changes to the latest commit - I am using it mostly for adding additional changes that I missed. I have seen some people who are using it when fixing PR comments instead of making separate commits. The drawback of this is that it is making the subsequent PR review harder because there is no way to see only the changes that were made.&lt;/li&gt;
&lt;li&gt;What is interactive rebase and some of the options we can use with it&lt;/li&gt;
&lt;li&gt;Squashing several commits into a single commit - I see this as one of the most important once in this article. We went through squashing by keeping and discarding commit messages, as well as deleting whole commits. This is extremely useful for keeping a cleaner history.&lt;/li&gt;
&lt;li&gt;Fix older commit - to be honest, this one is rarely used IMO. However, it is good to know because it is used from time to time.&lt;/li&gt;
&lt;li&gt;Reorder commits - I mostly used this when I needed to squash a commit into certain commit (not the previous one). Again, not very widely used but good to know.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We should already see how many things we can achieve by using &lt;code&gt;git rebase -i&lt;/code&gt;. All of the seen options can be combined and used together which makes &lt;code&gt;git rebase -i&lt;/code&gt; extremely powerful.&lt;/p&gt;

&lt;p&gt;Thank you for reading this to the end. I hope you enjoyed it and learned something new. If so, please follow me on &lt;a href="https://twitter.com/BelevMartin"&gt;Twitter&lt;/a&gt; where I will share other tips, new articles, and things I learn. If you would like to learn more, have a chat about software development or give me some feedback, don't be shy and drop me a DM.&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>My first personal website</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sat, 06 Jun 2020 16:34:00 +0000</pubDate>
      <link>https://dev.to/martinbelev/my-first-personal-website-4fm</link>
      <guid>https://dev.to/martinbelev/my-first-personal-website-4fm</guid>
      <description>&lt;p&gt;Hi all,&lt;/p&gt;

&lt;p&gt;Having a personal website was a long wanted project of mine but I always postponed it for different reasons. Today, I am extremely excited to share it with all of you - &lt;a href="https://belev.dev/"&gt;https://belev.dev/&lt;/a&gt;. I am going to use it as a blog and mainly share things around software development from my experience.&lt;/p&gt;

&lt;p&gt;The site is built using &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby&lt;/a&gt; and &lt;a href="https://github.com/LekoArts/gatsby-themes/tree/master/themes/gatsby-theme-minimal-blog"&gt;LekoArts minimal blog theme&lt;/a&gt;. It is deployed using &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;. I bought the domain name from &lt;a href="https://www.namecheap.com/"&gt;Namecheap&lt;/a&gt; and afterwards configure the DNS through &lt;a href="https://docs.netlify.com/domains-https/netlify-dns/"&gt;Netlify DNS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Most probably I am going to write a blog post about my experience building my first personal website and my impressions about Gatsby and Netlify because it was my first touch with them.&lt;/p&gt;

&lt;p&gt;Thank you for reading this and I would really appreciate it if you give the website a try. Any feedback is welcome.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>gatsby</category>
      <category>netlify</category>
    </item>
    <item>
      <title>Git `merge` vs `rebase` to keep feature branch up to date</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Mon, 25 May 2020 14:47:57 +0000</pubDate>
      <link>https://dev.to/martinbelev/git-merge-vs-rebase-to-keep-feature-branch-up-to-date-297</link>
      <guid>https://dev.to/martinbelev/git-merge-vs-rebase-to-keep-feature-branch-up-to-date-297</guid>
      <description>&lt;p&gt;Today we are going to look at how Git &lt;a href="https://git-scm.com/docs/git-merge"&gt;merge&lt;/a&gt; and &lt;a href="https://git-scm.com/docs/git-rebase"&gt;rebase&lt;/a&gt; commands behave while trying to keep feature branch up to date.&lt;/p&gt;

&lt;p&gt;In a large codebase where a lot of people are working we have constant updates to the &lt;code&gt;master&lt;/code&gt; branch. We want to work on top of this branch and always have to latest changes. We can achieve this by either using &lt;code&gt;merge&lt;/code&gt; or &lt;code&gt;rebase&lt;/code&gt; to get the latest changes made in &lt;code&gt;master&lt;/code&gt; branch into our feature branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;merge&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;So what is &lt;a href="https://git-scm.com/docs/git-merge"&gt;merge&lt;/a&gt; doing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Join two or more development histories together&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's now look at an example using &lt;code&gt;merge&lt;/code&gt; to keep our branch up to date. This is pretty simple example with a few commits in each branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* c5d39ef (HEAD -&amp;gt; feature) update 1 feature.txt
* 0c4d97c add feature.txt
| * 4d55c54 (master) update 1 master.txt
|/
* 2358179 add master.txt

// Different representation of the situation
A---B  master
 \
  C---D  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We started our &lt;code&gt;feature&lt;/code&gt; branch from &lt;code&gt;master&lt;/code&gt; where at first there was only one commit &lt;code&gt;A&lt;/code&gt;. We made a commit 'C' in our feature branch. In the mean time someone made a commit &lt;code&gt;B&lt;/code&gt; in &lt;code&gt;master&lt;/code&gt; branch and after that we made another commit &lt;code&gt;D&lt;/code&gt; in our feature branch. We now have to get the latest changes from &lt;code&gt;master&lt;/code&gt; into our feature branch and we are going to use &lt;code&gt;merge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After executing &lt;code&gt;git merge master&lt;/code&gt; from our feature branch we got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   ec3f6dc (HEAD -&amp;gt; feature) Merge branch 'master' into feature
|\
| * 4d55c54 (master) update 1 master.txt
* | c5d39ef update 1 feature.txt
* | 0c4d97c add feature.txt
|/
* 2358179 add master.txt

// Different representation of the situation
A---B  master
 \
  C-B-D-E  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It has it's benefits, of course, as every other thing in software development but the drawbacks in large codebase are huge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is hard to go back and change/clean our feature branch commits.&lt;/li&gt;
&lt;li&gt;It is making hard to follow and find out when/why something was done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this simple example maybe it is understandable what happened. But in real life where we got hundreds of commits and we will make a lot of merge commits which are redundant. You can imagine that this is going to become almost impossible to follow when we are working for a long time on a feature because we will end up with a lot of merge commits.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;rebase&lt;/code&gt; to the rescue
&lt;/h3&gt;

&lt;p&gt;So what is &lt;a href="https://git-scm.com/docs/git-rebase"&gt;rebase&lt;/a&gt; doing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reapply commits on top of another base tip&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will review the same scenario but using &lt;code&gt;rebase&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A---B  master
 \
  C---D  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After executing &lt;code&gt;git rebase master&lt;/code&gt; from our feature branch we got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 7d4b7c0 (HEAD -&amp;gt; feature) update from-rebase.txt
* 5b61ccd add from-rebase.txt
* d694446 (master) update rebase.txt
* 8f8b0e3 add rebase.txt

// Different representation of the situation
A---B  master
     \
      C'-D'  feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We got our changes reapplied over the latest commit from &lt;code&gt;master&lt;/code&gt; branch. &lt;strong&gt;Note:&lt;/strong&gt; the commits have the same set of changes but from Git point of view they are completely different objects and have different hashes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;By using &lt;code&gt;rebase&lt;/code&gt; we benefit from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;making the history in our &lt;code&gt;master&lt;/code&gt; branch much easier to follow because it is linear&lt;/li&gt;
&lt;li&gt;long tramlines from long-lived feature branches&lt;/li&gt;
&lt;li&gt;ability to easily change our feature branch history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a couple of things to keep in mind though:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it can be confusing for less experienced Git users&lt;/li&gt;
&lt;li&gt;we are loosing the chronological order - IMO this is not a problem at all because we achieve series of intentional changes that are made to &lt;code&gt;master&lt;/code&gt; branch&lt;/li&gt;
&lt;li&gt;it can result in fixing the same conflict for every commit in the feature branch - for this one I find really useful the &lt;a href="https://git-scm.com/docs/git-rerere"&gt;git rerere&lt;/a&gt; configuration which is saving the resolved conflicts and then reusing them. With it we don't have to resolve the same conflict all over again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't recommend to blindly use &lt;code&gt;rebase&lt;/code&gt; to keep your feature branches up to date but for larger projects my preference is to use &lt;code&gt;rebase&lt;/code&gt; instead of &lt;code&gt;merge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When I started using Git I find those concepts very confusing, so I hope someone will enjoy this and will find it useful. If this is the case, please follow me on &lt;a href="https://twitter.com/BelevMartin"&gt;Twitter&lt;/a&gt; where I will share another tips and upcoming articles from my experience.&lt;/p&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>How to detect that mobile keyboard pops up in Web?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sat, 16 May 2020 11:33:42 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-detect-that-mobile-keyboard-pops-up-in-web-4gph</link>
      <guid>https://dev.to/martinbelev/how-to-detect-that-mobile-keyboard-pops-up-in-web-4gph</guid>
      <description>&lt;p&gt;Recently we had a feature in which we had to make an animation on our header only when the keyboard on mobiles devices has been displayed so that we can decrease the size of the header and make more space for the user on the screen.&lt;/p&gt;

&lt;p&gt;I think there is no standard way to do this. The options were either listen for input &lt;code&gt;focus&lt;/code&gt; events and based on them to apply our changes, or &lt;code&gt;resize&lt;/code&gt; events where some height calculations could be made to achieve the wanted behaviour. However, both options have their drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;with &lt;code&gt;focus&lt;/code&gt; event we are trying to fight the browser's default behaviour when the keyboard pops up. This being the case the solution seems a little patchy.&lt;/li&gt;
&lt;li&gt;with the &lt;code&gt;resize&lt;/code&gt; event there are some problems on iOS devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does someone know another way of detecting that the mobile keyboard is displayed?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How to prevent React setState on unmounted component - a different approach</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sat, 16 May 2020 09:45:59 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-prevent-react-setstate-on-unmounted-component-a-different-approach-2meg</link>
      <guid>https://dev.to/martinbelev/how-to-prevent-react-setstate-on-unmounted-component-a-different-approach-2meg</guid>
      <description>&lt;p&gt;If you are working with React, most probably you have already seen the below issues a lot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They can be caused easily by not cleaning up when component unmounts or route is changed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;setInterval&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;asynchronous request to the server for fetching data when component mounts&lt;/li&gt;
&lt;li&gt;form submit handler sending request to the server&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is this indicating?
&lt;/h3&gt;

&lt;p&gt;This is just a warning and it is not stopper for development, but as such it is showing that in our application code there may be some issues - for example we can have memory leak which can lead to performance issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are we going to cover in this post?
&lt;/h3&gt;

&lt;p&gt;Today we are going to look at a solution leveraging &lt;code&gt;Observables&lt;/code&gt; by using &lt;a href="https://rxjs.dev/guide/overview"&gt;RxJS&lt;/a&gt; which will make us almost forget about the described issues. The solution is focused on making requests to the server, we are not going to cover &lt;code&gt;setTimeout&lt;/code&gt;/&lt;code&gt;setInterval&lt;/code&gt; usage. We are also going to be using hooks. I am going to provide more information about our use case and how ended up with this solution.&lt;/p&gt;

&lt;p&gt;We are &lt;strong&gt;not&lt;/strong&gt; going to look at other solutions like &lt;code&gt;Cancellable Promises&lt;/code&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController"&gt;AbortController&lt;/a&gt; or &lt;code&gt;isMounted&lt;/code&gt; usage which is actually an antipattern - &lt;a href="https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html"&gt;https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html&lt;/a&gt;. We are &lt;strong&gt;not&lt;/strong&gt; going to get in details about &lt;code&gt;RxJS&lt;/code&gt; as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do we ended up here?
&lt;/h3&gt;

&lt;p&gt;For a long time we were using Promises for our requests. We started seeing the described warning more and more which was just showing us that we have to do something to solve it. I won't lie, at first we had a couple of usages of &lt;code&gt;isMounted&lt;/code&gt; which no one liked. We felt that it is not actually solving the problem but it is just a work around which prevented the call to &lt;code&gt;setState&lt;/code&gt;. We knew that this can't be the solution for us because it doesn't seem OK to write such additional code for every request that we are going to make.&lt;/p&gt;

&lt;p&gt;The good thing though was that under the hood we were already using &lt;code&gt;RxJS&lt;/code&gt; and &lt;code&gt;Observables&lt;/code&gt;. We are working in a really big application so just removing the &lt;code&gt;Promise&lt;/code&gt; usage wasn't a solution. We were going to gradually remove the &lt;code&gt;Promise&lt;/code&gt; usage and start using only &lt;code&gt;Observables&lt;/code&gt;. We should mention that we can unsubscribe from &lt;code&gt;Observable&lt;/code&gt;, but again this is something that we should do for every request which is just not good enough...&lt;/p&gt;

&lt;p&gt;I am feeling grateful and want to thank Jafar Husain for the wonderful course &lt;a href="https://frontendmasters.com/courses/asynchronous-javascript/"&gt;Asynchronous Programming in JavaScript (with Rx.js Observables)&lt;/a&gt; from which I learned so much and found the solution. The course is also available in Pluralsight - &lt;a href="https://www.pluralsight.com/courses/asynchronous-javascript-rxjs-observables"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the solution?
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Different way to think about our problem
&lt;/h5&gt;

&lt;p&gt;As Front-end developers, if we think more deeply about it, most of the things that we are doing can be described as a collection/stream of events happening over time. If we think about them as collection then this gives us new horizons because we know so many operations that we can do over collections (or at least I felt so). With a couple of operations like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;mergeMap&lt;/code&gt;, &lt;code&gt;concatMap&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;switchMap&lt;/code&gt; we can achieve so much. Jafar Husain is describing all of this in much greater details with great examples in his course - just give it a try.&lt;/p&gt;

&lt;p&gt;So, let's think about our request(s) as one collection (Observable) - let's call this one &lt;code&gt;A&lt;/code&gt;. And our component unmounting as another - let's call it &lt;code&gt;B&lt;/code&gt;. We would like to somehow combine those two in such a way that &lt;code&gt;A&lt;/code&gt; should emit values until an event occurs in &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Choosing &lt;code&gt;RxJS&lt;/code&gt; operator
&lt;/h5&gt;

&lt;p&gt;We described in abstract way what we want to achieve. Now let's look at some of the implementation details. We are using &lt;code&gt;RxJS&lt;/code&gt; which comes with a great number of operators that will solve most of our problems. When we look at the &lt;a href="https://rxjs.dev/api#operators"&gt;operators&lt;/a&gt;, &lt;a href="https://rxjs.dev/api/operators/takeUntil"&gt;takeUntil&lt;/a&gt; looks perfect for our use case - "Emits the values emitted by the source Observable until a notifier Observable emits a value.". This is exactly what we wanted so now we know that we are going to use &lt;code&gt;takeUntil&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Going for the implementation
&lt;/h5&gt;

&lt;p&gt;We are going to implement a custom hook which will be used to solve our problem. Let's start with the basics and just declare the structure of our hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;Observable&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;rxjs&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;useUnmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;useUnmount$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we have our hook, but we should add the implementation. We should return &lt;code&gt;Observable&lt;/code&gt; and being able to emit values. We are going to use &lt;code&gt;Subject&lt;/code&gt; for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Subject&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;rxjs&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;useUnmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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;unmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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;unmount$&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;useUnmount$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Good, but we are not there yet. We know that unmount will happen only once so we can emit and complete after this happens. We are going to use &lt;code&gt;useEffect&lt;/code&gt; cleanup function to understand when the component is unmounted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Subject&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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;const&lt;/span&gt; &lt;span class="nx"&gt;useUnmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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;unmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// implicit return instead of wrapping in {} and using return&lt;/span&gt;
      &lt;span class="nx"&gt;unmount$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;unmount$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&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;unmount$&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;unmount$&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;useUnmount$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It looks like we completed our implementation, but we are not yet. What is going to happen if the component where &lt;code&gt;useUnmount$&lt;/code&gt; is used unmounts? We are going to create another &lt;code&gt;Subject&lt;/code&gt;, emit and complete the previous one. We wouldn't want this behavior, but instead emitting only once when the component in which is used unmounts. &lt;code&gt;useMemo&lt;/code&gt; coming to the rescue here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Subject&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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;const&lt;/span&gt; &lt;span class="nx"&gt;useUnmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;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;unmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&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="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;unmount$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;unmount$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&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;unmount$&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;unmount$&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;useUnmount$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this we completed the implementation of our custom hook, but we still have to plug it into our collection &lt;code&gt;A&lt;/code&gt; which is responsible for our requests. We will imagine that our request abstraction is returning &lt;code&gt;Observable&lt;/code&gt;. And now the only thing left is to use the &lt;code&gt;useUnmount$&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;useCallback&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;takeUntil&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;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useUnmount$&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;./useUnmount&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;useRequest&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;unmount$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useUnmount$&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// from("response") should be replaced by your implementation returning Observable&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;takeUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unmount$&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;unmount$&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;useRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Observables&lt;/code&gt; can come in handy in many ways. It is a topic worth learning about and I believe it is going to be used more and more in the future. In combination with hooks, IMO we had come up with a very clean solution. It is saving us the cognitive load to think about cleaning up after each request that is made. I think this is a great win because there is one thing less to think/worry about while developing or reviewing a PR.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>Create PR against release branch from merged into develop branch?</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Wed, 21 Aug 2019 17:11:26 +0000</pubDate>
      <link>https://dev.to/martinbelev/create-pr-against-release-branch-from-merged-into-develop-branch-2efn</link>
      <guid>https://dev.to/martinbelev/create-pr-against-release-branch-from-merged-into-develop-branch-2efn</guid>
      <description>&lt;h4&gt;
  
  
  Given the following scenario:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;the main development branch is &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a feature branch (&lt;code&gt;f&lt;/code&gt; for short) is created from &lt;code&gt;develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a pull request is opened for the implemented feature&lt;/li&gt;
&lt;li&gt;the new feature should land in the new release but a release branch is created from &lt;code&gt;develop&lt;/code&gt; before the feature is reviewed and merged&lt;/li&gt;
&lt;li&gt;the PR gets reviewed and merged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the &lt;code&gt;f&lt;/code&gt; branch is merged into develop we should create a PR to the new release branch.&lt;/p&gt;

&lt;p&gt;P.S. &lt;code&gt;f&lt;/code&gt; branch is rebased over &lt;code&gt;develop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We decided to go with a new branch from the release branch and just cherry pick the commit that we wanted. But it was because we were in a hurry and the commit was only 1. I am still wondering if there is some other easier way to do this.&lt;/p&gt;

&lt;p&gt;What do you think will be the best and easiest way to do it?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>git</category>
    </item>
    <item>
      <title>How to enable JUnit 5 in new Spring Boot project</title>
      <dc:creator>Martin Belev</dc:creator>
      <pubDate>Sun, 03 Feb 2019 13:54:41 +0000</pubDate>
      <link>https://dev.to/martinbelev/how-to-enable-junit-5-in-new-spring-boot-project-29a8</link>
      <guid>https://dev.to/martinbelev/how-to-enable-junit-5-in-new-spring-boot-project-29a8</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally posted on &lt;a href="https://medium.com/@martinbelev/how-to-enable-junit-5-in-new-spring-boot-project-f95247cd2a3e" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to enable JUnit 5 in a newly created Spring&lt;br&gt;
Boot project. We are going through the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize new Sprint Boot project&lt;/li&gt;
&lt;li&gt;Having a look at our &lt;code&gt;pom.xml&lt;/code&gt; and mostly on &lt;code&gt;sprint-boot-starter-test&lt;/code&gt;
dependency, going a little deeper in &lt;code&gt;spring-boot-starter-test&lt;/code&gt; and see what
JUnit version it uses&lt;/li&gt;
&lt;li&gt;How to exclude child dependency that comes from one of our dependencies using
Maven&lt;/li&gt;
&lt;li&gt;Add JUnit 5&lt;/li&gt;
&lt;li&gt;Migrate JUnit 4 to JUnit 5&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;1) First, let’s go to &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Boot initializr&lt;/a&gt; and generate a new project.&lt;/p&gt;

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

&lt;p&gt;The defaults should be fine and you can click the “Generate Project” button. You should have downloaded a .zip archive of the starter Sprint Boot project. Unzip it and open it with IDE of your choice (I am using IntelliJ and the following code samples and examples will be shown from it). After opening it, you should see the following structure:&lt;/p&gt;

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

&lt;p&gt;2) Now let’s focus on the &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;pom.xml&lt;/code&gt; we can see the following dependency which includes libraries (such as JUnit, Hamcrest, and Mockito) for testing Spring Boot applications.&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We are going a little deeper to see the exact dependencies and their versions focusing on &lt;code&gt;junit&lt;/code&gt; with which &lt;code&gt;spring-boot-starter-test&lt;/code&gt; comes (in IntelliJ you can do this by &lt;code&gt;Ctrl + click&lt;/code&gt; onto &lt;code&gt;spring-boot-starter-test&lt;/code&gt;. In the snippet below, we can see that &lt;code&gt;sprint-boot-starter-test&lt;/code&gt; comes with JUnit 4.12 but there is JUnit 5 already. So how can we use the newer version of JUnit in our new Spring Boot project?&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.12&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;3) We should have a way to exclude JUnit 4 because we are currently depending on it because of &lt;code&gt;spring-boot-starter-test&lt;/code&gt;. We can do this by adding the following lines to our &lt;code&gt;spring-boot-starter-test&lt;/code&gt; dependency by which we exclude JUnit 4.&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;4) We are now going to configure JUnit 5 as a dependency using Maven. We will add the following dependencies in &lt;code&gt;pom.xml&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-api&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.3.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter-engine&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.3.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And we should add the following maven plugin to our build plugins&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.22.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;5) We have removed the dependency of JUnit 4, we have added JUnit 5 and now it is time to make a little code changes in order to use JUnit 5. Let’s focus on &lt;code&gt;DemoApplicationTests.java&lt;/code&gt; where we can see the following code&lt;/p&gt;

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


&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.runner.RunWith&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.context.junit4.SpringRunner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringRunner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplicationTests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;contextLoads&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Actually, the only things that we have to change are the &lt;code&gt;RunWith&lt;/code&gt; annotation because it’s from JUnit 4 and the import of &lt;code&gt;Test&lt;/code&gt; annotation. After the change, our test should look like&lt;/p&gt;

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

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.extension.ExtendWith&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.context.junit.jupiter.SpringExtension&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ExtendWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringExtension&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplicationTests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;contextLoads&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You should be ready to start writing tests using JUnit 5 now. : )&lt;/p&gt;

</description>
      <category>java</category>
      <category>junit</category>
      <category>testing</category>
      <category>springboot</category>
    </item>
  </channel>
</rss>
