<?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: Robbie</title>
    <description>The latest articles on DEV Community by Robbie (@rodw1995).</description>
    <link>https://dev.to/rodw1995</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%2F327216%2F4fd321c9-febc-475c-babb-bebb5e4e6428.png</url>
      <title>DEV Community: Robbie</title>
      <link>https://dev.to/rodw1995</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rodw1995"/>
    <language>en</language>
    <item>
      <title>RamdaJS: transduce</title>
      <dc:creator>Robbie</dc:creator>
      <pubDate>Fri, 03 Apr 2020 08:41:16 +0000</pubDate>
      <link>https://dev.to/rodw1995/ramdajs-transduce-59c6</link>
      <guid>https://dev.to/rodw1995/ramdajs-transduce-59c6</guid>
      <description>&lt;p&gt;When I was looking at the Ramda docs I came across the &lt;a href="https://ramdajs.com/docs/#transduce"&gt;transduce&lt;/a&gt; function. And at first I found it rather difficult to understand what exactly the function did and what you could do with it. So I did some reading about &lt;strong&gt;transducers&lt;/strong&gt; in general and started trying some things to fully understand. In this post I will describe the steps I took towards fully understanding this &lt;strong&gt;transduce&lt;/strong&gt; function.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a transducer?
&lt;/h1&gt;

&lt;p&gt;First things first. What are transducers and what can we do with them? Well, you may have guessed it already, but the word &lt;strong&gt;transduce&lt;/strong&gt; is just a combination of the words &lt;strong&gt;transform&lt;/strong&gt; and &lt;strong&gt;reduce&lt;/strong&gt;. And that is also what it does:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A transducer &lt;strong&gt;transforms&lt;/strong&gt; items while &lt;strong&gt;reducing&lt;/strong&gt; them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;I assume you have an understanding of what reducers are. If not, there are a lot of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce"&gt;resources&lt;/a&gt; out there that will help you and it's not that difficult.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Doc example
&lt;/h1&gt;

&lt;p&gt;Now we have some idea of what a transducer does, we can have a look at the example code from the &lt;a href="https://ramdajs.com/docs/#transduce"&gt;Ramde docs&lt;/a&gt; and try to understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&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;transducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&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="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what is happening here? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first 2 lines are pretty clear, I think. We declare an array of numbers and create a transducer function which is just a composed function of:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;R.map(R.add(1))&lt;/strong&gt;: map over an array and add 1 to each element&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R.take(2)&lt;/strong&gt;: take the first 2 elements of an array&lt;/li&gt;
&lt;li&gt;We use &lt;strong&gt;R.compose&lt;/strong&gt; here so it will perform a &lt;strong&gt;right-to-left&lt;/strong&gt; composition, i.e. first &lt;strong&gt;take&lt;/strong&gt; and then &lt;strong&gt;map&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;The last line is where we are going to use the &lt;strong&gt;transduce&lt;/strong&gt; function. The function accepts 4 arguments:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The transducer&lt;/strong&gt;: function that performs the transformation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The iterator&lt;/strong&gt;: in our case we will &lt;strong&gt;append&lt;/strong&gt; the &lt;strong&gt;current value&lt;/strong&gt; to the &lt;strong&gt;accumulator&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The initial value&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The list to iterate&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we run this example code the result will be an array of &lt;strong&gt;[2, 3]&lt;/strong&gt;. And that is understandable because in the &lt;strong&gt;composed transducer&lt;/strong&gt; function we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Take&lt;/strong&gt; the first 2 elements of the array -&amp;gt; &lt;strong&gt;[1, 2]&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add 1&lt;/strong&gt; to each element -&amp;gt; &lt;strong&gt;[2, 3]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But now you may ask yourself: What is the difference then with just running the composed transducer function with the numbers array? That will have the same result, right? Yes, it has!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only running the transducer function with the numbers array will return the same result&lt;/span&gt;
&lt;span class="nx"&gt;transducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, why are we using this &lt;code&gt;R.transduce&lt;/code&gt; function and not just the composed transducer function? &lt;strong&gt;What is the added value of using &lt;code&gt;R.transduce&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefits of &lt;code&gt;R.transduce&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;I found this point confusing at first, but it's pretty simple if you understand. Because the benefit of using transduce is &lt;strong&gt;performance&lt;/strong&gt; 🎉&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transducers are all about &lt;strong&gt;replacing multiple trips&lt;/strong&gt; through the same data &lt;strong&gt;with a single one&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So with using &lt;code&gt;R.transduce&lt;/code&gt; the composed transducer function will be used in a different &lt;strong&gt;optimised&lt;/strong&gt; way, where the array is only &lt;strong&gt;iterated once&lt;/strong&gt;! We can make that clear by replacing the &lt;code&gt;take&lt;/code&gt; with another &lt;code&gt;add&lt;/code&gt; and by adding some logs to the transducer function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LEFT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD 1 to&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&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="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD 2 to&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RIGHT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you will see a difference in output when using the transducer directly and when using it with &lt;code&gt;R.transduce&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;transducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [4, 5, 6, 7]&lt;/span&gt;
&lt;span class="c1"&gt;// RIGHT&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 2 to [3, 4, 5, 6]&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 1 to [4, 5, 6, 7]&lt;/span&gt;
&lt;span class="c1"&gt;// LEFT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understandable and as expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Iterate over the array and add 2&lt;/li&gt;
&lt;li&gt;Iterate over the array (&lt;strong&gt;again!&lt;/strong&gt;) and add 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, can you guess what &lt;code&gt;R.transduce&lt;/code&gt; will output when using our modified transduce function? Because it still had a surprise for me when running it for the first time. Let's see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [4, 5, 6, 7]&lt;/span&gt;
&lt;span class="c1"&gt;// LEFT&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 1 to 1&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 2 to 2&lt;/span&gt;
&lt;span class="c1"&gt;// RIGHT&lt;/span&gt;

&lt;span class="c1"&gt;// LEFT&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 1 to 2&lt;/span&gt;
&lt;span class="c1"&gt;// ADD 2 to 3&lt;/span&gt;
&lt;span class="c1"&gt;// RIGHT&lt;/span&gt;

&lt;span class="c1"&gt;// ... and the same for the numbers 3 and 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we can see clearly now is that &lt;strong&gt;the array is only iterated once&lt;/strong&gt;. Each element is passed to the transformer function before moving to the next element. So that is the &lt;strong&gt;performance&lt;/strong&gt; benefit we were talking about.&lt;/p&gt;

&lt;p&gt;But what you also must notice in the output is that &lt;code&gt;R.transduce&lt;/code&gt; is performing the operations &lt;strong&gt;left-to-right&lt;/strong&gt; instead of right-to-left what you would expect when using &lt;code&gt;R.compose&lt;/code&gt;. And that is just something you &lt;strong&gt;must know&lt;/strong&gt; about transducers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transducers compose in an opposite order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, using &lt;code&gt;R.compose&lt;/code&gt; with a transducer performs &lt;strong&gt;left-to-right&lt;/strong&gt; and using &lt;code&gt;R.pipe&lt;/code&gt; with a transducer performs &lt;strong&gt;right-to-left&lt;/strong&gt;. The exact &lt;strong&gt;opposite&lt;/strong&gt; when using normal function composition.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Reading the Ramda docs about &lt;code&gt;R.transduce&lt;/code&gt; can be very confusing at first. But in the end it is not that difficult to understand what the function does. At least, I hope you feel the same after reading this post.&lt;/p&gt;

&lt;p&gt;Transducers can just be very useful if you need to combine a number of operations (&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;take&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;) over a list. With a transducer it's then possible to &lt;strong&gt;optimize&lt;/strong&gt; this process and keep your code &lt;strong&gt;clean&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you still have any questions about transducers, don't hesitate 😄&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheers&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ramda</category>
      <category>functional</category>
      <category>transducers</category>
    </item>
    <item>
      <title>How I became a software developer in the traditional way</title>
      <dc:creator>Robbie</dc:creator>
      <pubDate>Fri, 27 Mar 2020 14:29:50 +0000</pubDate>
      <link>https://dev.to/rodw1995/how-i-became-a-software-developer-in-the-traditional-way-1c73</link>
      <guid>https://dev.to/rodw1995/how-i-became-a-software-developer-in-the-traditional-way-1c73</guid>
      <description>&lt;p&gt;Lately I read and hear more and more stories from people who have become software developers by following a &lt;strong&gt;bootcamp&lt;/strong&gt;. I didn't follow a bootcamp but became a software developer in the more &lt;strong&gt;traditional way&lt;/strong&gt;. So I thought maybe it's fun and interesting to write this story down.&lt;/p&gt;

&lt;h1&gt;
  
  
  Teenager
&lt;/h1&gt;

&lt;p&gt;It all started for me as a &lt;strong&gt;14 year old boy&lt;/strong&gt; in my room behind the computer. I don't remember exactly how but I got in touch with so-called click-to-pay websites. In short you got paid by clicking on a link or by having others clicking on your link. You would receive like 1 cent per 1000 clicks. And I wanted to become rich so… 😆&lt;/p&gt;

&lt;p&gt;I found out that with clicking on your own link every day you are not going to earn much. But there was also an option to start your own click-to-pay website. With that, you pay others a little bit less than you receive for clicking on your links. And yes, this was actually a kind of &lt;strong&gt;pyramid scheme&lt;/strong&gt;. But you could earn some pocket money with it, what is nice as a teenager.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So I bought a website and started my own click-to-pay website.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's &lt;strong&gt;where it all started&lt;/strong&gt; for me. I started &lt;strong&gt;experimenting&lt;/strong&gt;, made changes to &lt;strong&gt;the layout&lt;/strong&gt;, in &lt;strong&gt;PHP scripts&lt;/strong&gt;, in the &lt;strong&gt;database&lt;/strong&gt;. Often after school and in the evenings, with a real &lt;strong&gt;trial-and-error&lt;/strong&gt; approach, just on the live website... 🙈 It was really &lt;strong&gt;a lot of fun&lt;/strong&gt;, especially when something at the end worked out as you wanted.&lt;/p&gt;

&lt;p&gt;In this way I taught myself the basic knowledge of PHP, HTML, CSS, JavaScript and MySQL. And I went on with it, found it interesting and wanted to make more. Which eventually enabled me to create &lt;strong&gt;my very own click-to-pay script&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks to web.archive.org you can still &lt;a href="https://web.archive.org/web/20110924014235/http://www.cashpiraat.nl/index.php"&gt;visit&lt;/a&gt; a website that used it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, you are 16 and you want to learn more. And I took an important step in that when I came into contact with the &lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt; framework. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At that time Laravel 3.0 was just released and it was not very popular yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With Laravel I really took big steps in my development towards becoming a software professional. I learned a lot of new things, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MVC Pattern&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;Inversion of Control&lt;/li&gt;
&lt;li&gt;Object Relational Modeling&lt;/li&gt;
&lt;li&gt;HTML templating (blade)&lt;/li&gt;
&lt;li&gt;Database migrations&lt;/li&gt;
&lt;li&gt;And more things that I forget now...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I made various (hobby) websites in Laravel, including a website for the local football club.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's still &lt;a href="http://www.irene58.nl/"&gt;online&lt;/a&gt; but please don't try to hack it 🙏&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With using Laravel, I honestly thought I was there, that I knew pretty much everything about programming. I was quite wrong of course. For example, my controllers were huge with all the business logic in it. But I certainly already had &lt;strong&gt;a lot of knowledge for a 17 year old boy&lt;/strong&gt;, I think.&lt;/p&gt;

&lt;h1&gt;
  
  
  Student
&lt;/h1&gt;

&lt;p&gt;Because my interests in web development, my choice to go study &lt;strong&gt;computer science&lt;/strong&gt; was no surprise for anyone. However I did almost stop after the first week, because I was really wondering what I was doing there. I mean come on, &lt;strong&gt;a 2 hour lesson on HTML and CSS and how to give a text a different color...&lt;/strong&gt; I was already able to do that 4 years ago. In short, the first half year was not very challenging for me. But it was also logical that it all started from zero, because there were also students without prior knowledge. And eventually I'm very glad that I went through. Because I was &lt;strong&gt;learning a lot of other things&lt;/strong&gt;, besides the actual programming, that are important for a software professional, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working in teams&lt;/li&gt;
&lt;li&gt;Communication&lt;/li&gt;
&lt;li&gt;UML and other modelling tools&lt;/li&gt;
&lt;li&gt;Writing documentation&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think these are the important skills you learn in college and I'm wondering if you will learn them at a &lt;strong&gt;coding bootcamp&lt;/strong&gt;. At my study we didn't really learn a programming language though, you had to do that out of your own interest (in my case that was still Laravel and PHP).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;During college I never had to write a single line of JavaScript code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Professional
&lt;/h1&gt;

&lt;p&gt;After 4 years I graduated and my professional career could start. First, I was looking for a job in Laravel and PHP, but in the end I got a job as a &lt;strong&gt;NodeJS Backend Developer&lt;/strong&gt; at a &lt;strong&gt;digital agency&lt;/strong&gt;. Which I also liked because in that way I could learn something new, and it was JavaScript so not really new new. And in addition, I was very happy that I could just be the backend developer and not have to look at the frontend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I couldn't have imagined then that there would come a time that I would start enjoying frontend stuff.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yet, I already left my first job after 7 months. The most important reasons for this, were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No real challenges&lt;/li&gt;
&lt;li&gt;No work

&lt;ul&gt;
&lt;li&gt;After a project was finished, I had to entertain myself for 2 months, waiting for the next project.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Not feeling valued&lt;/li&gt;
&lt;li&gt;Lack of trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, I received an offer from a &lt;strong&gt;cryptocurrency startup&lt;/strong&gt; which was really appealing to me. And so I made my first career move.&lt;/p&gt;

&lt;p&gt;And at this startup I got a lot of freedom and, with that, a lot of responsibility. I learned a lot, worked on challenging and fun projects, &lt;a href="https://dev.to/rodw1995/show-dev-writing-a-trade-app-in-react-native-and-expo-3fpl"&gt;including my first app&lt;/a&gt; and discovered the &lt;strong&gt;fullstack developer&lt;/strong&gt; in me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With using React I suddenly liked doing things in the frontend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm very curious what my future career will bring me and what I will learn in the coming years. Because that's really the best part about being a software developer, constantly learning new things. You could even say it's a &lt;strong&gt;never ending bootcamp&lt;/strong&gt; 😉&lt;/p&gt;

&lt;p&gt;So that's my life as a software developer in short so far and I'm only 24 years old. A lot of beautiful years to come! Keep on coding 😄&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheers&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>life</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Cancel your promises when a component unmounts</title>
      <dc:creator>Robbie</dc:creator>
      <pubDate>Sat, 21 Mar 2020 08:25:23 +0000</pubDate>
      <link>https://dev.to/rodw1995/cancel-your-promises-when-a-component-unmounts-gkl</link>
      <guid>https://dev.to/rodw1995/cancel-your-promises-when-a-component-unmounts-gkl</guid>
      <description>&lt;p&gt;In basically all React applications you will need to perform some async operations in your components. A common example would be to fetch the authenticated user on mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useDidMount&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;@rooks/use-did-mount&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;useState&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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the authenticated user on mount&lt;/span&gt;
  &lt;span class="nx"&gt;useDidMount&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;fetchAuthenticatedUser&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;// Rest of the component...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;At first glance, this all seems fairly valid, but it can cause the following error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: Can't perform a React state update 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 a useEffect cleanup function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what does this mean? It is quite logical what happened if this error occurs in the above example, in that case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component &lt;strong&gt;unmounted before&lt;/strong&gt; the "fetchAuthenticatedUser" promise was &lt;strong&gt;resolved&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What means that if the promise &lt;em&gt;does&lt;/em&gt; resolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;setUser&lt;/strong&gt; function is &lt;strong&gt;called&lt;/strong&gt; on an &lt;strong&gt;unmounted&lt;/strong&gt; component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not allowed and to resolve this issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The promise has to be &lt;strong&gt;canceled&lt;/strong&gt; when the component &lt;strong&gt;unmounts&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how are we going to fix this?&lt;/p&gt;

&lt;h1&gt;
  
  
  Component still mounted?
&lt;/h1&gt;

&lt;p&gt;First we need a way to check if a component is still mounted. We can do so&lt;br&gt;
by making use of the &lt;strong&gt;cleanup&lt;/strong&gt; function in a &lt;strong&gt;useEffect&lt;/strong&gt; hook. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every effect may return a function that cleans up after it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So with the help of this cleanup function we can keep track of the mounted state and we can fix the potential error in the example code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useDidMount&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;@rooks/use-did-mount&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;useState&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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&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;// Keep track of the mounted state&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mountedRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the authenticated user on mount&lt;/span&gt;
  &lt;span class="nx"&gt;useDidMount&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;// Is mounted now&lt;/span&gt;
    &lt;span class="nx"&gt;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;fetchAuthenticatedUser&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;// Before calling "setUser", check if the component is still mounted&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;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;// Also in "useDidMount" we can use this cleanup function because it is just a wrapper around "useEffect"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Called before unmount by React&lt;/span&gt;
      &lt;span class="nx"&gt;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Rest of the component...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fix the potential error already. However, we probably need to do this in many components and therefore we can make it a little bit cleaner and more &lt;strong&gt;DRY&lt;/strong&gt; with a custom hook called &lt;strong&gt;useMountedState&lt;/strong&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  useMountedState
&lt;/h1&gt;

&lt;p&gt;We basically want to extract the "mountedRef" part from above code in a custom hook. So we can then return a function which returns the current mounted state of the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;mountedRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Basically the same as "useDidMount" because it has no dependencies&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&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;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="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;// The cleanup function of useEffect is called by React on unmount&lt;/span&gt;
      &lt;span class="nx"&gt;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&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="nx"&gt;mountedRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we can use this custom hook to make the fix a little bit cleaner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useDidMount&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;@rooks/use-did-mount&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;useState&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="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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useMountedState&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;./useMountedState&lt;/span&gt;&lt;span class="dl"&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="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;isMounted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMountedState&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the authenticated user on mount&lt;/span&gt;
  &lt;span class="nx"&gt;useDidMount&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;fetchAuthenticatedUser&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;// Before calling "setUser", check if the component is still mounted&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;isMounted&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Rest of the component...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already a little better, right? But we can do it even better with another custom hook, which will use the &lt;strong&gt;useMountedState&lt;/strong&gt; hook internally. We will call this one &lt;strong&gt;useCancelablePromise&lt;/strong&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  useCancelablePromise
&lt;/h1&gt;

&lt;p&gt;The purpose of this hook is to create a wrapper function that we can use in our components around promises. So the hook needs to give us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A function which &lt;strong&gt;accepts a promise&lt;/strong&gt; and &lt;strong&gt;returns a promise&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Where the returned promise resolves or rejects with the &lt;strong&gt;result of the accepted/wrapped promise&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Only when the component is still &lt;strong&gt;mounted&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;May sound a bit tricky, but it's pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useMountedState&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;./useMountedState&lt;/span&gt;&lt;span class="dl"&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="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;// Use our just created custom hook to keep track of the mounted state&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isMounted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMountedState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Create our function that accepts a promise&lt;/span&gt;
  &lt;span class="c1"&gt;// Note the second parameter is a callback for onCancel. You might need this in rare cases&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;onCancel&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="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// Wrap the given promise in a new promise&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;promise&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&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;// Only resolve the returned promise if mounted&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;isMounted&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Resolve with the result of the wrapped promise&lt;/span&gt;
            &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Only reject the returned promise if mounted&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;isMounted&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Reject with the error of the wrapped promise&lt;/span&gt;
            &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="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;finally&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;// Call the onCancel callback if not mounted&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isMounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;onCancel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;onCancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isMounted&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;Now we can change our example code for the last time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useDidMount&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;@rooks/use-did-mount&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;useState&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="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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useCancelablePromise&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;./useCancelablePromise&lt;/span&gt;&lt;span class="dl"&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="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;makeCancelable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCancelablePromise&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch the authenticated user on mount&lt;/span&gt;
  &lt;span class="nx"&gt;useDidMount&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;makeCancelable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchAuthenticatedUser&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;// Rest of the component...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaner and still safe! Because the promise returned from &lt;strong&gt;makeCancelable&lt;/strong&gt; is only resolved (or rejected) if the component is mounted 🎉&lt;/p&gt;

&lt;h1&gt;
  
  
  Library
&lt;/h1&gt;

&lt;p&gt;The source code of both custom hooks created in this article can be found on my Github:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rodw1995/use-mounted-state"&gt;useMountedState&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/rodw1995/use-cancelable-promise"&gt;useCancelablePromise&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And they are also both published as a npm package. So you can use them directly in your React (native) project by just adding them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;yarn&lt;/span&gt; add @rodw95/use-mounted-state
&lt;span class="k"&gt;yarn&lt;/span&gt; add @rodw95/use-cancelable-promise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So make your promises cancelable and safe! Happy coding 😀&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheers&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>promise</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Show DEV: Writing a Trade App in React Native and Expo</title>
      <dc:creator>Robbie</dc:creator>
      <pubDate>Fri, 20 Mar 2020 07:32:34 +0000</pubDate>
      <link>https://dev.to/rodw1995/show-dev-writing-a-trade-app-in-react-native-and-expo-3fpl</link>
      <guid>https://dev.to/rodw1995/show-dev-writing-a-trade-app-in-react-native-and-expo-3fpl</guid>
      <description>&lt;p&gt;In this article I want to describe the process I went through while creating an App with &lt;strong&gt;React Native and Expo&lt;/strong&gt; as a single developer on the task. Which is quite exciting if you don't have that much experience with App development...&lt;/p&gt;

&lt;h1&gt;
  
  
  Goal
&lt;/h1&gt;

&lt;p&gt;The goal was simple: create a Trade App for the &lt;a href="https://www.nocks.com/"&gt;Nocks&lt;/a&gt; cryptocurrency platform using there publicly available &lt;strong&gt;REST API&lt;/strong&gt;. The App will have to become available on both &lt;strong&gt;iOS&lt;/strong&gt; as on &lt;strong&gt;Android&lt;/strong&gt; and the features it should have are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication (with Nocks &lt;strong&gt;OAuth&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;App (un)lock with PIN, &lt;strong&gt;TouchID&lt;/strong&gt; or &lt;strong&gt;FaceID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;View available assets&lt;/li&gt;
&lt;li&gt;Make deposits&lt;/li&gt;
&lt;li&gt;Make withdrawals&lt;/li&gt;
&lt;li&gt;View history of trades and transactions&lt;/li&gt;
&lt;li&gt;Overview of markets&lt;/li&gt;
&lt;li&gt;Per market:

&lt;ul&gt;
&lt;li&gt;View open orders&lt;/li&gt;
&lt;li&gt;Cancel open orders&lt;/li&gt;
&lt;li&gt;Place a new order&lt;/li&gt;
&lt;li&gt;View history (list and graph view)&lt;/li&gt;
&lt;li&gt;View order book (list and graph view)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Various notifications&lt;/li&gt;
&lt;li&gt;Various settings (night mode, language etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So with such a list of features, where do you start?&lt;/p&gt;

&lt;h1&gt;
  
  
  Approach
&lt;/h1&gt;

&lt;p&gt;The first thing I did was creating &lt;strong&gt;user stories&lt;/strong&gt; out of the features list. Doing this gave me a better idea of what the &lt;strong&gt;expectations&lt;/strong&gt; were for the &lt;strong&gt;client&lt;/strong&gt; and for the &lt;strong&gt;end users&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With these user stories in place the plan was to use an &lt;strong&gt;agile-like&lt;/strong&gt; approach. Of course with some tweaks because of the small "team" that was involved in the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client:&lt;/strong&gt; The man with all the ideas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Owner:&lt;/strong&gt; Point of contact for me as the developer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer:&lt;/strong&gt; Me, the guy who had to make the product real&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;So how was this "agile" approach working?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every week I discussed my work with the product owner. I showed him the progress that I made and the user stories that were &lt;strong&gt;ready to test&lt;/strong&gt;. Together we tested these user stories and checked if these could be &lt;strong&gt;considered as done&lt;/strong&gt;. After that we discussed about the user stories that could be &lt;strong&gt;picked up next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By working this way, the product owner and the client were always well &lt;strong&gt;informed&lt;/strong&gt; about the state of the development process. And also for me it was very useful to retrieve &lt;strong&gt;quick feedback&lt;/strong&gt; on my work.&lt;/p&gt;

&lt;h1&gt;
  
  
  Stack
&lt;/h1&gt;

&lt;p&gt;As I mentioned before, I didn't have a lot of experience in App development. I only had experience with creating a small App with &lt;strong&gt;React Native and Expo&lt;/strong&gt;. Although this was just a small project, the impression I got with these frameworks was very positive. And because there was no real reason to not use them, I chose to go with it.&lt;/p&gt;

&lt;p&gt;Looking back, I think that was the right choice. I experienced Expo as a great tool with some great advantages which can really &lt;strong&gt;speed up&lt;/strong&gt; your development process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great documentation and community&lt;/li&gt;
&lt;li&gt;Easy to use build services&lt;/li&gt;
&lt;li&gt;Over-the-air updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However there were also some small issues I came across while using Expo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I wanted to use a library which depended on a later version of React Native than Expo supported. Because of that I needed to create a workaround and wait until the next Expo release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expo includes some libraries out of the box. One of them caused a deprecation warning when publishing to the App Store. It was only a warning... but it does not feel good that you have no control over it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end these two issues were not a big problem for the App. And if it was: there is always a possibility to &lt;strong&gt;eject&lt;/strong&gt; from Expo and go back to React Native only. Looking at the documentation, ejecting doesn't seem to be very difficult either, but you'd rather not do it if you don't have to. And I didn't have to 😄&lt;/p&gt;

&lt;h1&gt;
  
  
  Beta testing
&lt;/h1&gt;

&lt;p&gt;After about 3 months the &lt;strong&gt;MVP&lt;/strong&gt; was ready. It didn't yet have all the features, but it was &lt;strong&gt;usable&lt;/strong&gt; and had &lt;strong&gt;added value&lt;/strong&gt; for the end users. So it was ready to be tested by some "real" end users. First only for iOS with &lt;strong&gt;Testflight&lt;/strong&gt; and later on also for Android with &lt;strong&gt;Google Play beta testing&lt;/strong&gt;. The goals for this beta testing phase were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve feedback for the App in general

&lt;ul&gt;
&lt;li&gt;Looks, feeling, intuitivity etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check the stability of the App

&lt;ul&gt;
&lt;li&gt;We used &lt;strong&gt;Sentry&lt;/strong&gt; to track unexpected errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Continue with developing the remaining features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;over-the-air&lt;/strong&gt; updates that Expo &lt;strong&gt;out of the box supports&lt;/strong&gt; came in very handy during this phase. With that I could just push fixes without having to create new versions in the stores. And the testers didn't have to download a new version each time. This makes &lt;strong&gt;verifying fixes&lt;/strong&gt; with testers very &lt;strong&gt;easy&lt;/strong&gt; and &lt;strong&gt;fast&lt;/strong&gt;. Also with the new features that I developed during this phase I could often make use of these &lt;strong&gt;over-the-air&lt;/strong&gt; updates.&lt;/p&gt;

&lt;p&gt;After about 1,5 month of beta testing we could consider the app as stable and it was ready with all the requested features: &lt;strong&gt;time to publish!&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Result
&lt;/h1&gt;

&lt;p&gt;I must say that I'm very proud of the result. After the App went live there were only some minor issues and each of them could be fixed pretty fast. And yet again the &lt;strong&gt;over-the-air&lt;/strong&gt; updates came in very handy with this.&lt;/p&gt;

&lt;p&gt;If you get started with such a project where you are the only developer and you are working with frameworks you have not much experience with, it can be &lt;strong&gt;quite scary&lt;/strong&gt; at the beginning. And you will sometimes wonder if you are able to complete the job. But if you do manage to finish the job, you will eventually &lt;strong&gt;learn&lt;/strong&gt; a lot from it and it will give you a lot of &lt;strong&gt;satisfaction&lt;/strong&gt;. Especially if the client and the end users are very positive about the product you made. So sometimes you just need to &lt;strong&gt;accept the challenge and go for it!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Curious about the App?
&lt;/h2&gt;

&lt;p&gt;Here are some screenshots to give you an idea: &lt;/p&gt;

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

&lt;p&gt;And of course if you are interested in downloading the App. It's available in &lt;a href="https://apps.apple.com/us/app/nocks-trade/id1482094724"&gt;the App Store&lt;/a&gt; and in &lt;a href="https://play.google.com/store/apps/details?id=com.nocks.trade"&gt;the Google Play Store&lt;/a&gt; 😊&lt;/p&gt;

&lt;h1&gt;
  
  
  You want to create your fist App?
&lt;/h1&gt;

&lt;p&gt;React Native (with or without Expo), Flutter, Ionic or just going fully native, there are so &lt;strong&gt;much possibilities&lt;/strong&gt; and I only used one of them... So I can't possibly make a comparison or give any advice. The only thing I can say is that I really liked React Native + Expo. But whatever framework you choose: &lt;strong&gt;just get started!&lt;/strong&gt; Because app development is just &lt;strong&gt;a lot of fun&lt;/strong&gt; and you will probably &lt;strong&gt;learn&lt;/strong&gt; a lot from it.&lt;/p&gt;

&lt;p&gt;And if you choose Expo (great choice 😉) here are some helpful links:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.expo.io/versions/latest/"&gt;Expo documentation&lt;/a&gt; clear &lt;strong&gt;documentation&lt;/strong&gt; and useful &lt;strong&gt;tutorial&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://forums.expo.io/"&gt;Expo forum&lt;/a&gt; very helpful &lt;strong&gt;community&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And if you have any questions, don't hesitate to leave a comment 😄&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheers&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>expo</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>RamdaJS: Using it for the first time </title>
      <dc:creator>Robbie</dc:creator>
      <pubDate>Thu, 19 Mar 2020 07:39:00 +0000</pubDate>
      <link>https://dev.to/rodw1995/first-time-using-ramda-521p</link>
      <guid>https://dev.to/rodw1995/first-time-using-ramda-521p</guid>
      <description>&lt;p&gt;&lt;a href="https://ramdajs.com/"&gt;Ramda&lt;/a&gt; is a JavaScript library that I know for a while but have never used before. Now that I want to use it in my projects, I will write about my experiences with it in some blog posts. And in this article I will describe my first experience with the library. But first things first:&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Ramda
&lt;/h1&gt;

&lt;p&gt;Ramda describes itself as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A practical &lt;strong&gt;functional&lt;/strong&gt; library for JavaScript programmers.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well that covers already a lot I think. It’s a toolset like the popular &lt;a href="https://lodash.com/"&gt;lodash&lt;/a&gt; but in a more functional style:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It embraces &lt;strong&gt;immutable data&lt;/strong&gt; and &lt;strong&gt;pure functions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;All functions are &lt;strong&gt;curried&lt;/strong&gt; automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it’s especially useful if you want to do functional programming in JavaScript (or TypeScript).&lt;/p&gt;

&lt;h1&gt;
  
  
  Using Ramda for the first time
&lt;/h1&gt;

&lt;p&gt;Ramda was one of those libraries on my list to check out. So I included it in a React project where my main goal was to play with some new tools (I plan to write some blogs about this “test” project as well). The Ramda functions I used the most during this project were:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ramdajs.com/docs/#pipe"&gt;pipe&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I think it's clear what the &lt;strong&gt;pipe&lt;/strong&gt; function does for everyone that is into functional programming: it performs &lt;strong&gt;left-to-right function composition&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNotEmpty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course Ramda also has a &lt;strong&gt;compose&lt;/strong&gt; function which does the &lt;strong&gt;right-to-left function composition&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNotEmpty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two functions are simply indispensable in a library that describes itself as functional.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ramdajs.com/docs/#cond"&gt;cond&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;You can use the &lt;strong&gt;cond&lt;/strong&gt; function as an alternative for &lt;strong&gt;if-else&lt;/strong&gt; constructions. In my test project I used it to create a function that will call the correct error handler based on the given error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function to check if an error has a certain code&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasErrorCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allPass&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;isPlainObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propEq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Condition statement which will call the correct error handler&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;hasErrorCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NotAuthorizedException&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;code&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;// Handle "NotAuthorizedException"&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;hasErrorCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserNotFoundException&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;code&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;// Handle "UserNotFoundException"&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Functions that always returns true&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;// Error handler fallback&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;// Call error handler&lt;/span&gt;
&lt;span class="nx"&gt;errorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks pretty clean, right? Imagine writing this with &lt;strong&gt;if-else&lt;/strong&gt; statements...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ramdajs.com/docs/#tryCatch"&gt;tryCatch&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;If you don't like to have &lt;strong&gt;try... catch...&lt;/strong&gt; statements in your code like me than this function will really help you. It's more of a wrapper around try catch statements which accepts two functions: a &lt;strong&gt;tryer&lt;/strong&gt; and a &lt;strong&gt;catcher&lt;/strong&gt;. When the tryer &lt;em&gt;does not&lt;/em&gt; throw an error the result of the tryer will be returned. On the other hand, if the tryer &lt;em&gt;does&lt;/em&gt; throw an error the catcher will be called and it's result will be returned. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In plain JavaScript you will have something like this&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Ugh, we must use let here&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mayThrowAnError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In Ramda with tryCatch you can do this&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tryCatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mayThrowAnError&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;always&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my opinion much cleaner and you don't have to use &lt;em&gt;let&lt;/em&gt; 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://ramdajs.com/docs/#propEq"&gt;propEq&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A simple function that checks if a property of an object is equal to the given value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Find a person where name = "Robbie"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propEq&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="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Robbie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And yes, this can also be easily done in plain JavaScript too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Find a person where name = "Robbie"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Robbie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The question is: what is more readable? I guess you can discuss that.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Ramda offers a lot of helpful functions for &lt;strong&gt;functional programming&lt;/strong&gt; and &lt;strong&gt;function composition&lt;/strong&gt;. It helps (not enforce) you to write functions without &lt;strong&gt;side-effects&lt;/strong&gt; (pure) and use &lt;strong&gt;immutable data&lt;/strong&gt;. So if you think these concepts are important in good code (you should, in my opinion) it’s definitely a library to check out. It has great power, but….&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don’t over use it.&lt;/strong&gt; Sometimes just plain JavaScript is better or clearer. A good software developer always keeps the &lt;strong&gt;readability of code&lt;/strong&gt; in mind. Maybe you can write the most complex things with Ramda but you should always ask yourself: &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Will it be easy for my colleague to &lt;strong&gt;read&lt;/strong&gt; this code and &lt;strong&gt;understand&lt;/strong&gt; directly what’s happening? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, you can debate about what is more readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A function that accepts a string and checks if it's not in an array&lt;/span&gt;

&lt;span class="c1"&gt;// Using Ramda&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notInArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Using plain JavaScript&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notInArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It’s big and has a lot of functions.&lt;/strong&gt; It will take some time to familiarize yourself with all of them. I probably have missed a lot of powerful functions I could use in my first project. However you will also notice, when you start using Ramda, that you will &lt;strong&gt;instinctively&lt;/strong&gt; think: &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Uhm there is probably a Ramda function for this.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To learn all the possibilities you should just include it in your project and you will learn it along the way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript and Ramda….&lt;/strong&gt; First of all I must note that I’m not the biggest TypeScript expert so that has to do with it too. But in my first project I had some problems with &lt;strong&gt;return types&lt;/strong&gt; that where incorrectly or not automatically set. Which is a pain because you know the function works but the compiler is complaining. An example of a problem that I had with TypeScript and Ramda:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This will cause an error&lt;/span&gt;
&lt;span class="k"&gt;return&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NonNullable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propEq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&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="c1"&gt;// TypeScript error: No overload matches this call.&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Turns out you have to tell the reject function that it's dealing with an array&lt;/span&gt;
&lt;span class="k"&gt;return&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NonNullable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&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;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propEq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&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="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All problems with TypeScript and Ramda seems "fixable", so again this may be more of an issue related to my TypeScript knowledge than related to Ramda itself.&lt;/p&gt;

&lt;h1&gt;
  
  
  More about Ramda
&lt;/h1&gt;

&lt;p&gt;Ramda is a very popular library and so there is enough to read about it. An overview of some great articles can be found &lt;a href="https://github.com/ramda/ramda/wiki"&gt;here&lt;/a&gt; or check out the &lt;a href="https://ramdajs.com/docs/"&gt;documentation&lt;/a&gt; right away and &lt;a href="https://ramdajs.com/repl/?v=0.27.0"&gt;try it out&lt;/a&gt;!&lt;/p&gt;

&lt;h1&gt;
  
  
  Something else…
&lt;/h1&gt;

&lt;p&gt;This is my first post on dev.to. I hope someone is going to read it and it would be awesome if it’s in some way useful to someone. In the future I want to write more posts and they will probably go about JavaScript and related frameworks/libraries. If you have any questions about this post or Ramda in general, please let me know. And of course, I would also like to hear if you have any tips for me about Ramda or about writing posts on dev.to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheers&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ramda</category>
      <category>functional</category>
      <category>firstpost</category>
    </item>
  </channel>
</rss>
