<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mayuran</title>
    <description>The latest articles on DEV Community by Mayuran (@maybebored).</description>
    <link>https://dev.to/maybebored</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%2F94355%2Fe8c9ae5a-c5a7-434e-9391-57ced1555b9c.png</url>
      <title>DEV Community: Mayuran</title>
      <link>https://dev.to/maybebored</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maybebored"/>
    <language>en</language>
    <item>
      <title>Fixing Memory Leaks in Node.js</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Tue, 20 Feb 2024 20:00:14 +0000</pubDate>
      <link>https://dev.to/maybebored/memory-profiling-nodejs-apps-to-debug-issues-3e7e</link>
      <guid>https://dev.to/maybebored/memory-profiling-nodejs-apps-to-debug-issues-3e7e</guid>
      <description>&lt;p&gt;Usually unless there is a spike in traffic the memory usage of a server should be regular, and stable. Memory usage of a server that continuously increases over time / per request could indicate a memory leak bug.&lt;/p&gt;

&lt;p&gt;This post describes how to use "Chrome Dev Tools for Node" to profile memory of a NodeJs App, and identify the source of a memory leak.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

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

git clone git@github.com:maybebored/codesamples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;memory-leak-example

&lt;span class="c"&gt;# Build&lt;/span&gt;
yarn build

&lt;span class="c"&gt;# Run the app with --inspect so it can be profiled&lt;/span&gt;
node &lt;span class="nt"&gt;--inspect&lt;/span&gt; ./dist/index.js
&lt;span class="c"&gt;# This will output the debugger port to connect ex:- Debugger listening on ws://127.0.0.1:9229/a2fc3802-d5d9-497b-b3f7-9fe439414e13&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Use the dedicated DevTools for Node on &lt;a href="https://dev.tochrome://inspect/#devices"&gt;Chrome Devices Page&lt;/a&gt;. Navigate to the Memory tab, and check that the Node process shown matches the debugger port of your app. If it doesn't show there, go to Connection page and add the connection as &lt;code&gt;localhost:{Your debugger port}&lt;/code&gt;, example mine is &lt;code&gt;localhost:9229&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profiling
&lt;/h2&gt;

&lt;p&gt;There are 3 different profiling types shown here. This post will utilise the Heap snapshot. Perhaps a future post will explore the other 2 types in more detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipt3co1qffike6elmod1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipt3co1qffike6elmod1.png" alt="Screenshot of a Chrome Dev Tools Memory tab. It shows 3 types of memory profiling types to choose from"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Heap Snapshot
&lt;/h3&gt;

&lt;p&gt;A heap snapshot is what it sounds like, a snapshot of all the objects stored in the heap, how much memory they are using, what created them, and some more details.&lt;/p&gt;

&lt;p&gt;I found that comparing snapshots overtime provided the most useful hints to find the source of the leak. &lt;/p&gt;

&lt;p&gt;Click on the record button to take a snapshot before firing any requests. This serves as the baseline. Then fire requests and take a snapshot. Repeat this a few times until the analysis reveals something useful.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;h1&gt;
  
  
  fire n requests
&lt;/h1&gt;

&lt;p&gt;ab -n 1000 &lt;a href="http://localhost:4000/info" rel="noopener noreferrer"&gt;http://localhost:4000/info&lt;/a&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Snapshot 1&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqbuyexajmmvo3kh8xwp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqbuyexajmmvo3kh8xwp.png" alt="Screenshot of a Chrome Dev Tools Memory tab. It shows 3 snapshots, and the 1st snapshot is selected. It displays four columns, namely, Constructor, Distance, Shallow Size, and Retained Size."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After taking the first snapshot, by default a Summary view is displayed, which shows some important data. The different columns are explained in detail in &lt;a href="https://developer.chrome.com/docs/devtools/memory-problems/heap-snapshots#summary_view" rel="noopener noreferrer"&gt; Chrome's developer docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to note here is the difference between the column Shallow Size, and Retained Size. Shallow size is memory held by the the &lt;em&gt;Constructor&lt;/em&gt; alone, Shallow size is memory held by the &lt;em&gt;Constructor&lt;/em&gt; indirectly because it holds a reference to another object. By default the Constructors are sorted by their retained size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Snapshot 2
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygg78bp1qlh0mu52ejfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygg78bp1qlh0mu52ejfu.png" alt="Screenshot of a Chrome Dev Tools Memory tab. It shows 3 snapshots, and the 2nd snapshot is selected. It displays four columns, namely, Constructor, Distance, Shallow Size, and Retained Size."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This snapshot was taken a few seconds after firing 6000 requests. It is important to remember each snapshot does garbage collection before the snapshot. This means, the memory usage shown in the snapshot is that which is currently in usage.&lt;/p&gt;

&lt;p&gt;In this snapshot we notice the memory usage is 24.3 MB. We also notice that in 6th place is a class defined in the app's code: &lt;code&gt;Logger&lt;/code&gt;, holding roughly 14 MB - over 50% of the heap memory. This already provides some useful clues about where the issue could be, yet it does not point exactly where the issue is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compare snapshot 2 to snapshot 1
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48j9cyq2gpmpsufzchk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48j9cyq2gpmpsufzchk5.png" alt="Screenshot of a Chrome Dev Tools Memory tab. It shows 3 snapshots, and the 2nd snapshot is selected. The view is a comparison view comparing Snapshot 2 to Snapshot 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comparison view shows "Size Delta" in &lt;em&gt;Constructors&lt;/em&gt; between Snapshot 2 and 1. This allows us to scope down into the problem. When sorting by "Size Delta" it is clear that almost 13 MB of strings were created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlljtjvgexvmyicatmmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlljtjvgexvmyicatmmi.png" alt="Screenshot of a Chrome Dev Tools Memory tab. It shows 3 snapshots, and the 2nd snapshot is selected. The view is a comparison view comparing Snapshot 2 to Snapshot 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on (strings), reveals all the strings that were created, and clicking on each opens a detailed view of its contents. At the bottom, in Retainers tab, a hierarchical view of the string's references are shown. Over here, it is noticeable a variable named &lt;code&gt;buffer&lt;/code&gt; that belongs to our &lt;code&gt;Logger&lt;/code&gt; class is referencing it.&lt;/p&gt;

&lt;p&gt;Every other string also points to the same variable &lt;code&gt;buffer&lt;/code&gt;. With this information, it is clear enough to debug the code to fix the memory leak.&lt;/p&gt;

&lt;p&gt;Note that the hierarchy of references extends all the way until express.js handler functions, and then to NodeJs internal event loop functions. This is the reason why Summary view of a snapshot is not very useful as internal closures' retained memory also increases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Chrome DevTools allows for 3 types of memory profiling NodeJs Apps&lt;/li&gt;
&lt;li&gt;Heap snapshot types allows taking many snapshots and comparing them.&lt;/li&gt;
&lt;li&gt;Summary view of a snapshot does not give an immediate clue as to where the problem is because library functions / internal classes can also appear there.&lt;/li&gt;
&lt;li&gt;Comparison view shows objects created between 2 snapshots, allowing to scope down to the problem area.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>performance</category>
      <category>tutorial</category>
      <category>backend</category>
    </item>
    <item>
      <title>7 things I learned in my first year of work</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Sat, 20 Jun 2020 14:47:50 +0000</pubDate>
      <link>https://dev.to/maybebored/7-things-i-learned-in-my-first-year-of-work-50f4</link>
      <guid>https://dev.to/maybebored/7-things-i-learned-in-my-first-year-of-work-50f4</guid>
      <description>&lt;p&gt;Fitting in at your first job can be challenging. Often, there'd be no one to guide you, tell you right from wrong, almost everything you learn is on your own. Growing and improving in your first job, is not obvious either, it takes time and effort. I joined a team, that guided  me and provided me with an environment to learn, grow and have fun along the way. I learned many things in my year long journey, and I wish to share some of them, hoping that it helps the newcomers of tomorrow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Don't be afraid to interact.
&lt;/h2&gt;

&lt;p&gt;If you're an ambivert like me, you may try to avoid unnecessary social interactions as much as possible. The ambivert (or introvert) in you will cause you to incorrectly think every non-work interaction is unnecessary. It's a bias, don't give in to it. Through some of the most awkward &lt;em&gt;'Hello's&lt;/em&gt;  and &lt;em&gt;'Nice to meet you's&lt;/em&gt;  I've met some of the brightest minds at my workplace. &lt;/p&gt;

&lt;p&gt;When you start talking to people and find out their interests, ideas and stories, you make connections you'd be truly fond of. It will make your work life a bit less boring and more importantly make collaborating an exciting activity.&lt;/p&gt;

&lt;p&gt;I made friends with an engineer who loves teaching, maintains an &lt;a href="https://hellokoding.com/"&gt;awesome tech blog&lt;/a&gt; and loves travelling. I learnt a lot about Java from him, and helped him with JavaScript where I could. We worked on complex tasks together. It was satisfying to collaborate with someone with so much experience, and I may never have had the opportunity if not for the awkward &lt;em&gt;'Hi how's it going?'&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: Stick to your work schedule.
&lt;/h2&gt;

&lt;p&gt;I knew it's a bad idea to take your work home, but disappointingly, I would find myself working on tasks at home, every other day. It was just bad planning on my part that contributed to this failure.&lt;/p&gt;

&lt;p&gt;Eventually I adopted a different model. I plan a schedule when I start my work day, evaluate how much I've completed at the end of the day, adjust my workload for the next day based on how much I can complete and repeat this process. This worked for a while until I started taking up ad hoc tasks, during the middle of the day, failing to complete my planned tasks for the day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter priority based task handling&lt;/strong&gt;. My planned tasks were my highest priority, I picked them and sorted them based on my capability to complete them and how impactful they were. Ad hoc tasks pop up a lot in an &lt;a href="https://www.atlassian.com/agile/manifesto"&gt;agile team&lt;/a&gt;, they are good, it's the mechanism to continuously steer clear of obstacles, and stay on the road towards the bigger goal. But they messed up my daily plan, so naturally I deprioritized tasks for my original list, to make space for the ad hoc task. This is working for me even a year later.&lt;/p&gt;

&lt;p&gt;Assigning priorities is a mundane process, but it benefits me in the following ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I rarely take work home, so I have time at home to spend on myself.&lt;/li&gt;
&lt;li&gt;I feel good about ticking off all my tasks for the day. I am able to see myself grow when I complete more complex tasks quicker.&lt;/li&gt;
&lt;li&gt;It improved my productivity, and therefore the team productivity.&lt;/li&gt;
&lt;li&gt;I got pretty good at judging priority, which is an essential skill in and outside work.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lesson 3: Stick to your learning schedule.
&lt;/h2&gt;

&lt;p&gt;If you read the previous lesson, you'd appreciate the value of a schedule. In the world of software, no one knows everything, and the rate at which new information pops up is overwhelming, so how do you keep up with all the new frameworks, languages and best practices.&lt;/p&gt;

&lt;p&gt;You don't. You can try to adopt the &lt;a href="https://medium.com/personal-growth/the-t-shaped-approach-to-building-a-21st-century-career-764bdbbcbb4b"&gt;T-shaped learning model&lt;/a&gt;. Simply put, it's when you learn to become an expert at one thing by researching and acquiring deep knowledge, while expanding your knowledge across various subjects.&lt;/p&gt;

&lt;p&gt;I enjoy learning about the web, so I dived into front-end development with React, Angular and experimented with some other frameworks. The more I worked, the more I realised, how important understanding JavaScript (ECMA Script) was to becoming a good front-end developer and building client side application, because all good UI frameworks, do the same thing: build wrappers around JavaScript's core features to expose APIs that make the developer's life easier.&lt;/p&gt;

&lt;p&gt;So I spent a lot of time reading and understanding the fundamentals of JavaScript, tinkering with experimental JS features, using advanced concepts at work, all in order to improve my mastery of the language. This helps me work with modern frameworks better, debug faster and justify my technical decisions. In addition, I continue to learn more about how the web works, how online payments work (My team is working on a payment gateway) and cloud technologies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rj7vqd0arfhqsavmjrp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2rj7vqd0arfhqsavmjrp.jpg" alt="T diagram of knowledge" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My T shaped knowledge on software might look like the above.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To do this effectively, I put in six hours each week for six months to read, code and discuss JavaScript with experts. 1 year later, I can work with advanced concepts like closures, promises and async functions with ease. I'm not an expert yet, but I'm progressing steadily.&lt;/p&gt;

&lt;p&gt;Figure out what you'd like to learn by actually trying everything you might like to learn; you'll eventually find out what you are most interested in. After that work out a study plan, invest time, subscribe to resources online (paid or free) and work your way through it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://medium.com/@jchyip/why-t-shaped-people-e8706198e437"&gt;More on T shaped learning&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Lesson 4: Challenge your peers.
&lt;/h2&gt;

&lt;p&gt;As a junior working with people who have more experience and knowledge can be daunting. It's normal to feel like you should have less say, but it's wrong to follow through with that feeling.&lt;/p&gt;

&lt;p&gt;You're depriving yourself of opportunities to learn if you never challenge your peers. Sticking to my learning schedule helped me understand JavaScript as a language really well, why it was made, how it was supposed to be used and what are some common pitfalls.&lt;/p&gt;

&lt;p&gt;We use AWS Lambdas at work to offload asynchronous tasks, which was a neat idea. The code written (in JavaScript) to do it, not so much. I raised questions about efficiency, complained about code quality and eventually asked for a chance to work on it to make it better. It didn't go exactly as planned, (we still have Lambdas written with bad code, more on that later) but some good came out of it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The team appreciated my growth and my ability to point out mistakes.&lt;/li&gt;
&lt;li&gt;I learned how to communicate my thoughts better, especially on tech. It's not easy to get your point across all the time, which is why it takes practice.&lt;/li&gt;
&lt;li&gt;Asking 'Why are we doing this?' helped me understand the system better, allowing me to be a contributor the next time we were designing new features.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start with a simple "why", at your next meeting. It goes a long way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 5: Do Effort vs Impact analysis
&lt;/h2&gt;

&lt;p&gt;As a software developer you put effort into solving problems that have various levels of impact. Sometimes you're changing the colour of a button, sometimes you're integrating a fraud detection mechanism into an online payment flow.&lt;/p&gt;

&lt;p&gt;It's important to decide how much time you'll spend planning/working on your task, before you get started on it. &lt;/p&gt;

&lt;p&gt;Changing the color of a button, has comparatively less impact on the user experience, than integrating fraud detection. It is also easily undoable, however undoing an integration from the user journey is not easy. Therefore, spend less time planning and discussing the color, instead push the change and wait for feedback from the customer experience team, to decide how you'll improve. &lt;/p&gt;

&lt;p&gt;However, if you integrate fraud detection without proper planning, you may break existing user experience, face new bugs, and may not even achieve your goal of preventing fraud effectively. In this case, it is worthwhile to test the integration separately, discuss edge cases and spend time building experiments. These experiments maybe throwaway work, but it may save you from costly bugs and frustrated users.&lt;/p&gt;

&lt;p&gt;When my team wanted to integrate a third party fraud detection API, I spent time writing SQL and Node scripts to test the software in an isolated environment. We may never use the code I wrote, but it helped uncover that we were missing some key pieces in our flow required for fraud detection. If we didn't realise this this integration would have been a costly mess.&lt;/p&gt;

&lt;p&gt;When given a problem, before you plan a solution, think of the impact solving it will have on your users. Plan your effort with respect to this impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 6: Take up teaching
&lt;/h2&gt;

&lt;p&gt;It's not only the best way to give back to the community, but also a great way to validate your skills. I've always loved teaching other, so I was fond of teaching others at work. &lt;/p&gt;

&lt;p&gt;Through teaching, I improved how I communicate complex concepts, and when people ask me questions to which I don't have an answer, I'm presented with an opportunity to learn more. Through a cycle of learning and teaching, I improved my React skills rapidly.&lt;/p&gt;

&lt;p&gt;In addition, you also build meaningful connections with your team members, when you play the role of a teacher. You build trust and gain opportunities to collaborate on exciting problems. &lt;/p&gt;

&lt;p&gt;As a teacher you're not only absorbing knowledge but also disseminating knowledge, which helps your team to trust you and eventually gain opportunities to work on exciting and novel problems.&lt;/p&gt;

&lt;p&gt;As a new member in the team, it might seem impossible to start teaching others, but your fresh perspective on the system and the free time you have helps you build knowledge that others might need desperately. Use this opportunity to try to teach something, however simple it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 7: Don't fall into imposter syndrome
&lt;/h2&gt;

&lt;p&gt;The world of software is filled with popular, influential and talented people. I've felt insufficient after seeing developers who own GitHub repos with over 1k stars, write consistently, brag a huge following and rank high on Stack Overflow, while I hadn't answered a single question until &lt;a href="https://stackoverflow.com/users/11984608/mayuran-s"&gt;recently&lt;/a&gt;. I sank into a feeling that everything I know is trivial and I could be easily replaced. I compared myself to people I didn't even know, and felt bad about it. This feeling is referred to as &lt;a href="https://time.com/5312483/how-to-deal-with-impostor-syndrome/"&gt;Imposter Syndrome&lt;/a&gt;. The right way to deal with these feelings is to have better perspective.&lt;/p&gt;

&lt;p&gt;The high performing developers you see online, didn't get there in a day, they worked hard for it. What you need to do is not feel bad about your efforts, but work on improving yourself. You've done a good job so far and you have more to go.&lt;/p&gt;

&lt;p&gt;On that note, remember to take care of your physical and mental health, more often than you take care of career.&lt;/p&gt;




&lt;p&gt;These lessons definitely aren't all the answers to shaping your career, but it should get you started well. In conclusion, your first job (in software) will be filled with challenges and opportunities. Learn to pick and choose wisely, take it easy on yourself when you make mistakes and have fun along the way. &lt;/p&gt;

&lt;p&gt;No one has the right answer to everything, so don't be afraid to try what you like, and create your own identity in the complex world of Software Development.&lt;/p&gt;

&lt;p&gt;If you liked this follow me here and/or on &lt;a href="https://twitter.com/mayuselvaraja"&gt;Twitter&lt;/a&gt; for more of my thoughts on software.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>Part 2: Stashing and Rebasing in Git</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Fri, 20 Mar 2020 12:37:21 +0000</pubDate>
      <link>https://dev.to/maybebored/part-2-stashing-and-rebasing-in-git-4143</link>
      <guid>https://dev.to/maybebored/part-2-stashing-and-rebasing-in-git-4143</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This series assumes the reader is familiar with using the command line and has used basic git commands during development. The series aims to provide examples of using lesser known git commands that improve development experience and reduce friction during collaboration across the team.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Part 1 covered how to set up git for your project, so you can collaborate better. Part 2 is about &lt;code&gt;git stash&lt;/code&gt; and &lt;code&gt;git rebase&lt;/code&gt; - two commands I use regularly when collaborating on tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  git stash
&lt;/h2&gt;




&lt;p&gt;While working in a team, there might be situations where you'd have to temporarily put away your current work, to work on something of higher priority, and &lt;code&gt;git stash&lt;/code&gt; helps you &lt;em&gt;stash&lt;/em&gt; your work away and clear your working directory.&lt;/p&gt;

&lt;p&gt;It helps to understand about the three stages, that your changes are moved to and from in a git repository, before we dive into git stash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxepyz5hzx5ufmptc7gx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxepyz5hzx5ufmptc7gx.png" alt="Diagram of git stages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When you checkout or make new changes they live on the working directory.&lt;/li&gt;
&lt;li&gt;Changes you &lt;code&gt;git add&lt;/code&gt; are moved to a staging area.&lt;/li&gt;
&lt;li&gt;From there when &lt;code&gt;git commit&lt;/code&gt; they are moved to the repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So in between all these stages, &lt;code&gt;git stash&lt;/code&gt; pushes all the changes in the working directory to a special directory called stash.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git stash push [-m &amp;lt;message&amp;gt;]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine a scenario, where you started working on a feature, but you're not nearly ready to commit these changes, and your teammate asks you to work on a different feature branch, because it is of higher priority. &lt;/p&gt;

&lt;p&gt;To start off you'd need to clean your working directory, and save your existing changes somewhere safe.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash push -m "Upgrading version"&lt;/code&gt; does just that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fynij1par0i8lw763ejjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fynij1par0i8lw763ejjl.png" alt="Screenshot of git stash push command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how after running &lt;code&gt;git stash&lt;/code&gt;, the working directory becomes clean, that's because all the changes have been pushed elsewhere. Let's take a look at it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git stash list&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It's what it sounds like, this commands lists down all the changes you stashed. We've stashed one such change. Let's look at where they've been saved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ryz5pfprav9yfkbidml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ryz5pfprav9yfkbidml.png" alt="Screenshot of git stash list command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git stash show&lt;/code&gt; summarises the stashed changes. &lt;code&gt;git stash show -p [&amp;lt;stash&amp;gt;]&lt;/code&gt; shows the exact diff that is stashed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft9mazsgm5yoyi7rzkrb4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft9mazsgm5yoyi7rzkrb4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git stash pop [&amp;lt;stash&amp;gt;]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let's find out how we can retrieve changes from a stash to the working directory. There are two ways to do this: &lt;code&gt;git stash pop&lt;/code&gt; and &lt;code&gt;git stash apply&lt;/code&gt;. &lt;code&gt;pop&lt;/code&gt; removes the stash before applying it, &lt;code&gt;apply&lt;/code&gt; does the same but doesn't remove the change set from the stash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5kho5jwbgakx3b94se0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5kho5jwbgakx3b94se0k.png" alt="Screenshot of git stash pop command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how the stash is empty after popping.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git stash apply [&amp;lt;stash&amp;gt;]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ttr9stktr7ns4gzogox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ttr9stktr7ns4gzogox.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The stash remains the same after using apply.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git stash drop [&amp;lt;stash&amp;gt;]&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Use this command when you want to delete an outdated stash from you list. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;When you want to clear the entire list, use &lt;code&gt;git stash clear&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  pro tips
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;git stash&lt;/code&gt; to temporarily put away your changes when checking out a new branch.&lt;/li&gt;
&lt;li&gt;Ensure your working directory is clean before applying changes from stash.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt; and &lt;code&gt;drop&lt;/code&gt; take an optional &lt;code&gt;&amp;lt;stash&amp;gt;&lt;/code&gt; parameter. If not provided, it defaults to 0, which is the latest stash.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  git rebase
&lt;/h2&gt;




&lt;p&gt;&lt;code&gt;git rebase&lt;/code&gt; applies your commits on top of another branch's tip. A diagram would explain this better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2sxa3dl6pnbvuuhp3a0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2sxa3dl6pnbvuuhp3a0e.png" alt="Diagram explaining what happens in git rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command allows you to be able to move your commits, making this a very powerful command, used for different purposes. Let's look at a few scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conflict free merges
&lt;/h3&gt;

&lt;p&gt;As we saw in &lt;a href="https://dev.to/maybebored/part-1-setting-up-git-5819"&gt;Part 1&lt;/a&gt; of this series, teams that follow git, feature branches are merged onto the Development branch. To avoid conflicts during merge, we try to ensure that the HEAD of your feature branch is on top of the latest commit in the Development branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6k037vmbxg1w6okujv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6k037vmbxg1w6okujv6.png" alt="Screenshot of git log of diverged branches before and after git rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Branch &lt;strong&gt;feature&lt;/strong&gt; and branch &lt;strong&gt;Development&lt;/strong&gt; have one commit each and therefore in git terms, have diverged. By rebasing &lt;strong&gt;feature&lt;/strong&gt; on &lt;strong&gt;Development&lt;/strong&gt;, all the commits of the &lt;strong&gt;feature&lt;/strong&gt; branch will be &lt;em&gt;replayed&lt;/em&gt; on top of the latest commit in the &lt;strong&gt;Development&lt;/strong&gt; branch.&lt;/p&gt;

&lt;p&gt;Notice how after &lt;em&gt;rebasing&lt;/em&gt; the commit hash changes, this is because git creates new commits behind the screen, and stops pointing to the old commits.&lt;/p&gt;

&lt;p&gt;Merging &lt;code&gt;feature_branch&lt;/code&gt; to &lt;code&gt;Development&lt;/code&gt; would now result in a fast-forward merge, which means there will be no conflicts to resolve during the merge. A bit more about &lt;a href="https://www.atlassian.com/git/tutorials/using-branches/git-merge" rel="noopener noreferrer"&gt;Git Merge&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rewriting history
&lt;/h3&gt;

&lt;p&gt;Git Rebase essentially allows for moving commits around. Since git commits are record of history, by moving them around we can indeed &lt;em&gt;rewrite history&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Here's a quick overview of ways you can change history:&lt;/p&gt;

&lt;h4&gt;
  
  
  - &lt;em&gt;Pick&lt;/em&gt; or &lt;em&gt;drop&lt;/em&gt; commits.
&lt;/h4&gt;

&lt;p&gt;You might have accidentally committed some changes. To undo that you can drop it from the history.&lt;/p&gt;

&lt;h4&gt;
  
  
  - &lt;em&gt;Squash&lt;/em&gt; commits together.
&lt;/h4&gt;

&lt;p&gt;Consider a series of commits in which you fixed typos. Consider squashing all of them together to make your history look cleaner.&lt;/p&gt;

&lt;h4&gt;
  
  
  - &lt;em&gt;Edit&lt;/em&gt; or &lt;em&gt;reword&lt;/em&gt; commits.
&lt;/h4&gt;

&lt;p&gt;Everyone loves meaningful and clean commit messages. Reword commits if you think it wouldn't make sense to your reviewer.&lt;/p&gt;

&lt;h3&gt;
  
  
  pro tips
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;git rebase&lt;/code&gt; to sync your feature branch with the branch it will be merged into.&lt;/li&gt;
&lt;li&gt;Interactive rebase (&lt;code&gt;git rebase -i&lt;/code&gt;) requires basic vim usage. Check out this awesome &lt;a href="https://devhints.io/vim" rel="noopener noreferrer"&gt;cheatsheet&lt;/a&gt; to get started.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;In this post, we checked out &lt;code&gt;git stash&lt;/code&gt; and &lt;code&gt;git rebase&lt;/code&gt; and where to use them. Check out the &lt;a href="https://git-scm.com/docs" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; for advanced usage and in some depth information.&lt;/p&gt;

&lt;p&gt;Let me know if you'd like me to continue updating this series, with more commands I run into.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Part 1: Setting Up Git</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Fri, 14 Feb 2020 12:08:16 +0000</pubDate>
      <link>https://dev.to/maybebored/part-1-setting-up-git-5819</link>
      <guid>https://dev.to/maybebored/part-1-setting-up-git-5819</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This series assumes the reader is familiar with using the command line and has used basic git commands during development. The series aims to provide examples of using lesser known git commands that improve development experience and reduce friction during collaboration across the team.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before we dive in, it helps to imagine a scenario in which git is used in a modern development team. A project's original source code is usually stored in a remote server provided by a 3rd party git service such as GitHub. Each team member then forks this repo, clones the fork, to work on their changes and then eventually &lt;em&gt;merge&lt;/em&gt; it back to the original source code via a Pull Request. This is one of the many approaches to using git, called &lt;a href="https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow" rel="noopener noreferrer"&gt;Forking Workflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If that didn't make much sense, don't worry. We will look at each step in detail, using a demo repository and cover some useful commands that will help you collaborate better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Fork the original remote repository
&lt;/h3&gt;

&lt;p&gt;Remote repository refers to repository hosted by GitHub on their server. Note that forking isn't a special git command. All it does is make a copy of the remote repository in your own remote server. Here's an example repository, (wittily named "&lt;a href="https://github.com/octocat/Spoon-Knife" rel="noopener noreferrer"&gt;Spoon-Knife&lt;/a&gt;") you can &lt;em&gt;fork&lt;/em&gt; to see for yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Clone the forked repository
&lt;/h3&gt;

&lt;p&gt;Now that you forked to create your own remote copy of the original repo, you can copy it to your local machine to begin work.&lt;/p&gt;

&lt;p&gt;It's really easy to make a copy of a repository. &lt;code&gt;git clone &amp;lt;repository&amp;gt;&lt;/code&gt;. &lt;code&gt;&amp;lt;repository&amp;gt;&lt;/code&gt; here refers to the location of the repository to copy from. Could be a local file path, or a remote url. In this case you'd be using a remote url like such &lt;em&gt;example&lt;/em&gt;. Try cloning the fork you made in Step 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Do a status check.
&lt;/h3&gt;

&lt;p&gt;Okay you've forked &lt;code&gt;octocat/Spoon-Knife&lt;/code&gt; to your own remote repository, and you've cloned a copy of your remote git repository to your local machine. That's &lt;strong&gt;three&lt;/strong&gt; repositories that must be kept in sync so that individual contributions from the rest of the team doesn't cause issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The original remote repo: octocat/Spoon-Knife (Upstream)&lt;/li&gt;
&lt;li&gt;Your remote repo: /Spoon-Knife (Origin)&lt;/li&gt;
&lt;li&gt;Your local repo /Home/Projects/Spoon-Knife (Local)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Changes are &lt;em&gt;pushed&lt;/em&gt; from &lt;strong&gt;Local&lt;/strong&gt; to &lt;strong&gt;Origin&lt;/strong&gt; and merged from &lt;strong&gt;Origin&lt;/strong&gt; to &lt;strong&gt;Upstream&lt;/strong&gt;. It is possible, that while you are working on your changes, other developers have merged code to Upstream. So it is important you regularly check if Upstream has changes, that you need to synchronise. Sounds complicated, but git makes it really easy to do this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3.1 Track remote repositories
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    git remote &lt;span class="nt"&gt;-v&lt;/span&gt; 
    &lt;span class="c"&gt;# origin https://github.com/maybebored/Spoon-Knife.git (fetch)&lt;/span&gt;
    &lt;span class="c"&gt;# origin https://github.com/maybebored/Spoon-Knife.git (push)&lt;/span&gt;

    git remote add upstream https://github.com/octacat/Spoon-Knife.git 
    &lt;span class="c"&gt;# Set `upstream` to track the original remote repository.&lt;/span&gt;

    git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
    &lt;span class="c"&gt;# origin https://github.com/maybebored/Spoon-Knife.git (fetch)&lt;/span&gt;
    &lt;span class="c"&gt;# origin https://github.com/maybebored/Spoon-Knife.git (push)&lt;/span&gt;
    &lt;span class="c"&gt;# upstream https://github.com/octocat/Spoon-Knife.git (fetch)&lt;/span&gt;
    &lt;span class="c"&gt;# upstream https://github.com/octocat/Spoon-Knife.git (push)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git remote -v&lt;/code&gt; lists all the remote repositories that are being currently tracked. By default it will track, the remote repository from which we cloned, and calls it &lt;code&gt;origin&lt;/code&gt;. This is your server side copy of the original project.&lt;/p&gt;

&lt;p&gt;We add another remote reference to "upstream" with &lt;code&gt;git remote add upstream &amp;lt;upstream&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3.2 Fetch the development/master branch from upstream
&lt;/h3&gt;

&lt;p&gt;Now that we told git the two remote repositories to track, let's fetch a branch from the remote repository and begin work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git repositories contain branches to maintain different versions of the project, where one branch will be the master branch or the original version of the code. Other versions &lt;em&gt;branch&lt;/em&gt; off, from the master &lt;em&gt;branch&lt;/em&gt;. It is common practice to also maintain a &lt;em&gt;development&lt;/em&gt; branch for the version of the code with new changes, so that it can be tested in a test environment, before it is merged to the master branch, to be deployed to a production environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Spoon-Knife" doesn't have a "development" branch, so we will fetch the master branch. Before that run &lt;code&gt;git status&lt;/code&gt; to check the current status of your local repository.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgddnl8hx5rtvogvne0ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgddnl8hx5rtvogvne0ny.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;On branch master&lt;/code&gt; suggests that we are already on the master branch. The local master branch was set to track the remote branch at my server side copy: &lt;code&gt;origin/master&lt;/code&gt; when the repository was cloned and is currently up to date with it. We also see that the &lt;code&gt;working tree is clean&lt;/code&gt; (We will explore what this means soon).&lt;/p&gt;

&lt;p&gt;Other developers will eventually merge their code to the original repository at upstream/master, never to my server side copy of the repository. Therefore, I do not want my local master branch to track my server side copy at origin/master, instead I want it to track the original server side repository upstream/master.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    git fetch upstream master 
    &lt;span class="c"&gt;# From https://github.com/octocat/Spoon-Knife&lt;/span&gt;
    &lt;span class="c"&gt;# * branch            master     -&amp;gt; FETCH_HEAD&lt;/span&gt;
    &lt;span class="c"&gt;# * [new branch]      master     -&amp;gt; upstream/master&lt;/span&gt;

    git branch &lt;span class="nt"&gt;--set-upstream-to&lt;/span&gt; upstream/master
    &lt;span class="c"&gt;# Branch 'master' set up to track remote branch 'master' from 'upstream'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we need to fetch the master branch from upstream using &lt;code&gt;git fetch upstream master&lt;/code&gt; then we need to set our local master branch to track it. &lt;code&gt;git branch --set-upstream-to upstream/master&lt;/code&gt; Now we can fetch changes from upstream to ensure the local branch is synchronised with the upstream branch.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;git status&lt;/code&gt; now shows that local master branch is tracking the original master branch at upstream/master.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdudta8uj516p59up8v1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdudta8uj516p59up8v1z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good! We have successfully set up everything we need to begin working on our feature. Before that, let's recap what we have done so far.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4y60qpnqggmyj46o8aob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4y60qpnqggmyj46o8aob.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We forked octocat/Spoon-Knife to make our own server side copy&lt;/li&gt;
&lt;li&gt;We cloned our server side copy, to make a copy in our local machine.&lt;/li&gt;
&lt;li&gt;We fetched master branch and set its upstream to master branch in the original remote repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the next post, we will explore two more commands (&lt;code&gt;git stash&lt;/code&gt;, &lt;code&gt;git rebase&lt;/code&gt;) that will make fast-paced development a bit less painful.&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How To Use React Error Boundary</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Mon, 09 Sep 2019 16:01:25 +0000</pubDate>
      <link>https://dev.to/maybebored/how-to-use-react-error-boundary-21el</link>
      <guid>https://dev.to/maybebored/how-to-use-react-error-boundary-21el</guid>
      <description>&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;In a previous post, I explained how I came to find out about Error Boundary. In this post let us dive into it a bit more, and understand how React provides a declarative way to catch and handle errors that occur during rendering. Finally, I will show how I used it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarative Error Handling
&lt;/h2&gt;

&lt;p&gt;In a typical JavaScript code, errors can be caught and handled using a &lt;code&gt;try&lt;/code&gt; - &lt;code&gt;catch&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A new error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Caught this error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;em&gt;imperative&lt;/em&gt; code where we tell the program &lt;em&gt;how&lt;/em&gt; to do something, usually in a series of steps. This is not the case when using React, where we tell the program &lt;em&gt;what&lt;/em&gt; to do. &lt;/p&gt;

&lt;p&gt;Let's take a look at code examples, I found &lt;a href="https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2"&gt;elsewhere&lt;/a&gt; of both approaches, for doing the same task of changing a &lt;code&gt;button&lt;/code&gt; element's colour&lt;/p&gt;

&lt;p&gt;Imperative example, where we provide step-by-step instructions to change the change the button colour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React example, where we handle state and return the button element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&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;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&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="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; 
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="na"&gt;btn&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are only telling React &lt;em&gt;what&lt;/em&gt; to return (display) given the current state of the program. Therefore using a &lt;code&gt;try-catch&lt;/code&gt; block while trying to render a component will not &lt;em&gt;catch&lt;/em&gt; errors in the component. React Error Boundary is a declarative approach to error handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I used React Error Boundary
&lt;/h2&gt;

&lt;p&gt;Using Error Boundary helps render a fallback UI, which is better UX than a blank screen, but we can do better. We can reset the state so users can go back to what they saw before the error occurred, without having to reload the page.&lt;/p&gt;

&lt;p&gt;The fallback UI can contain a button, which when clicked, sets the component's state to its initial state, that is &lt;code&gt;{hasError: false}&lt;/code&gt;. But before it does this we must reset the state of the child component that is rendered within the Error Boundary, so that when the app re renders we are not in an &lt;em&gt;erroneous&lt;/em&gt; state. See for yourself below.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/maybebored/embed/OJLvLNq?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With that I conclude my two part series on React Error Boundary. The last bit about resetting state is just something I experimented with, I didn't find anything online that endorses that, so I appreciate any feedback on that.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>ui</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React Error Boundary - An Intro</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Mon, 09 Sep 2019 16:01:11 +0000</pubDate>
      <link>https://dev.to/maybebored/react-error-boundary-an-intro-41lj</link>
      <guid>https://dev.to/maybebored/react-error-boundary-an-intro-41lj</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;My team and I are currently working on an analytics dashboard for a payment gateway at work. We are using ElasticSearch to comb through large amounts of raw data, aggregate that, then provide useful insights, displayed on a beautiful UI built using ReactJS. The application's backend is supported by NodeJS + Express and MongoDB for some data persistence.&lt;/p&gt;

&lt;p&gt;After working on it for ~4 months, I finally got to demo it, to other team mates. It wasn't perfect, but I wanted to show what we have achieved so far. I showed our really fast search feature. I hit enter after typing the search term, expected it to load the results in blazing fast speed, but instead I got a white screen. The entire app had crashed, with no information about what went wrong. This was embarrassing, and I just found out that we hadn't thought of error messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;We have unit tests, code reviews and manual QA testing to prevent the bad stuff like this from happening. BUT, it did. I figured out the root cause using Chrome Dev Tools, and quickly resolved it, but this wasn't enough. What if this happens at a real demo. I needed to do something better.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Why did the app crash?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;In one of the component's &lt;em&gt;render&lt;/em&gt; code I was trying to access a property on an &lt;code&gt;undefined&lt;/code&gt; object. That throws an exception: &lt;code&gt;TypeError&lt;/code&gt;. And if you don't handle this exception, then you get the infamous &lt;code&gt;Uncaught TypeError&lt;/code&gt; in the browser console.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2cau15t2gb0beuqp12p5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2cau15t2gb0beuqp12p5.png" alt="Error Message Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;But, why the did the app &lt;strong&gt;crash&lt;/strong&gt; ?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;To answer this, let's dig into the code a bit more. In the below pen, as you click the button the status updates, but the third time you click it you will see a blank screen, because the app &lt;em&gt;crashes&lt;/em&gt;. Open the pen in &lt;a href="https://codepen.io/maybebored/full/zYORvgO" rel="noopener noreferrer"&gt;full view&lt;/a&gt; and inspect your browser console, and you'll see the error occurred in the &lt;code&gt;BadgeComponent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/maybebored/embed/zYORvgO?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Why would an error that occurred in one child component &lt;em&gt;crash&lt;/em&gt; the entire application? The React Team has an &lt;a href="https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html#new-behavior-for-uncaught-errors" rel="noopener noreferrer"&gt;answer to that&lt;/a&gt; - but in short and quite obviously, leaving a broken UI is bad UX, so it is better to just remove the entire UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Error Boundary
&lt;/h2&gt;

&lt;p&gt;A blank UI with nothing to see is also bad UX, and to answer that React 16 introduces &lt;a href="https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries" rel="noopener noreferrer"&gt;&lt;code&gt;Error Boundary&lt;/code&gt;&lt;/a&gt;. It is essentially a component that is able to handle an error that occurs in a child component, and display/render a fallback UI. There are plenty of great posts online explaining how to use one, but here's a quick pen I made that gracefully handles the error we see in the above pen.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/maybebored/embed/GRKQqVv?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In my next post in this series, I'll talk about how Error Boundary works, and show you what to do after an error has been &lt;em&gt;caught&lt;/em&gt; by the Error Boundary Component.&lt;/p&gt;

</description>
      <category>react</category>
      <category>ui</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to set up a custom domain for your EC2 instance without using Route53</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Thu, 21 Mar 2019 03:11:13 +0000</pubDate>
      <link>https://dev.to/maybebored/how-to-set-up-a-custom-domain-for-your-ec2-instance-without-using-route53-f9</link>
      <guid>https://dev.to/maybebored/how-to-set-up-a-custom-domain-for-your-ec2-instance-without-using-route53-f9</guid>
      <description>&lt;p&gt;In my &lt;a href="//page.prevPostLink"&gt;previous post&lt;/a&gt; I explained how to deploy a simple WordPress site using AWS. This post shows how to set up a custom domain to access your site. The default way to access EC2 instances is by typing its IP address (&lt;em&gt;192.168.0.1&lt;/em&gt;) in a browser. This is great for testing, but when going public with your blog or portfolio website, it makes more sense to have a domain name such as "example.com" instead. You can learn more about &lt;a href="http://bpastudio.csudh.edu/fac/lpress/471/hout/netech/dns.htm" rel="noopener noreferrer"&gt;DNS and IP addresses&lt;/a&gt; outside this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/route53/" rel="noopener noreferrer"&gt;AWS Route53&lt;/a&gt; is a web-based domain resolution service, packed with additional features for reliability and scalability. It's easy to use, flexible and great for beginners. However, this post is intended for those (like me) who do not wish to use Route53.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Set up Elastic IP
&lt;/h3&gt;

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

&lt;p&gt;Navigate to EC2 &amp;gt; Network and Security &amp;gt; Elastic IPs on the AWS Management Console and click on allocate new address.&lt;/p&gt;

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

&lt;p&gt;Click "Allocate" on the next screen. You'll see your newly created Elastic IP after confirming. Select this IP &amp;gt; Actions &amp;gt; Associate Address.&lt;/p&gt;

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

&lt;p&gt;Select your instance from the dropdown and click Associate. You now have an elastic IP address for your EC2 instance. This means you have a static IP that doesn't change even after restarting the instance. This is important to complete our next step.&lt;/p&gt;

&lt;p&gt;Verify that you can see your website by navigating to this elastic IP address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Update your domain's DNS records to point to your elastic IP
&lt;/h3&gt;

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

&lt;p&gt;Create &lt;a href="https://pdrcybersecurity.com/dns-request-types-cheat-sheet/" rel="noopener noreferrer"&gt;type A DNS record&lt;/a&gt; for your domain, which points to your elastic IP. Without an elastic IP,  we'd have to keep updating this record ever time you restart your AWS instance.&lt;/p&gt;

&lt;p&gt;After you create a new DNS record it can take anywhere between 5 minutes to 1 hour, to update. ⏳&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Update EC2 instance's domain settings
&lt;/h3&gt;

&lt;p&gt;Login to your EC2 instance via SSH, then specify your domain name in apps/wordpress/htdocs/wp-config.php file like shown below.&lt;/p&gt;

&lt;p&gt;Replace```define('WP_SITEURL',&lt;br&gt;
&lt;br&gt;
 'http://' . $_SERVER['HTTP_HOST'] . '/');&lt;br&gt;
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;with```define('WP_SITEURL',

 'http://DOMAIN/');
define('WP_HOME', 'http://DOMAIN/');

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

&lt;/div&gt;

&lt;p&gt;And that's about it. You should be able to access your WordPress site at your domain address. 🎉&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let me know what you thought about this article in the comments. I want to improve my writing and help others learn to love tech, the way I did.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ec2</category>
      <category>webdev</category>
      <category>route53</category>
    </item>
    <item>
      <title>Deploy A Wordpress Website using AWS EC2 (The absolute beginner's guide)</title>
      <dc:creator>Mayuran</dc:creator>
      <pubDate>Fri, 15 Mar 2019 12:19:53 +0000</pubDate>
      <link>https://dev.to/maybebored/deploy-a-wordpress-website-using-aws-ec2-the-absolute-beginners-guide-2plf</link>
      <guid>https://dev.to/maybebored/deploy-a-wordpress-website-using-aws-ec2-the-absolute-beginners-guide-2plf</guid>
      <description>&lt;p&gt;WordPress themes are a great because you can set up an elegant website, within minutes, almost effortlessly. Because it abstracts away most of the styling and &lt;strong&gt;all&lt;/strong&gt; of the backend work, WordPress is the go-to solution to put up a website. If you are just getting started in the web development world, this guide is for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Set up your AWS account
&lt;/h3&gt;

&lt;p&gt;AWS offers a &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;free tier&lt;/a&gt; to get free hands-on experience with its services, for new &lt;a href="https://portal.aws.amazon.com/gp/aws/developer/registration/index.html?refid=em_127222" rel="noopener noreferrer"&gt;sign-ups&lt;/a&gt;. The free tier is sufficient for this guide. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Follow this &lt;a href="https://aws.amazon.com/getting-started/tutorials/launch-a-wordpress-website/" rel="noopener noreferrer"&gt;AWS Tutorial&lt;/a&gt; to set up a WordPress website.
&lt;/h3&gt;

&lt;p&gt;This tutorial is well written to guide newcomers. Yet, if it is still confusing (which is okay), leave a comment to get some help. The above guide is only meant for those who want to deploy a mostly &lt;a href="https://www.youtube.com/watch?v=_wFJj94kSTU" rel="noopener noreferrer"&gt;static&lt;/a&gt;, simple, experimental blog. It is &lt;strong&gt;not&lt;/strong&gt; meant for production level solutions.&lt;/p&gt;

&lt;p&gt;AWS EC2 is a virtual server in the cloud, and an Amazon Machine Image (AMI) provides the configuration information to this server so it can host your Wordpress website. When you select "Wordpress powered by Bitnami" and click next you get that done in &lt;em&gt;ONE&lt;/em&gt; click. Ability to launch one-click solutions is one of the many benefits of modern cloud computing.&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%2Fd1.awsstatic.com%2FDigital%2520Marketing%2FHouse%2Fother%2Flaunch-a-wordpress-website%2FLaunch%2520a%2520WordPress%2520Website%2520-%2520AMI.8dcfa97e04c6daaf3b1681f1e509419e9cdce962.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1.awsstatic.com%2FDigital%2520Marketing%2FHouse%2Fother%2Flaunch-a-wordpress-website%2FLaunch%2520a%2520WordPress%2520Website%2520-%2520AMI.8dcfa97e04c6daaf3b1681f1e509419e9cdce962.png" alt="2.1 select ec2 ami"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 (Optional) - Configure your EC2 instance's security configurations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;If you can access your EC2 instance's public IP on your browser, you can ignore this step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security configurations are usually created automatically when you set up your EC2 instance, to protect your virtual server from external attacks. Check your security configurations by selecting your instance and then viewing its associated security group, under the "Description" tab. You should see something like the image below. Then go to your instance's security group, by clicking on it.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj1vhgwhrj6w88ato1nfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj1vhgwhrj6w88ato1nfh.png" alt="3.1 security group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you successfully created your instance but can't access it using your browser, then maybe you haven't allowed any incoming connections to your instance. Edit your security group's inbound rules to allow incoming traffic. These rules describe the type and source of incoming web traffic that is allowed by your instance. The image below shows my rules.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0ouh2pcv6b174rt6cl03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0ouh2pcv6b174rt6cl03.png" alt="3.2 my inbound rules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I allow HTTP and HTTPS traffic from all IP addresses because I'm hosting a website, but I only allow SSH traffic (SSH is used to remotely connect to my server) from my IP. Configuring security rules, is easy and intuitive on AWS Console.&lt;/p&gt;

&lt;p&gt;If you do not have inbound rules that allow HTTP or HTTPS traffic then you cannot view your site using a browser (nor can anyone else). So go ahead and add a rule, choose HTTP/HTTPS for type, and for source, add either your ip address or leave it blank to allow all incoming connections. If you're interested in learning more about security groups in AWS, &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html" rel="noopener noreferrer"&gt;the official documentation&lt;/a&gt; is a good place to start.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyn3wmyla9r7ykxtp67su.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyn3wmyla9r7ykxtp67su.png" alt="3.3 edit inbound rules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go check if you can visit your instance's public IP using a browser. There you go, you just used AWS to deploy a Wordpress Website.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let me know what you thought about this article in the comments. I want to improve my writing and help others learn to love tech, the way I did.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>awsec2</category>
      <category>wordpress</category>
      <category>cloud</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
