<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nishchal Gautam</title>
    <description>The latest articles on Forem by Nishchal Gautam (@cyberhck).</description>
    <link>https://forem.com/cyberhck</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%2F179313%2F728e1e35-dd16-43ee-90b3-bb9300fbcba6.jpeg</url>
      <title>Forem: Nishchal Gautam</title>
      <link>https://forem.com/cyberhck</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cyberhck"/>
    <language>en</language>
    <item>
      <title>Here's how I use JWT, maybe you should too</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Tue, 26 Jan 2021 16:30:11 +0000</pubDate>
      <link>https://forem.com/cyberhck/here-s-how-i-use-jwt-maybe-you-should-too-47l5</link>
      <guid>https://forem.com/cyberhck/here-s-how-i-use-jwt-maybe-you-should-too-47l5</guid>
      <description>&lt;p&gt;I'm sure you've seen a lot of articles suggesting to use JWT, and some people who haven't done enough of JWT to say don't use JWT (or maybe some who gave it a try for 5 mins, and thought no, JWT is for noobs)&lt;/p&gt;

&lt;p&gt;I'm going to write about how I'm using JWT and while it does feel foolproof, it obviously isn't, (every app has vulnerabilities)&lt;/p&gt;

&lt;p&gt;Okay, first things first, I'm going to assume you know what is JWT and how to validate, I don't want to go through what JWT is, every article even remotely touching about JWT will explain what it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use asymmetric key
&lt;/h2&gt;

&lt;p&gt;Using symmetric key complicates things, it requires you to share this key with other services if they also need to validate JWT.&lt;/p&gt;

&lt;p&gt;Asymmetric key can simply expose it's public key to public storage (even S3).&lt;/p&gt;

&lt;h2&gt;
  
  
  Rotate your key pair and never transmit private key
&lt;/h2&gt;

&lt;p&gt;When an application starts, it starts a background job which will create a keypair and store public key in public storage, and private key in it's own secure memory (not even in secondary memory, private key should only be stored in RAM)&lt;/p&gt;

&lt;p&gt;Which might beg the question, how do we scale?&lt;/p&gt;

&lt;p&gt;Actually, this is more scalable, say you're auto scaling, every time one instance of your identity service starts, it'll simply generate a key pair.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use &lt;code&gt;kid&lt;/code&gt; field to validate JWTs.
&lt;/h2&gt;

&lt;p&gt;When signing any JWT, use the current private key to sign and include &lt;code&gt;kid&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;Now at any given time, there might be N number of valid private/public key (N = number of instances of your identity service running), this will increase with scale.&lt;/p&gt;

&lt;p&gt;Now since you have the kid, you can fetch the public key for that particular kid and simply validate it. (And of course you can cache it)&lt;/p&gt;

&lt;p&gt;By this time, you've done it, you've a scalable JWT based auth server, it rotates keys at given interval, and there's no way for a human to get access to key because it's in RAM (if a hacker gets access to server and somehow looks at RAM, I guess that is still vulnerable, but then we have more things to worry about, I guess we could make it harder, if you have some idea, please comment below)&lt;/p&gt;

&lt;h1&gt;
  
  
  Logging out
&lt;/h1&gt;

&lt;p&gt;Every time I talk about JWT with a group of people, there's always a question of logging out.&lt;/p&gt;

&lt;p&gt;First off, setting a lower value of expiry is good idea, as short as 15 minutes is a very good point for security already. But we can do better.&lt;/p&gt;

&lt;p&gt;I have two approaches, first is simply store the JWTs created by refresh tokens in db, and you can blacklist them when users log out, but this means you're storing a lot of tokens in your db. You can use &lt;code&gt;jti&lt;/code&gt; claim for this.&lt;/p&gt;

&lt;p&gt;What I actually like is having a secondary value in JWT &lt;code&gt;rid&lt;/code&gt; this is not a standard claim, but idea is to store which refresh token actually generated this jwt, that way when refresh token is revoked, we simply put this on blacklist for a particular amount of time (once all jwts expire from this refresh token, say in 15 mins, we can clean this blacklist up)&lt;/p&gt;

&lt;h1&gt;
  
  
  Here's what we have at last
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;We're using a auth in a way that other services are able to easily verify if jwt is valid&lt;/li&gt;
&lt;li&gt;key pairs are rotated every N minutes (I do few hours)&lt;/li&gt;
&lt;li&gt;private key never leaves RAM so it's more difficult to generate fraudulent JWTs.&lt;/li&gt;
&lt;li&gt;Logging out can be done using a blacklisting mechanism (pub/sub could be a game changer)&lt;/li&gt;
&lt;li&gt;if your auth server needs to scale, it can do so, and private key doesn't need to be sent to other 9 instances, because there's nothing wrong with having 10 valid key pairs at the same time.&lt;/li&gt;
&lt;li&gt;This is super scalable, say you have bunch of servers across the world, and you could in theory have 10 identity service on each region of the world, let's say 50 identity service running at any time. Even in this case, because you can simply fetch public key using kid, there's no issue, you can easily scale this.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jwt</category>
      <category>authentication</category>
    </item>
    <item>
      <title>My home internet setup</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Mon, 16 Nov 2020 03:22:57 +0000</pubDate>
      <link>https://forem.com/cyberhck/my-home-internet-setup-50md</link>
      <guid>https://forem.com/cyberhck/my-home-internet-setup-50md</guid>
      <description>&lt;p&gt;So I've been in Thailand for almost about 5 years now and I must say I really enjoy it.&lt;/p&gt;

&lt;p&gt;Whenever I'm planning on a move from one home to other I always plan the internet first, the day we move I set an appointment with my ISP and I do this well in advance so that I never have to use my phone's data. But that's not the thing I want to talk about here.&lt;/p&gt;

&lt;p&gt;My setup currently consists a router with modem built in which was provided by ISP directly, it's a decent router with 2 access points, one with 2.4 Ghz and one with 5 Ghz both have separate passwords, I use 5 Ghz but when I'm out of range I'm still able to use 2.4 (in case I'm out in the garden)&lt;/p&gt;

&lt;p&gt;What I did a while back is setup pihole in my raspberrypi which was sitting around doing nonsense IoT project I did before.&lt;/p&gt;

&lt;p&gt;Instead of pointing DNS to my rpi from each devices and having to tell guests that they can use my DNS instead of ISP dns (some people would ask what a DNS was, and that's a different conversation), I rather changed my router settings so that the settings which router provides all devices already contains my pihole dns.&lt;/p&gt;

&lt;p&gt;This means, any device connecting to my WiFi automatically uses my DNS provider, here I can block websites, but I've done adblocking, this helped me a bunch because phones or smart TVs don't have adblocking capability that I know of. I don't do certain website blocking but I can if I wanted to.&lt;/p&gt;

&lt;p&gt;Now because I'm using my own DNS, and Thailand's ISP does a dns filtering blocking of websites (sites that are banned in thailand), those still work! Without the use of VPN, and when the guests come they're surprised and ask if I have built-in VPN on router, I say no (they can check whatismyip and get info)&lt;/p&gt;

&lt;p&gt;I didn't realize having your own DNS is awesome, but it totally is, and I recommend you doing the same SPECIALLY if your country does DNS blocking.&lt;/p&gt;

</description>
      <category>pihole</category>
      <category>raspberrypi</category>
      <category>dns</category>
      <category>censorship</category>
    </item>
    <item>
      <title>OS wars let's settle this right now</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Thu, 05 Nov 2020 03:02:16 +0000</pubDate>
      <link>https://forem.com/cyberhck/os-wars-let-s-settle-this-right-now-afa</link>
      <guid>https://forem.com/cyberhck/os-wars-let-s-settle-this-right-now-afa</guid>
      <description>&lt;p&gt;Let me re-ignite this flame one last time, but trust me, I'm sure you'll like what I have to say.&lt;/p&gt;

&lt;p&gt;In past 5 years, I have been in 3 companies, in first company, they only asked me what hardware I want and what were the specs. I could choose literally any hardware I'd want. When I joined I saw majority of people were on windows, one guy was on mac and me being on Manjaro at first and Ubuntu when I crashed Manjaro. There the code we wrote was cross compatible, when any of us found compatibility issue, we fixed it.&lt;/p&gt;

&lt;p&gt;On my next company I was locked down to windows but I was given a separate laptop after manager's approval which had linux mint on it, but most of the project under this company was in legacy .NET framework which meant working a lot with windows hardware.&lt;/p&gt;

&lt;p&gt;My current company, everyone is locked down to a MAC even though all projects are in golang or elixir. There's no manager's approval to get other hardware. It's a company policy to give everyone a macbook pro regardless of developer wanting it.&lt;/p&gt;

&lt;p&gt;My philosophy is that tools should work for me, I shouldn't work around the tools, there are small things I like to do, the virtual workspaces on linux, the guake terminal, all of these tiny things make me so much productive, now being locked to mac is making me working AROUND the mac instead of making IT work for me.&lt;/p&gt;

&lt;p&gt;Now I'm not bashing on mac, if mac does what you want it to do, great. I guess what I'm saying is choose an OS which you're comfortable with, don't jump on the hype train, just because all the nerds are using gentoo or arch doesn't mean you've to do the same, if you're comfortable with windows, good for you!&lt;/p&gt;

&lt;p&gt;Make your tools work FOR you, don't work around the tools, use what you're comfortable with. For me, workspace is a must, guake terminal is a game changer, and small tiny things I can't even remember to write it down, doesn't work on windows nor mac.&lt;/p&gt;

&lt;p&gt;Now I know someone will say, "But windows has virtual workspace", yeah, but is it as good as what I have? Say I'm on my primary workspace where I write code. I want to listen to music so I open Spotify, but I realize Spotify doesn't belong in primary, so I can press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Alt&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;DownArrow&lt;/code&gt; which moves my Spotify to music workspace, (I use 2x2 workspaces), there's no shortcut for that, windows has only horizontal workspace and no 2d Grid, don't get me started with mac, just to switch workspace, you need to use mouse. The support for external keyboard is non existent.&lt;/p&gt;

&lt;p&gt;So for the last time: Let people use what they want to use. If they're building a iOS app, they'll ASK for mac, if they're building windows app, they'll ASK for windows, if that's not the case, there's no point locking people down to what YOU think is better for them, they know what's good for them.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>macos</category>
      <category>windows</category>
    </item>
    <item>
      <title>Let's talk about how React is only a view layer</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Sun, 26 Jul 2020 05:08:00 +0000</pubDate>
      <link>https://forem.com/cyberhck/let-s-talk-about-how-react-is-only-a-view-layer-5gg1</link>
      <guid>https://forem.com/cyberhck/let-s-talk-about-how-react-is-only-a-view-layer-5gg1</guid>
      <description>&lt;p&gt;Hello everyone,&lt;br&gt;
This is a mix between discussion and a post, if you don't agree with me, I hope you write a comment and hopefully change my mind as long the point changes my views. I have recently done &lt;a href="https://github.com/fossapps/Feature.Manager"&gt;https://github.com/fossapps/Feature.Manager&lt;/a&gt; project, and I need a UI, I don't need UI to be fancy or production ready, I want it to be simple, and when I do decide to change I should still be able to make it production ready.&lt;/p&gt;
&lt;h2&gt;
  
  
  Fetching from API
&lt;/h2&gt;

&lt;p&gt;To fetch a data from API, I don't expect people to write &lt;code&gt;fetch&lt;/code&gt; calls, they shouldn't be going to documentation and trying to find out how to make the call, what is the url, what parameter is going to be used etc. That's just a implementation detail which no one cares for, I want developers to invest time in actually building a product rather than stare at a API documentation, in the interest of saving developer's time, I always prepare/generate a API client.&lt;/p&gt;

&lt;p&gt;I generally use swagger to document my API, and I generate clients for most of the language, however for typescript, I use &lt;code&gt;@crazyfactory/tinka&lt;/code&gt;, this supports middleware, mocking, testing, caching etc, I haven't found anything which makes api calls better than this.&lt;/p&gt;

&lt;p&gt;When I do need to make an API call, here's what I do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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;isError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something&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;}&lt;/span&gt;
&lt;span class="c1"&gt;// use the actual response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And because everything is in typescript, I get full typescript features everywhere.&lt;/p&gt;

&lt;p&gt;Now consumer of Sdk, never has to look at API documentation, just use your IDE, which shows what you need.&lt;/p&gt;

&lt;p&gt;Normally for a large project where I want to ensure it's a very solid project, I create a separate package and use &lt;code&gt;semantic-release&lt;/code&gt; to create releases automatically with proper semantic versioning, if you don't know what this is, have a look at semantic-release project.&lt;/p&gt;

&lt;p&gt;But in my case, I just created a directory called Sdk and wrote everything there. Here's a PR which introduced it: &lt;a href="https://github.com/fossapps/Feature.Manager.Ui/pull/27"&gt;https://github.com/fossapps/Feature.Manager.Ui/pull/27&lt;/a&gt;&lt;br&gt;
If you follow that PR you'll notice that I'm using the tinka package, and adding Sdk methods, and because everything's typed, consumer of this Sdk, (which is this project itself), will never have to worry about what method it's using, what URL it's hitting etc. Now obviously I could generate a client using autorest, but I couldn't find a generator which supported middlewares (I'll need middleware support).&lt;/p&gt;
&lt;h2&gt;
  
  
  Storing data (React is a View layer, don't fetch / store data in a view layer)
&lt;/h2&gt;

&lt;p&gt;Now that fetching data is out of the way, let's talk about storing data.&lt;/p&gt;

&lt;p&gt;I treat React as a view library, even though they're planning on introducing API calls with suspense soon.&lt;/p&gt;

&lt;p&gt;One thing I really hate when I review someone's code, they simply go to &lt;code&gt;componentDidMount&lt;/code&gt; (or &lt;code&gt;useEffect&lt;/code&gt;), and make a api call, or they have hooks which makes the API call and put it on state.&lt;/p&gt;

&lt;p&gt;IMO, this is a NO-NO, why would you access data from your view layer, have you ever queried a database from your view layer in any other MVC frameworks? Should you?&lt;/p&gt;

&lt;p&gt;For that reason I've a different layer, I call it side effect layer, I use redux-saga for managing side effects this let's me keep my view and logic completely separate, in theory, if someone decided that I needed to ditch react for something else, in this situation I technically can, because again, React is just a view layer.&lt;/p&gt;

&lt;p&gt;I keep data on redux and if say some day I happen to say I don't want to redux for data storage and want to move to mobx, I still can. They're not glued together.&lt;/p&gt;

&lt;p&gt;Here's how I do this:&lt;br&gt;
I've a page which needs data from API call, on it's componentDidMount (or useEffect, I'll come to this later), I check if I already have data available on store, if I do, then I don't do anything.&lt;/p&gt;

&lt;p&gt;But if I don't have any data on store, then my componentDidMount will dispatch a action &lt;code&gt;SOME_DOMAIN/FETCH_DATA&lt;/code&gt; (or something similar), it dispatches this, and my side effect layer notices this (redux saga has ability to listen to actions and call a method when it happens) on that call, I call API using the Sdk I mentioned before, and set the data on redux.&lt;/p&gt;

&lt;p&gt;There's a side effect to this, how many times have you tried to do setState on a unmounted component? Say user goes to a page and immediately navigates away from that component, then you get a warning from react saying that's wrong, also you now can't re-use that data anymore, when user comes to the component, you make the api call again.&lt;/p&gt;

&lt;p&gt;Because redux and redux-saga are different layers, that problem is not there anymore (and you can test your redux, redux-saga and your component separately, and writing tests are easier).&lt;/p&gt;

&lt;p&gt;If you had done a fetch call inside a component, you'll end up with one messy component, and a very dreadful set of tests (worst if you decide to test after the code is done)&lt;/p&gt;

&lt;p&gt;So I don't think you should keep data on your view layer, I also don't think you should make any calls from your view layer and I certainly don't think you should mix all of them on same layer.&lt;/p&gt;

&lt;p&gt;The PRs I linked to, and the project I've linked to, neither of them is a gold standard, I know that, had I enough time, and had this project needed to be that way, I certainly would have spent a bit more time to separate Sdk into whole another npm package, same thing with components, I could have used a higher order component to give the color values and made the whole thing themeable, but that's not for today.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's talk about redux hooks
&lt;/h2&gt;

&lt;p&gt;I've seen people jumping on this hooks' train left and right, let's talk about redux hooks first.&lt;/p&gt;

&lt;p&gt;When you &lt;code&gt;useSelector&lt;/code&gt; on your component, you basically glue your component to redux, view layer and data layer is very tightly coupled, and that's not what you want in a production ready app, I personally don't even want it on a throw away app, is calling connect function really that difficult?&lt;/p&gt;

&lt;p&gt;And I've heard this argument before, "How about we create a Wrapper component which calls the useSelector and passes them down to components which needs them", to that I say you just implemented &lt;code&gt;connect&lt;/code&gt; component, it's basically the same, except you'll want to do it for every component, if not, it's just another &lt;code&gt;connect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And with redux hooks, now you have to mock your redux store, which is a whole other story.&lt;/p&gt;

&lt;p&gt;Remember, you really don't want to glue your view and data layer. I keep the concerns separate, and when you do use redux hooks your component violates a lot of SOLID principles.&lt;/p&gt;

&lt;p&gt;It certainly violates single responsibility principle, because it's now communicating with your redux layer,&lt;/p&gt;

&lt;p&gt;It also violates open for extension and closed for modification principle, Now that you've used redux hooks, you can't extend it in anyway, you're actually tied to redux layer, and that's it. Take these two component for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&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;IThemeProp&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;props&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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Alert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AlertWithHook&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="nx"&gt;props&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;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above examples are just simple react hooks, but let's take them as an example,&lt;/p&gt;

&lt;p&gt;The first component which doesn't use hooks, can be extended easily, you can just use the component without the theme, and personalize it.&lt;/p&gt;

&lt;p&gt;The second component however, is already tied with a certain context, and there's nothing you can do to change the second component with hook.&lt;/p&gt;

&lt;p&gt;Another thing, the first component is a pure component (without the higher order component), for same input, it always returns same output, but the second one with hooks, isn't a pure component, it actually depends on what hook returns, which is a side effect, I generally tend not to go that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance and functional vs classes
&lt;/h2&gt;

&lt;p&gt;First off, I always prefer functional components for smaller components, if a component is getting big, probably time to break them down to smaller components.&lt;/p&gt;

&lt;p&gt;Facebook also says, don't go and change your existing class components and change to functional, there's no need for that, (but people being people, have started rewriting libraries), I'm not doing that.&lt;/p&gt;

&lt;p&gt;Another thing is people say with hooks, you get performance boost. I don't think that's the case, let me tell you why.&lt;/p&gt;

&lt;p&gt;I think the hooks create another side effect which is all your components are functional, and functions are faster than classes, the performance boost isn't coming from hooks, but the fact that you have functional components.&lt;/p&gt;

&lt;p&gt;What I prefer is to have smaller functional components, and when it comes to larger components which &lt;em&gt;might&lt;/em&gt; have logic, or needs multiple handlers, I tend to have them as a separate method, after all, I can actually do OOO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussions welcome
&lt;/h2&gt;

&lt;p&gt;I'm sure I might have missed some points, and there are so many things I wanted to communicate, but don't have the time to write about and don't want to extend the post too long.&lt;/p&gt;

&lt;p&gt;Please raise your concerns in a way we can talk about, and if you don't agree, let me know why you don't agree, if you do, can you elaborate why you feel that way? I feel like there are some things my instincts tell me are dirty, but I can't actually explain them.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>redux</category>
    </item>
    <item>
      <title>Freelancing at it's best</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Thu, 05 Mar 2020 14:02:27 +0000</pubDate>
      <link>https://forem.com/cyberhck/freelancing-at-it-s-best-4f6k</link>
      <guid>https://forem.com/cyberhck/freelancing-at-it-s-best-4f6k</guid>
      <description>&lt;p&gt;I feel like I do really well when it comes to freelancing, not that I do it that often, but the way I do it however makes a lot of sense for me.&lt;/p&gt;

&lt;p&gt;I believe it'll make a lot of sense for anyone who is not only doing freelancing but also a potential client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality of Product
&lt;/h2&gt;

&lt;p&gt;Now a days when I build an application I make sure there's enough visibility. I send measurement data for each tasks, every edge case handled, every time user sends bad data, or wrong username/password combination, expired JWT etc, and I create a dashboard on Grafana which nicely shows this data in real time. I always have health-checks setup correctly, and make sure important things from Grafana actually have alerts.&lt;/p&gt;

&lt;p&gt;Let's look at my auth service as an example, It implements JWT and uses private/public key JWT signing, which means public key can be used in my rest of services to verify, not only that, the key pairs are constantly rotated and private key never even enters a storage device like SSD or HDD, (unless OS decided to do a SWAP).&lt;/p&gt;

&lt;h2&gt;
  
  
  Working while not being paid
&lt;/h2&gt;

&lt;p&gt;I work on some apps even when I don't have a client, specially when I don't have a client, I work on things that I think will have more consumers, and when clients do come in, I simply do a &lt;code&gt;docker pull service&lt;/code&gt; and start working on front-end so that I can deliver a good product and really fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Even
&lt;/h2&gt;

&lt;p&gt;Almost 99% of the clients need some sort of authentication, having my auth service ready to pull from docker hub helps a great deal.&lt;/p&gt;

&lt;p&gt;I might have worked about 150 hours making this production ready, but I charge clients for 30 hours, this way I get paid for some part of my work, client is happy because he got production ready software with 1/5th the cost, in literally few minutes and I'm obviously happy because I just need 4 more clients to break even, after which I'm making money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being Transparent
&lt;/h2&gt;

&lt;p&gt;Obviously when you communicate with the client when you send your proposal, if you decide not to tell that you're pulling the service so you can charge them extra is just being an ass. Most of the people appreciate honesty, You can make a agreement in advance, and if the client would NOT pay for reusable service, maybe it's good if you just find a new client, Or if it's for some other issues, there's always an option to re-write the auth service maybe, I have never came across this situation so I don't know what's the right thing to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing expectations
&lt;/h2&gt;

&lt;p&gt;One thing which I learnt after I included auth service for the first time, despite having made clear, client missed the fact that I didn't actually have to do anything, just the front-end, but after you're done with all the components you have for pulling, then you still need to write code for the rest of the stuff, in my case my client was expecting me to deliver in the same pace in what I delivered before, which won't work of course, because remaining part of the project would have to be written from scratch, and they'll cost significantly higher as I'm not reusing a service, rather writing from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Effects of this system
&lt;/h2&gt;

&lt;p&gt;I always work hourly or with deliverable with milestones, when I make a proposal, I make abundantly clear to the client that we're gonna be pulling the service directly, and implementing a basic authentication system for front-end, almost no UI work, just basic forms. Once this is done, client is expected to pay some amount of money. This helps weed-out those non paying clients, or those who abandon the project or those who aren't serious about project. This means, even if you got a really bad client, you would have lost maybe 2-3 hours of work, and in my case not even that as I've already setup front-end demo project as well, I work 30 mins to make sure client is actually okay and won't dump the project when he has to pay, in client's perspective, project's one milestone was still delivered even though I didn't have to work on it.&lt;/p&gt;

&lt;p&gt;Another thing I do is if I work hourly, I always send them an invoice after which I don't work on the project until client deals with the invoice and pays. That way in case something happens, you loose only the last invoice, at least not as bad as not having paid for anything when the project is over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saying No
&lt;/h2&gt;

&lt;p&gt;Every once in a while, I find some people saying, since you've already worked on it, and why not just let them get it for free and charge my future clients, or once one client even said, I'm not gonna pay for it, you might as well include it for free as I'd not get the contract if I wouldn't agree.&lt;/p&gt;

&lt;p&gt;For all these kinds of clients, I simply say No, I'd rather not work on their project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Good Will
&lt;/h2&gt;

&lt;p&gt;Sometimes you'll face that you do have a project, but you haven't actually tested it on production, you aren't sure how well it performs, OR sometimes you're building a project and you realize that you can use it later, in these cases I find myself in a good case of building good will.&lt;/p&gt;

&lt;p&gt;The idea is simple, you simply tell your client that you will give it for 1/10th of the price instead of 1/5 because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you haven't tested this on production and them using it would help verify&lt;/li&gt;
&lt;li&gt;they have been a really good client and you want to offer them a one time discount&lt;/li&gt;
&lt;li&gt;OR WHEN they're making you build something you know you'll need later, in that case, you're better having them pay 1/10th and keep your service for yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Managing your own expectations
&lt;/h2&gt;

&lt;p&gt;Sometimes you'll have worked on some service which simply won't be used as often as you'd have thought, sometimes you find no one who would use your service at all, all these cases, there's a chance you might not make any money off of those projects, but to make sure you get best out of them, make sure you're always learning. If you learnt things from a service, then maybe it's worth it.&lt;/p&gt;

&lt;p&gt;And sometimes you hit jackpot, you might get clients who need a lot of your service, or some of your service is actually used more often than you anticipated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Throwing some info:
&lt;/h2&gt;

&lt;p&gt;I have total of 3 services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AuthService (depends on a 4th service called KeyStore service)&lt;/li&gt;
&lt;li&gt;EmailService&lt;/li&gt;
&lt;li&gt;CartService&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me AuthService (8 clients using this) and EmailService (6 clients using this) make the most money, Cart service not so much as not too many people come to me asking to build a e-commerce platform.&lt;/p&gt;

&lt;p&gt;And that's just because I recently started doing this, I anticipate every single clients who I'll do projects for will need auth service AND email service.&lt;/p&gt;

&lt;h2&gt;
  
  
  FIN
&lt;/h2&gt;

&lt;p&gt;I feel this is a very good balance for both me and my client, I get to learn, I get paid for building a good quality service, and client gets his project developed faster/cheaper. I think this is what we call a win-win.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Let's understand QuickSort the easy way</title>
      <dc:creator>Nishchal Gautam</dc:creator>
      <pubDate>Sun, 27 Oct 2019 06:53:01 +0000</pubDate>
      <link>https://forem.com/cyberhck/let-s-understand-quicksort-the-easy-way-5jp</link>
      <guid>https://forem.com/cyberhck/let-s-understand-quicksort-the-easy-way-5jp</guid>
      <description>&lt;p&gt;Hello devs,&lt;/p&gt;

&lt;p&gt;This is my first post on dev.to (any edit suggestions welcomed) but since everyone wants to skip to the material right away so let's get to it.&lt;/p&gt;

&lt;h1&gt;
  
  
  QuickSort
&lt;/h1&gt;

&lt;p&gt;I'm gonna be doing everything with TypeScript but you could change this to whatever you'd like.&lt;/p&gt;

&lt;p&gt;Let's assume you have an array of numbers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="mi"&gt;1&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And you'd like to sort them, the obvious way is to do &lt;code&gt;items.sort()&lt;/code&gt; and it just works. There's really no need for you to do the sorting yourself, almost all languages include sorting and I think they are more optimized than what we would implement.&lt;/p&gt;

&lt;p&gt;But for the sake of argument let's say you're in an interview and interviewer asks you to write quick sort.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding requirements:
&lt;/h1&gt;

&lt;p&gt;First let's get requirements out of the way, what's better than to just write some test cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sort&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should be able to sort empty array&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;([])).&lt;/span&gt;&lt;span class="nx"&gt;toStrictEqual&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should be able to sort array with just 1 item&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toStrictEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should be able to sort array with multiple items&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&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;4&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;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;toStrictEqual&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;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&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;The way QuickSort works is by selecting a pivot element (any element, generally we pick the first one because of simplicity), and putting smaller items than the pivot to the left and larger items to the right, and this is done for each parts.&lt;/p&gt;

&lt;p&gt;Let's do a QuickSort manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="mi"&gt;1&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// pivot = 1&lt;/span&gt;
&lt;span class="c1"&gt;// there are no smaller items,&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 4, 2, 8, 6]&lt;/span&gt;
&lt;span class="c1"&gt;// let's do second pass for the rest of elements&lt;/span&gt;
&lt;span class="c1"&gt;// pivot = 4&lt;/span&gt;
&lt;span class="c1"&gt;// smaller = 2&lt;/span&gt;
&lt;span class="c1"&gt;// larger = 8, 6&lt;/span&gt;
&lt;span class="c1"&gt;// arranging: [1, 2, 4, 8, 6]&lt;/span&gt;
&lt;span class="c1"&gt;// another pass:&lt;/span&gt;
&lt;span class="c1"&gt;// pivot = 8&lt;/span&gt;
&lt;span class="c1"&gt;// smaller = 6&lt;/span&gt;
&lt;span class="c1"&gt;// there's no larger element&lt;/span&gt;
&lt;span class="c1"&gt;// final sorted array: [1, 2, 4, 6, 8]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Did you notice a pattern there? It's simple, take a pivot, get items lesser items than pivot from rest of items, take remaining items which are larger, and put them together and repeat.&lt;/p&gt;

&lt;p&gt;Let's write some pseudo code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pivot = first element, rest = rest of elements&lt;/li&gt;
&lt;li&gt;smallerItems = elements in rest lesser than pivot&lt;/li&gt;
&lt;li&gt;largerItems = remaining items in rest&lt;/li&gt;
&lt;li&gt;sort(smallerItems), pivot, sort(largerItems)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's write a function that does just that,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sort&lt;/span&gt; &lt;span class="o"&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;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;number&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;pivot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&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;smaller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rest&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;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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;pivot&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;larger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rest&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;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="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;pivot&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="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smaller&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;larger&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 a recursive function and will never return, we're missing a exit condition, which should return same items if array has less than or equal to 1 items &lt;code&gt;if (items.length &amp;lt;= 1)return items;&lt;/code&gt; Now our final function becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sort&lt;/span&gt; &lt;span class="o"&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;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;number&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;items&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&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;smaller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rest&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;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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;pivot&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;larger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rest&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;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="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;pivot&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="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smaller&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;larger&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;Let's do a quick check if this is actually working, to do that, I'll go to &lt;a href="http://www.typescriptlang.org/play/?ssl=10&amp;amp;ssc=1&amp;amp;pln=1&amp;amp;pc=1#code/MYewdgzgLgBBICdYF4YAoCWUCmBbCAXDGAK64BG2CA2gLoCURpFVdMyAfDAN4BQMMDADN0WPBAB0AG2xgA5lAAWMADyoAjPR78BMBNigkEYQTnwBuHQF8doSLGoAHDADcQUADQwJP-dFrspuKWAnbQcLgAhlIyCIF+UBJCGFI4CGgAHuxcWSowzm5Q9CEwYbBSkQhyVPHY0EkpaZnZMFkcqAXuxTr6hsYw1D4S8EhoEFExVPRenZ7ePiNQaBVVU7SWVpaLaNTqXgAsXgBMXgAcXgBsDLxAA"&gt;typescript playground&lt;/a&gt; and copy and run the code on browser, and it works:&lt;/p&gt;

&lt;p&gt;Obviously this isn't how you'd write any code if you were doing a pair programming, you'd want to do some level of TDD with feedback, since that can't be done on a dev.to post, so here's a video, but before you watch there's something I'd like to make clear:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On video when I'm adding first test which says for empty arrays and second test which checks for arrays with 1 items, I already added if condition on code, which is wrong, I should have simply returned the items, and on next iteration I should have added if condition, I kinda cheated on TDD, please overlook that&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/X_U35r6ZlJ8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I hope this was a nice read, please give feedback in comments, also let me know if you have seen more readable quicksort.&lt;/p&gt;

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