<?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: Thinkster</title>
    <description>The latest articles on Forem by Thinkster (@gothinkster).</description>
    <link>https://forem.com/gothinkster</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%2F322287%2F2f60c7b6-53b9-4fec-a179-c60a64c87587.jpg</url>
      <title>Forem: Thinkster</title>
      <link>https://forem.com/gothinkster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gothinkster"/>
    <language>en</language>
    <item>
      <title>Code Smell: Abstractions?</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Wed, 26 Feb 2020 18:22:18 +0000</pubDate>
      <link>https://forem.com/thinkster/code-smell-abstractions-19j1</link>
      <guid>https://forem.com/thinkster/code-smell-abstractions-19j1</guid>
      <description>&lt;p&gt;I recently read a great blog article by Coding Unicorn over on dev.to titled &lt;a href="https://dev.to/codingunicorn/flexible-code-is-considered-harmful-13nm"&gt;“Flexible code considered harmful”&lt;/a&gt;. Forgiving the over-used “considered harmful” title, the article was extremely thought-provoking. It’s fairly short and I recommend you give it a read.&lt;/p&gt;

&lt;p&gt;She makes an interesting point about how creating flexible code means that the code could be easily extended in the future, but those extension points have a cost in increased complexity. This means that the code is actually harder to understand and harder to change.&lt;/p&gt;

&lt;p&gt;She also mentions the &lt;a href="http://techdistrict.kirkk.com/2009/10/07/the-usereuse-paradox/"&gt;“Use/Reuse Paradox”&lt;/a&gt; (another good read, if a bit abstract) which indicates that things that are easy to use are difficult to reuse.&lt;/p&gt;

&lt;p&gt;Her summary point is “flexible and abstract code is hard to use and also hard to understand”. This point is certainly worth consideration. As we make code more flexible and abstract, does it become harder to use and understand?&lt;/p&gt;

&lt;p&gt;Let’s analyze this with some sample code.&lt;/p&gt;

&lt;p&gt;Let’s use an application that organizes and displays articles. Here is the structure for a sample article (highly simplified):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lwMdQEzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/389/0%2Amw_o620TJr8RlQRX%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lwMdQEzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/389/0%2Amw_o620TJr8RlQRX%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As indicated, each article can be tagged with one or more tags. In our interface, if we select one tag, we want to filter a list of articles by that tag. But we want to be able to drill down as well. For example, after selecting all javascript articles, we may want to drill down to just those related to Express. So once we select a tag and filter the articles to just those with that tag, we need to create a list of tags that all of those articles contain. We will need to make sure this list is de-duplicated, and we also need to remove the selected tag from the list.&lt;/p&gt;

&lt;p&gt;Be sure you understand what the requirements of our task are before you try to read the code. Now let’s create an algorithm to do this given a list of articles and a selected tag:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3IF6xH0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/615/0%2ARQ-IRipUzB5lW3gj%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3IF6xH0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/615/0%2ARQ-IRipUzB5lW3gj%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To understand anything unfamiliar in the above code, see the notes for the algorithm &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/5597452969443328/5570275139911680"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wrote this algorithm very straightforwardly. I tried to make it simply do the work. I added no abstractions. I would consider this the quickest way to get it working. It does the job, and the code is perhaps “simple” since it uses little to no abstractions. Does that make it easy to use? Certainly calling the function is easy to do.&lt;/p&gt;

&lt;p&gt;But what if we applied some typical coding refactorings and introduced some abstractions?&lt;/p&gt;

&lt;p&gt;Exercise: For a fun exercise, try taking this algorithm and “fixing” it before you look at my adjusted solution. Just make it better and more readable according to your own judgments. You can click this link and make your changes. Then compare to what I did with my fix shown below and see if you arrived at a similar solution.&lt;/p&gt;

&lt;p&gt;And now here’s the refactored algorithm, adding what I considered to be appropriate abstractions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pJ5_3EUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/576/0%2APn1wgQAMg3ecTuyx%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pJ5_3EUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/576/0%2APn1wgQAMg3ecTuyx%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at what has happened. I’ve created some sub-functions and a single class TagList, and now I’ve got all these reusable pieces that could be composed to do other jobs. Most of these functions can easily be reused. The TagList could be used in a lot of other places doing other jobs with tags in an application like this.&lt;/p&gt;

&lt;p&gt;I’ve added abstractions. I’ve arguably made the code more extensible and reusable. Have I made it more difficult to use or understand? You’d have a very hard time convincing me that the original solution was better in any way.&lt;/p&gt;

&lt;p&gt;Would &lt;strong&gt;you&lt;/strong&gt; say that this code is more readable than the original algorithm? Although readability can be subjective, I would guess that most people would say the new algorithm is more readable.&lt;/p&gt;

&lt;p&gt;One important point about abstractions that is critical to understand is that an abstraction is basically a way to handle several smaller pieces together with a simpler, single “handle.” A good example of an abstraction is a steering wheel in a car. It’s a simple tool that actually controls a very complex mechanism of rods and gears and various pieces. When we abstract away some of our code we give ourselves a simpler way to work with and reason about that code. That reduces our cognitive load. In &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/5345606690406400/5570275139911680"&gt;this fantastic article&lt;/a&gt; on programming and cognitive load, you can read about how cognitive load is essentially our hard limit as programmers. Abstractions allow us to work better and faster.&lt;/p&gt;

&lt;p&gt;Of course, like all things, this can be taken to an extreme. We generally call this over-engineering or the &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/5278415316058112/5570275139911680"&gt;YAGNI principle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, by adding these abstractions, did I over-engineer the solution? Was adding a “TagList” class too much? I tried implementing the algorithm without that class and I honestly felt like it made the code simpler. Another fun exercise: take my &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/5669848938184704/5570275139911680"&gt;final algorithm&lt;/a&gt; and try to refactor it and remove the TagList. After you do ask yourself if you think the code is now easier to use?&lt;/p&gt;

&lt;p&gt;One final point to explore is that we have used a rather simple code here. In a production system, the complexity is often multiplied by a factor of 10 or more. So does this hold up in a more complex system? We would have to spend hours (or perhaps weeks or months) together working on a system to really answer that question fully, but for reference, I actually based this example on a more complex algorithm that did the same thing in a production application I built. In that application, I implemented the full algorithm and even with abstractions I had a very difficult time keeping the cognitive load light enough to arrive at a correct solution. Without the abstractions, I would never have been able to create a working solution.&lt;/p&gt;

&lt;p&gt;So yes, we can over-engineer things, but avoiding abstractions is unlikely to make our code easier to write or read or extend.&lt;/p&gt;

&lt;p&gt;Agree? Disagree? Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Code Craftsmanship - Anticipating Change</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Tue, 25 Feb 2020 16:30:37 +0000</pubDate>
      <link>https://forem.com/thinkster/code-craftsmanship-anticipating-change-3708</link>
      <guid>https://forem.com/thinkster/code-craftsmanship-anticipating-change-3708</guid>
      <description>&lt;p&gt;Recently, I wrote a blog about &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/6104993704968192/5570275139911680"&gt;shotgun surgery&lt;/a&gt;. I talked about how the shotgun surgery code smell works. If you aren't familiar with it, go and check out that blog post.&lt;/p&gt;

&lt;p&gt;I like keeping these emails fairly short and digestible, but there's a bit more I wanted to discuss about this code smell, and how it relates to the process of growing your architecture.&lt;/p&gt;

&lt;p&gt;When we discuss software craftsmanship, such as code smells, we are working on keeping our code maintainable. This is a bottomless pit of effort. Ultimately we could spend years just perfecting code without ever adding new capabilities or features. It's the classic struggle between maintainability and over-engineering (which is a code smell itself). We can craft, and polish, and refactor, and re-architect, and make our code more and more beautiful. But at some point, we're wasting our time and should be doing something else (probably building more features).&lt;/p&gt;

&lt;p&gt;So where do we draw the line? How do we know when to stop? How can we decide what is good engineering, and what is over-engineering? What objective criteria can we use?&lt;/p&gt;

&lt;p&gt;It comes down to knowing what parts of the code to spend your time on, and here comes some of the art of programming: where is code likely to change? Craftsmanship improves maintainability. Maintainability is about changing code in the future. So if we know what code will change in the future, and how and why, then we know where to focus our efforts today.&lt;/p&gt;

&lt;p&gt;That's why shotgun surgery is a code smell. It is about the cost of making a change in the future. So knowing that a change could be made lets us address the issue today so that the changes (surgery) we make tomorrow are easier (or even possible).&lt;/p&gt;

&lt;p&gt;If you know for sure that a particular tax calculation will be changing next year, then you should make sure that the relevant section of the application is easy to change, and therefore you will spend extra time crafting that part of your system.&lt;/p&gt;

&lt;p&gt;Therefore, the time you spend considering the likelihood of change in a particular part of your system is time well spent. It gives you insight into what parts of the application should receive more focus. Never neglect parts of your system, but spend the extra time on the places that have a high likelihood of change.&lt;/p&gt;

&lt;p&gt;Identifying these places will often come from experience as a software developer. It will also come from domain knowledge about what you're building. It will come from understanding your backlog and what features may be built in the future. But there are certainly a few places that are more than likely to require change over time regardless of the above. So here are a few places you should highly consider spending extra time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interfaces with external systems&lt;/li&gt;
&lt;li&gt;Interfaces with other internal systems&lt;/li&gt;
&lt;li&gt;Interfaces between tiers of the existing system&lt;/li&gt;
&lt;li&gt;The user interface, especially core functionality that is important to your users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are areas that are likely to change, and likely to change frequently. So make sure they aren't full of cobwebs.&lt;/p&gt;

&lt;p&gt;Ultimately there's no crystal ball, no way to peer into the future. So keeping your entire code base well maintained is still the right answer. Every time you ignore a code smell, you are borrowing from tomorrow to pay today. Don't let that get out of hand.&lt;/p&gt;

&lt;p&gt;What likely places of change did I miss? &lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Code Smell: Comments</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Thu, 20 Feb 2020 21:23:34 +0000</pubDate>
      <link>https://forem.com/gothinkster/code-smell-comments-2pa5</link>
      <guid>https://forem.com/gothinkster/code-smell-comments-2pa5</guid>
      <description>&lt;p&gt;The idea behind comments seems pretty straightforward: we can add information about code that the code itself doesn’t give. It may be a comment about the purpose of the code. It may be a warning about changing the code in what seems like an obvious way, but would have a negative consequence. Or it may be an explanation of a strange performance optimization.&lt;/p&gt;

&lt;p&gt;Whatever the reason, comments are code smells. In essence, each comment we write is a failure. A failure of expressiveness. The fault may be ours, or it may be the fault of the language. No matter the reason, it is still a failure.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because if your code doesn’t “speak for itself”, and we have to add a comment, then we are dealing with a situation that is less than ideal. This is the real world and we rarely ever achieve the ideal, but nonetheless comments are less than ideal. Often times it is the fault of the technology we’re working with. We are doing something complex and we have to explain why we did this. It’s necessary. But it’s still less than ideal. If the code speaks for itself, then comments are unnecessary.&lt;/p&gt;

&lt;p&gt;We can’t control our technology. But we can control the code we write. We can improve our own expressiveness.&lt;/p&gt;

&lt;p&gt;Let’s consider the drawbacks of comments.&lt;/p&gt;

&lt;p&gt;First, comments are inexact. Code executes EXACTLY how it is written. We may or may not understand the code and how it will execute, but it always is exact. It always runs as written. Comments may be inaccurate. They may say something only mostly true about the code, based on our understanding.&lt;/p&gt;

&lt;p&gt;Second, comments are separate from the code they annotate. Therefore the code can change, and the comments may not be kept up. We may also accidentally separate our code spatially from the comments that apply to it, and create confusion by the geographical disparity. But more likely they just get out of date.&lt;/p&gt;

&lt;p&gt;Combine the first and second points, and we can get comments that are outright lies, misleading us into doing and thinking things that cost us time and energy at best, and at worst, they may cause us to introduce new bugs into production.&lt;/p&gt;

&lt;p&gt;We might think to ourselves: well, we have a team of good developers, we’ll just rely on them to keep comments up to date and keep them with the code they apply to. Sure. And while we’re at it we’ll count on them to unit test 100% of the time and we’ll ask them to stop writing any more bugs. Meanwhile back in the real world, mistakes get made. People get lazy. And why have a situation where this can even happen? Why have a situation that is less than ideal. Expressive code requires no comments. So always prefer expressive code over comments.&lt;/p&gt;

&lt;p&gt;Let’s look at one of the most common examples: regular expressions. Regular expressions are powerful. And usually they are extremely succinct compared to alternative methods using more typical code structures. But there’s an old saying: When you have a problem, and you use regular expressions, then you now have two problems. Regular expressions are notorious for being difficult to read and maintain. As a result, we very often put comments on our regular expressions to explain what they do.&lt;/p&gt;

&lt;p&gt;This is a failure of the expressiveness of our code. Regular expressions may be succinct and effective, but they are NOT readable. As a result of the failure of the language to be readable, or expressive, we usually have to employ comments. This situation is mostly the fault of the language, but there are ways we can mitigate the effect of something like this.&lt;/p&gt;

&lt;p&gt;Here’s an example with the obligatory comment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F636%2F1%2Anvx8leXsfXKM5aQqRhBrUQ.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F636%2F1%2Anvx8leXsfXKM5aQqRhBrUQ.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what if we refactored the code to this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F657%2F1%2A0qeKoAlmmm1N4MXRfdMmzg.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F657%2F1%2A0qeKoAlmmm1N4MXRfdMmzg.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the need for a comment has disappeared. This may not be possible with all situations with regular expressions, but it’s certainly a step in the right direction.&lt;/p&gt;

&lt;p&gt;Let’s consider an even more common scenario. This is some production code from an Angular project I worked on.&lt;/p&gt;

&lt;p&gt;Here’s the original code we wrote: (don’t bother really trying to grok the code, just look at the comments)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F722%2F1%2AmX6DsF3arJbd_qSgVWtXMQ.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F722%2F1%2AmX6DsF3arJbd_qSgVWtXMQ.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now refactored to not need comments:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AeUAPyF-02o1k1JX0MPcZ0w.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AeUAPyF-02o1k1JX0MPcZ0w.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By doing this we have added expressiveness, increased readability, and removed the need for comments. And now we can never get in the situation where we have old, inaccurate comments causing us problems.&lt;/p&gt;

&lt;p&gt;Every time I write a comment (and I write plenty of them) I always ask myself: “Is there a way to write more expressive code and remove the need for this code?”&lt;/p&gt;

&lt;p&gt;So in all cases, prefer fewer comments, and only use comments when expressiveness fails you, preferably due to the limitations of the language or framework and not your own coding.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/" rel="noopener noreferrer"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt; | Twitter: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Code Smell: Shotgun Surgery</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Tue, 18 Feb 2020 18:49:07 +0000</pubDate>
      <link>https://forem.com/gothinkster/code-smell-shotgun-surgery-2c47</link>
      <guid>https://forem.com/gothinkster/code-smell-shotgun-surgery-2c47</guid>
      <description>&lt;p&gt;If nothing else, the name of this code smell is one of the more entertaining names. The shotgun surgery code smell is one of the code smells that often overlaps with other code smells, particularly duplicate code. But it can still pop up and knowing about it and looking for it in your code will help you to keep your code more easily maintained. This is ESPECIALLY true of code bases that suffer from classes and functions that are too large.&lt;/p&gt;

&lt;p&gt;Remember the part of your system everyone is afraid to touch? You can almost guarantee it has issues with shotgun surgery. In fact, the shotgun surgery code smell is at the root of that issue of “you change something here and it breaks something over there” which has possibly caused more &lt;a href="https://www.youtube.com/watch?v=wwM3cUJKkuE" rel="noopener noreferrer"&gt;keyboard-related violence&lt;/a&gt; than just about anything else.&lt;/p&gt;

&lt;p&gt;To put it simply, shotgun surgery is when you have to go to multiple places in your codebase and make the same change. Let’s look at a simplified example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F615%2F1%2AdHw19POxCv0Hn2nzKXC86A.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F615%2F1%2AdHw19POxCv0Hn2nzKXC86A.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This savings class doesn’t look too bad at first glance, but the issue here is the proliferation of very similar code. Specifically, that minimum balance check.&lt;/p&gt;

&lt;p&gt;this.balance &amp;lt; MIN_BALANCE&lt;/p&gt;

&lt;p&gt;We’re doing that in three places. If something about that ever needs to change, then we’ll have to make changes in three places. Notice that all the code is not identical in each case, but the core logic is identical.&lt;/p&gt;

&lt;p&gt;So let’s look at one possible refactoring (you may come up with even better ones).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F613%2F1%2ABcKDLSK3y8X5mCYOlrYzqw.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F613%2F1%2ABcKDLSK3y8X5mCYOlrYzqw.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we have extracted the core logic of the check, and moved it to its own method. Personally, this is one of my favorite refactorings, to extract the boolean condition in an if into its own method, because then I can give that ugly boolean logic a nice name. Since we have gathered the duplicate logic together, we now have just one place to make changes if something about the minimum balance calculation needs to change.&lt;/p&gt;

&lt;p&gt;We could certainly go farther and look for even more similar logic extraction. But we’ll leave our example like this.&lt;/p&gt;

&lt;p&gt;Of course this is simple when the similar logic is gathered all together like this and obviously duplicated. In a real code base, this may be scattered around a much larger class, or it may even be in multiple classes, and even in different parts of the code base. But the lesson still stands. When we are dealing with checking the minimum balance, that should be done in ONE place, not three, or five, or ten. That way changes are easy to implement.&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/" rel="noopener noreferrer"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt; | Twitter: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>refactorit</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Code Smell: Side Effects — Solution</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Mon, 17 Feb 2020 17:07:49 +0000</pubDate>
      <link>https://forem.com/thinkster/code-smell-side-effects-solution-2dd2</link>
      <guid>https://forem.com/thinkster/code-smell-side-effects-solution-2dd2</guid>
      <description>&lt;p&gt;Recently I wrote about a particular code smell: Side Effects. Several people called me out for not providing a suggested fix to the identified problem. If you didn't read the original article, you can find it &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/5078485544730624/5570275139911680"&gt;here&lt;/a&gt;. You will want to be familiar with what I wrote to continue on here with the solution.&lt;/p&gt;

&lt;p&gt;In that article, we saw how we have a side effect in our loadUser function. Let's go through options for addressing this code smell.&lt;/p&gt;

&lt;p&gt;Our first task is to look at the calling code. Ultimately this is where the code smell is coming from because it's in the calling code that we SHOULD be handling the responsibility of emptying the cart, but instead, it got put into the loadUser function.&lt;/p&gt;

&lt;p&gt;Let's look at some example calling code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Ro7Ai48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AlOld_pgWdZTTfUig%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Ro7Ai48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AlOld_pgWdZTTfUig%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here our handleUserLogin method first creates a new empty user, sets it into the session object's user variable, and finally asks the session to load the User. It's inside this call that the cart is emptied. This is the crux of our issue. That operation of loading the user has some specific tasks. But it's ALSO emptying out the cart. That is perfectly appropriate in the situation of handling the user login. But if we ever needed to load user data and didn't want the side effect of emptying out the cart to happen, (maybe while refreshing data from the server) we don't have that option. A function should only do one thing. The loadUser function does two.&lt;/p&gt;

&lt;p&gt;So let's fix that by extracting the cart.empty call out of the loadUser function. The simplest answer is just to move it up one level into our calling code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VivQHBey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A_DLWWCYy8BkmrmqV%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VivQHBey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A_DLWWCYy8BkmrmqV%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And our loadUser is now clean of side effects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4HA50Hb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A1WMAzYx6HlOdXOum%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4HA50Hb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A1WMAzYx6HlOdXOum%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when someone else comes along and calls loadUser, they will get the result they want, and no unnecessary side effects.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Code Smell: Side Effects</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Thu, 13 Feb 2020 17:39:15 +0000</pubDate>
      <link>https://forem.com/gothinkster/code-smell-side-effects-3mp0</link>
      <guid>https://forem.com/gothinkster/code-smell-side-effects-3mp0</guid>
      <description>&lt;p&gt;When people say the term “side effects” we immediately think of functional programming. Having no side effects is a well-known rule of good functional programming. But the “No Side Effects” advice actually applies just as much to typical Object-Oriented Programming. It just requires a more nuanced definition of what a side effect is.&lt;/p&gt;

&lt;p&gt;Let’s look at a few examples of functions. Just glance at this list and see if you can determine from the name what the functions actually do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kLIsNK-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/220/1%2ACv6JGyf6EiBXociUfzFbqA.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kLIsNK-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/220/1%2ACv6JGyf6EiBXociUfzFbqA.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those functions are fairly straightforward. They give us a description that we can interpret and make some pretty reasonable assumptions about what they do.&lt;/p&gt;

&lt;p&gt;Now let’s imagine an implementation of one of these. We’ll use loadUser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CI91FTKd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/543/1%2ASUKMCoGw3mpZsyLDIeXjyQ.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CI91FTKd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/543/1%2ASUKMCoGw3mpZsyLDIeXjyQ.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now look closely at this function. There’s something fishy going on. Let’s break it down. First, it sets user data. Exactly what a loadUser function should do. Then it sets a loaded status of some kind on the user. Ok, we just loaded our user, so that makes sense as well. But THEN it empties out the cart. That’s our problem.&lt;/p&gt;

&lt;p&gt;When we just look at the function name loadUser, and if we saw it being called somewhere, knowing that it empties out the shopping cart is not in any way communicated. Sure, where it’s called, it may be completely reasonable that we empty out the cart because in that call we are loading a new user. But the function doesn’t communicate that. That opens us up to some insidious problems.&lt;/p&gt;

&lt;p&gt;What if we later on call loadUser to refresh the user data from the server? Or for some other reason, but we DON’T want the cart to be emptied when we do. Since we don’t know it’s doing that, we won’t know that we caused this problem possibly until it shows up in production with users complaining that every so often their cart just gets emptied out.&lt;/p&gt;

&lt;p&gt;THAT is a side effect. In OO programming, side effects are when a function does something it doesn’t communicate, something that might not be anticipated. Those are side effects.&lt;/p&gt;

&lt;p&gt;Good functions don’t have side effects, whether you’re doing OO or functional. Good functions communicate what they do so that you don’t have to dig in and read them to know what’s going on. Cognitive load is one of the biggest hurdles to programmer productivity. This practice helps keep that in check.&lt;/p&gt;

&lt;p&gt;So keep your eyes out for this code smell, and fix it where you find it.&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>A Reason for Change</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Wed, 12 Feb 2020 20:32:23 +0000</pubDate>
      <link>https://forem.com/gothinkster/a-reason-for-change-131f</link>
      <guid>https://forem.com/gothinkster/a-reason-for-change-131f</guid>
      <description>&lt;p&gt;There is much said about the SOLID principles. If you’re not familiar, the SOLID principles of Object Oriented development are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open/Closed Principle&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Liskov Substition Principle&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interface Segregation Principle&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these are important, but the one that probably gets the most coverage is the Single Responsibility Principle. Simply stated, each class should only do one thing.&lt;/p&gt;

&lt;p&gt;Of course this sounds good in principle but when dealing with actual code, this becomes far more nuanced and complex. Where should the responsibilities of a class end? Depending on how you define the class’s responsibilities, you can struggle with and justify a lot of bloat in your code. In a cart class, should it handle generating the subtotal or just hold the items and let someone else do the math? Is that one of its responsibilities? What about if we add a “save for later” feature? Is that the cart’s responsibility or someone else’s?&lt;/p&gt;

&lt;p&gt;As you struggle with these questions, you can spend a lot of time debating the right way to craft your code.&lt;/p&gt;

&lt;p&gt;When you’re having trouble deciding what functionality should or should not be the responsibility of a given class, there’s an alternative interpretation of the Single Responsibility Principle that can often lead to good results. I don’t recommend utilizing this method exclusively, but instead include it in your analysis when asking yourself “should this class/component include this functionality?”&lt;/p&gt;

&lt;p&gt;That is the “Reason for Change”. Ask yourself: what reasons would cause the class to change, and if it changes, what functionality would be affected by that change? Then work towards the ideal that a class would have only one reason to change.&lt;/p&gt;

&lt;p&gt;Let’s say that you’re working on a system that needs some real-time communication with a custom websocket. We not only need to connect and disconnect, but we also need to validate the identity of the client. So we come up with the following public methods for a “SocketConnection” class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;connect()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;authenticate()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;disconnect()&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seems reasonable doesn’t it? The class is responsible for the communication with the server, and all things related to that are in the class.&lt;/p&gt;

&lt;p&gt;But think about this: connection &amp;amp; disconnection are likely to change together. If the way that we connect changes, then it’s reasonable that the disconnection may change as well. Those two piece of functionality belong together and are likely to reuse a lot of functionality between them.&lt;/p&gt;

&lt;p&gt;On the other hand the authentication piece is possibly very different from the other two. If we change how we authenticate after we connect, we very likely wouldn’t change how we connect or disconnect.&lt;/p&gt;

&lt;p&gt;So the reasons for change are different. This implies that the responsibilities should be separated out into two different classes. That leaves the class that simply connects and disconnects with only one reason to change: The method of connection has changed. And the other class has a single reason to change as well.&lt;/p&gt;

&lt;p&gt;Now don’t think that what we should end up with is a million different classes each with one method. But instead look at the class not as a collection of “related” functionality, but instead as a collection of “interdependent” functionality. Then separate out stuff that isn’t interdependent into collaborators and dependencies. A great way to identify this is to ask if the class has a single reason for change.&lt;/p&gt;

&lt;p&gt;In the end you’ll have to make your own judgements, but just getting in the habit of asking yourself the above questions will help you design better, more robust, more well-factored classes.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploy Your First Site to Netlify in Under Three Minutes</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Tue, 11 Feb 2020 17:06:01 +0000</pubDate>
      <link>https://forem.com/gothinkster/deploy-your-first-site-to-netlify-in-under-three-minutes-40m3</link>
      <guid>https://forem.com/gothinkster/deploy-your-first-site-to-netlify-in-under-three-minutes-40m3</guid>
      <description>&lt;p&gt;I'm a huge fan of Netlify, I've made no secret of that. I think that the JAMStack is one of the most innovative and promising techniques in recent years for web development. So I asked &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/6298029557809152/5570275139911680"&gt;Preston Lamb&lt;/a&gt;, the author of our awesome &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/6736249969967104/5570275139911680"&gt;"Deploying Apps to Netlify"&lt;/a&gt; course, to write up a quick summary of how to get a site up and running on Netlify in just a couple minutes. Seriously. You can follow this tutorial and have an app deployed to Netlify in less than 3 minutes. If you haven't tried out Netlify before, you should definitely follow along.&lt;/p&gt;

&lt;p&gt;Preston: Netlify is one of the best platforms to happen to the web development community in the last several years. I've been using the product for a little over 2 years, and it has made deploying everything from static sites to single-page apps so much easier. If you've never used Netlify, but have a site or application that needs to be deployed, I highly recommend taking a look at Netlify.&lt;/p&gt;

&lt;p&gt;For those of you who aren't familiar with what Netlify is, it's a platform that gives you the ability to deploy your website or web application without the need to manage the server yourself. Generally speaking, you will connect your project repository (GitHub, GitLab, and Bitbucket for now) to Netlify and when new code is pushed to the repo, the site will be automatically deployed. In addition to the continuous deployment and hosting of the sites, Netlify offers many great features, like custom domains, SSL certificates, form submissions, analytics, and serverless functions, to name a few. Netlify allows you to build whatever it is you'd like to build and makes it as easy as possible to host it. Oh, and the best part is: it's free to get started! You can host a personal site on Netlify for free, and many of the add-ons have a free tier. This is great because it allows you to try it out with no risk. If it works for you (which it should in most situations), then you can keep using it. If not, you can switch to another solution.&lt;/p&gt;

&lt;p&gt;So let's talk about what you need to do to get started. The first step is to go to &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4595466940710912/5570275139911680"&gt;www.netlify.com&lt;/a&gt; and sign up (the account is free). The easiest way to sign up is with your GitHub, GitLab, or Bitbucket account. To walk through this exercise use GitHub. After signing up, you'll end up on a page which will eventually list out all the sites you've deployed to Netlify.&lt;/p&gt;

&lt;p&gt;We can get a simple site deployed in less than three minutes now. Head over to &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/6023256676237312/5570275139911680"&gt;https://github.com/joeeames/netlify-hello-world&lt;/a&gt; and fork that repo (it's just a simple site with one static page).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--syHWYqx7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AnbDzXHqbfcOB3V8z%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--syHWYqx7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AnbDzXHqbfcOB3V8z%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to Netlify. Towards the right and top of the page is a button that says "New site from Git".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--98ucGeKw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AgdFMqmua_us0STLL%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--98ucGeKw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AgdFMqmua_us0STLL%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the button, and go through the steps to create your new site. The first step is locating the repository. First, click the GitHub button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1dwX0Mls--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AdtTQmUAznVZVQm2A%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1dwX0Mls--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AdtTQmUAznVZVQm2A%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, select the repo you just cloned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7uCgGUwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AsrHpGaxrpmCOQvKL%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7uCgGUwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AsrHpGaxrpmCOQvKL%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting the repository, you'll be able to select a branch from which you'll want to deploy your site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z_Wl-F9H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AtlpXDRJp907nudsP%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_Wl-F9H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AtlpXDRJp907nudsP%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll also be able to enter the build command your app or site needs to run, and then the directory where the built site will be located. Finally, you'll be able to set any build environment variables that your site may need. In our case, you don't need to enter anything since this is just a simple HTML site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k5Av8KNw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AgvQKo2zqGjYrD5uq%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k5Av8KNw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AgvQKo2zqGjYrD5uq%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've deployed your site, you can customize the site in a number of ways. The first way is to change the URL to the site. By default, Netlify will automatically generate a site ID, and the URL will look like this: some-site-id.netlify.com. The "some-site-id" part though will normally be something hard to remember and type. But, you are allowed to change that value to anything you want, as long as it's unique.&lt;/p&gt;

&lt;p&gt;To change it, click on the site settings button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BKy4Vjx1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A-ZUsWE5zba-xKfUk%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BKy4Vjx1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A-ZUsWE5zba-xKfUk%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That takes you to the "Site details" portion of the settings page. In that box is a button, "Change site name". Click that button, and in the modal, you'll be able to change your site's name. Again, it can be anything you'd like as long as it's unique, and the form will tell you if it is unique. This will make it easier for people (including you) to get to the URL for your site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oMbsewS7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2ARxGJ5AEl35LinVBz%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oMbsewS7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2ARxGJ5AEl35LinVBz%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a custom domain that you'd like to set up for your site though, or would like to purchase one, you can click the "Domain settings" button or choose the "Domain management" section of the settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zx9fvaHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AnbPRM7SvRkZlDtYW%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zx9fvaHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AnbPRM7SvRkZlDtYW%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Netlify will walk you through the process of configuring your custom domain or purchasing a new one and setting that up. The process isn't too complicated and will allow an even simpler way for people to get to your site or application.&lt;/p&gt;

&lt;p&gt;I could go on and on about the benefits of Netlify and its features, but I think you get the point. It's an incredible tool, and one that I really believe can benefit any developer. Whether your site is built in Angular, React, Gatsby, Vue, Jekyll, or just plain old HTML, CSS, and JavaScript, Netlify is the tool for you. Try it out, and let me know how it goes!&lt;/p&gt;

&lt;p&gt;-&lt;a href="https://twitter.com/prestonjlamb?lang=en"&gt;Preston Lamb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this tutorial helpful, be sure to check out Preston's &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/6549483837194240/5570275139911680"&gt;Netlify course&lt;/a&gt; on Thinkster.io!&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Better Way to Loop Over an Array</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Fri, 07 Feb 2020 17:06:22 +0000</pubDate>
      <link>https://forem.com/thinkster/a-better-way-to-loop-over-an-array-ae3</link>
      <guid>https://forem.com/thinkster/a-better-way-to-loop-over-an-array-ae3</guid>
      <description>&lt;p&gt;When you need to loop over an array in JavaScript do you default to the trusty for loop? Even got yourself a quick keyboard macro to create your for loop? You're in good company, I do the same. Something like the following is my habitual goto when looping over an array of data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AuUkiTfKHaSKUsSN1.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AuUkiTfKHaSKUsSN1.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But there's a better way. the forEach method on arrays not only lets you deal with this pattern in a more functional way, it's just prettier (no relation to prettier :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ArOkNK5dcT050_sav.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ArOkNK5dcT050_sav.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what if you need the index? what if you're going to display that as well, like in the following?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ACyd-Zvjiqy4aTmXf.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ACyd-Zvjiqy4aTmXf.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, no problem. foreach has you covered there. The second parameter to the foreach is the current index.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A5C6J0RBBapPHAlZg.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A5C6J0RBBapPHAlZg.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, foreach allows you to separate out your iteration function from the iteration itself and create code that is extremely readable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AdMohAqq3RchZLSL4.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AdMohAqq3RchZLSL4.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You CAN do this with a for loop, but it's not nearly as readable:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AfZZ0M7iecrqCgpRn.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AfZZ0M7iecrqCgpRn.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One final note. The forEach function also uses a 3rd parameter which is the array itself, in case you need to use the entire array in your processing function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AZi9ulOM-f-VOcRft.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AZi9ulOM-f-VOcRft.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it's time to actually LEARN something. Without practice, tomorrow you'll only remember about 15% of what you just read. Want to learn all of it? That requires actually PRACTICING what I just showed you.&lt;/p&gt;

&lt;p&gt;This StackBlitz project has several different for loops that need to be turned into more readable foreach functions. It'll take you a couple minutes to complete, but by the time you're done you'll actually feel comfortable using forEach in your own coding, and can finally drop that less effective for loop.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/" rel="noopener noreferrer"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt; | Twitter: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>refactorit</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>What the Heck is a JavaScript Map?</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Wed, 05 Feb 2020 17:33:40 +0000</pubDate>
      <link>https://forem.com/thinkster/what-the-heck-is-a-javascript-map-2i82</link>
      <guid>https://forem.com/thinkster/what-the-heck-is-a-javascript-map-2i82</guid>
      <description>&lt;p&gt;Imagine the following scenario in JavaScript:&lt;/p&gt;

&lt;p&gt;You’re building a contact management app, and you need to track data about contacts, but you need to allow your users to add custom data points for each contact in the system. So for one contact, you might track their name, age and birthday, but for another contact, you want to track their favorite holiday and the name of their dog.&lt;/p&gt;

&lt;p&gt;How would you go about modeling this in your logic?&lt;/p&gt;

&lt;p&gt;One possible answer would be a pair of arrays. The first array would contain the labels for each data point, and the other array would contain the values of each data point. But this is a bit unwieldy. Maybe a single array, where the even indexes have the label of the data, and the odd indexes have the value? So if data[0] equals “name” then data[1] would contain the contact’s name.&lt;/p&gt;

&lt;p&gt;Again, this works, but it’s a bit….clunky.&lt;/p&gt;

&lt;p&gt;An object is a much better choice, since it’s innately a key/value pair, and you can add keys &amp;amp; values to an existing object at runtime. You can do this by accessing and setting the properties of the object using the array indexer syntax.&lt;/p&gt;

&lt;p&gt;Usually to get the name property of an object we do this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--POXJN3A7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/132/0%2A7UHhQeQXv5PpLYRW.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--POXJN3A7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/132/0%2A7UHhQeQXv5PpLYRW.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;but we can actually access that same property by doing this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fisoXOtr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/163/0%2AJ3cTQncuEHo4FEiI.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fisoXOtr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/163/0%2AJ3cTQncuEHo4FEiI.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now, we can add new properties with names defined by our users, by using a function like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AvGP9wTE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/662/0%2A3OvZOqx0o6sKjmv-.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AvGP9wTE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/662/0%2A3OvZOqx0o6sKjmv-.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out an example of this &lt;a href="https://stackblitz.com/edit/angular-ltpgpj?file=src%2Fapp%2FaddDynamicProps.ts"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But there’s another option. The new ES6 datatype Map can offer the same functionality with possibly a bit more elegance. A map is like an object, in that it is a collection of key/value pairs, but instead of using an array syntax, Maps use set and get methods.&lt;/p&gt;

&lt;p&gt;So the above function would now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--awP7kErc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/665/0%2Az7_n5-7pwh5vXxzP.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--awP7kErc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/665/0%2Az7_n5-7pwh5vXxzP.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See a running example &lt;a href="https://stackblitz.com/edit/angular-pnftyo?file=src%2Fapp%2FaddDynamicProps.ts"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Map object has a few advantages over a standard JavaScript object: it remembers insertion order, it’s a bit easier to iterate over, it has a length property, it supports datatypes other than strings as the key, and it’s easier to remove items from.&lt;/p&gt;

&lt;p&gt;Knowing the different data types available, and their relative strengths &amp;amp; weaknesses can make a great deal of difference in your code.&lt;/p&gt;

&lt;p&gt;Now if you really want to stretch your noggin, see if you can figure out what the following code would do:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Djf5dR69--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/271/0%2A7m7pBA3173l0cgHR.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Djf5dR69--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/271/0%2A7m7pBA3173l0cgHR.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And what if we added this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--heN7-eCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/211/0%2AJ6BOTKbB7Mrh0qqb.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--heN7-eCf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/211/0%2AJ6BOTKbB7Mrh0qqb.png%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try it out in &lt;a href="https://stackblitz.com/edit/js-jftsjg"&gt;this stackblitz project here&lt;/a&gt; (open the console by clicking the word “console” in the bottom right).&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>JavaScript is Taking Over the World, and TypeScript With It</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Tue, 04 Feb 2020 17:17:36 +0000</pubDate>
      <link>https://forem.com/thinkster/javascript-is-taking-over-the-world-and-typescript-with-it-4ph</link>
      <guid>https://forem.com/thinkster/javascript-is-taking-over-the-world-and-typescript-with-it-4ph</guid>
      <description>&lt;p&gt;JavaScript has become the most popular programming language in the world. But as JavaScript has become more popular, so has TypeScript, and it's rise continues. The RedMonk language popularity measure has been &lt;a href="https://redmonk.com/sogrady/2019/03/20/language-rankings-1-19/"&gt;recently released&lt;/a&gt; and has shown a huge jump in TypeScript usage.&lt;/p&gt;

&lt;p&gt;Not everyone is happy about this. Many developers love their nice, dynamic JavaScript, and don't want types. But like it or not, there's a very real possibility that you may end up in a job using TypeScript.&lt;/p&gt;

&lt;p&gt;That's why I've put together a brand new, completely free course on the &lt;a href="https://thinkster.io/tutorials/five-essential-lessons-for-typescript-competence"&gt;Five Essential Lessons for TypeScript Competence&lt;/a&gt;. I have cut out all the extra cruft and kept in just the essential things that you need to know about TypeScript. I even included some practice exercises so that you can actually LEARN the concepts by DOING, instead of just listening and then immediately forgetting most of what you heard. Check it out. It's well worth your time if you're not comfortable with TypeScript yet. You'll be TypeScript competent in just fifteen minutes.&lt;/p&gt;

&lt;p&gt;I hope you enjoy it.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
 | Twitter: &lt;a class="comment-mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Code Smell: Null Check</title>
      <dc:creator>Thinkster</dc:creator>
      <pubDate>Mon, 03 Feb 2020 20:22:04 +0000</pubDate>
      <link>https://forem.com/thinkster/code-smell-null-check-2kg1</link>
      <guid>https://forem.com/thinkster/code-smell-null-check-2kg1</guid>
      <description>&lt;p&gt;I love this code smell. First I find the solution to be fascinating. Second, the indicator (checking for null) is often NOT a problem, more so than in most code smells. But that's the beauty of code smells. They give us an indication that something MIGHT be amiss, but we have to check it out ourselves and decide if something really does need to be corrected.&lt;/p&gt;

&lt;p&gt;So let's start by looking at an example of the problem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AQ8lIsatLPcXnLE5Y%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AQ8lIsatLPcXnLE5Y%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we have some sample code from an eCommerce site. It's fairly typical on these sites to allow you to check out as a guest and not create an account.&lt;/p&gt;

&lt;p&gt;Here is one such algorithm, where we determine the discount to apply to the order. If the user is checking out as a guest (the customer object is null) then we use a default discount, otherwise we use the customer's earned discount.&lt;/p&gt;

&lt;p&gt;Looking at this method our null check seems fairly harmless. This is a reasonable way to implement the necessary functionality.&lt;/p&gt;

&lt;p&gt;Now let's look at another method from that same class:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A2y2nXwJdVTy800qZ%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A2y2nXwJdVTy800qZ%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we have the same thing going, we have to know if the user is checking out as guest or not. And now we can start to see part of the problem. Our null checks are littered around our code. We can assume that this logic is common, so we have to frequently check to see if the customer is null for the order.&lt;/p&gt;

&lt;p&gt;This is our code smell. Frequent checks for the same null.&lt;/p&gt;

&lt;p&gt;So what do we do about this? There's a very cool fix we can apply here by using what's called a Null Object. Null objects are special classes which replace a null value in our code so that we can simplify our code. Let's see how this is done.&lt;/p&gt;

&lt;p&gt;First we create a NullCustomer class. This is our Null Object. Notice the two methods it has. Remember where those methods are used?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ApN5LzOU9OXBsXynE%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ApN5LzOU9OXBsXynE%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we create our NullCustomer, and use it instead of setting the customer to null. This way, we do our null check only once.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AWyOfRamd5TaJdfT9%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AWyOfRamd5TaJdfT9%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now, we can go back to our order class and fix the getDIscount and processOrder methods. Because our Null Object implements those methods, we no longer have to do any kind of check in our code. That makes our core business logic simpler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2Ap1uLzXY9zEr59azP%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2Ap1uLzXY9zEr59azP%3F" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, our getDiscount has become so simple, we may consider dropping it altogether.&lt;/p&gt;

&lt;p&gt;This is the power of the Null Object used to solve the Null Check code smell. I really think this is a cool technique to solve a relatively common problem.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;Signup for my newsletter at &lt;a href="https://is-tracking-link-api-prod.appspot.com/api/v1/click/4616255200034816/5570275139911680" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;br&gt;
Visit Us: &lt;a href="https://thinkster.io/" rel="noopener noreferrer"&gt;thinkster.io&lt;/a&gt; | Facebook: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt; | Twitter: &lt;a class="mentioned-user" href="https://dev.to/gothinkster"&gt;@gothinkster&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codesmells</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
