<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Coding With Logan]]></title><description><![CDATA[Coding With Logan]]></description><link>https://blog.codinglogan.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 11:33:42 GMT</lastBuildDate><atom:link href="https://blog.codinglogan.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How To Fix Git Refs With Case Sensitivity]]></title><description><![CDATA[Symptoms I Observed On a Mac
Every time I performed a git fetch or a git pull on my MacBook for a particular repository I would see a log from the command that said something like the following.
From github.com:
 * [new branch]      User/feature -> o...]]></description><link>https://blog.codinglogan.dev/how-to-fix-git-refs-with-case-sensitivity</link><guid isPermaLink="true">https://blog.codinglogan.dev/how-to-fix-git-refs-with-case-sensitivity</guid><category><![CDATA[Git]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Thu, 14 Sep 2023 00:08:45 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-symptoms-i-observed-on-a-mac">Symptoms I Observed On a Mac</h2>
<p>Every time I performed a <code>git fetch</code> or a <code>git pull</code> on my MacBook for a particular repository I would see a log from the command that said something like the following.</p>
<pre><code class="lang-bash">From github.com:
 * [new branch]      User/feature -&gt; origin/User/feature
</code></pre>
<p>What I noticed though, that branch was an old and outdated one that nobody was working on.  I came to find out it hadn't been updated for 11 months!  I had been seeing this message from github.com for long enough...  I had to track it down to remove it.</p>
<h2 id="heading-the-fix">The Fix</h2>
<p>Git provides a way to <em>migrate the refs</em> on your local machine to a flat file with case sensitivity, instead of the default directory structure which may be case-insensitive.</p>
<p>Run this command from your repository root:</p>
<pre><code class="lang-bash">git pack-refs --all
</code></pre>
<p>https://git-scm.com/docs/git-pack-refs</p>
<p>Then do a <code>git pull</code> or <code>git fetch</code>, and you'll stop seeing the "new branch" because the ref will use the flat file with the correct case.</p>
<h2 id="heading-the-root-problem-amp-explanation">The Root Problem &amp; Explanation</h2>
<p>Git refs may be stored case-sensitive in one filesystem, but case-insensitive in another.</p>
<p>This can cause some references in git to be incorrect according to your local filesystem.</p>
<p>In my scenario that I observed (every day) the branch was named on the remote using capital letters, <code>User/feature</code>.  To add to the mix there were other branches named lowercase, <code>user/feature2</code>.  So when refs were being stored in my filesystem it would put the branch under whatever one existed first, which happened to be the lowercase one.</p>
<pre><code class="lang-bash">user
  - feature
  - feature2
</code></pre>
<p>Ideally it would store them like this so git can correctly find the ref.</p>
<pre><code class="lang-bash">User
  - feature
user
  - feature2
</code></pre>
<p>When the refs are stored in a flat file the case sensitivity can be preserved, so you won't see the new branch warning anymore.</p>
<h2 id="heading-disclaimer">Disclaimer</h2>
<p>Over time when branches are updated, there's a chance you will have to run the command again, this only affects your local machine's refs.</p>
<p>An alternative approach could be to rename the offending branch on the remote itself.</p>
]]></content:encoded></item><item><title><![CDATA[Learning From Interviews]]></title><description><![CDATA[Want to know what a real coding interview experience is like?  Let me share with you my most recent experience and key takeaways I walked away with.
Summary
The software development industry has a lot of steps to take in its interview process.  Frequ...]]></description><link>https://blog.codinglogan.dev/learning-from-interviews</link><guid isPermaLink="true">https://blog.codinglogan.dev/learning-from-interviews</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 19 Jun 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Want to know what a real coding interview experience is like?  Let me share with you my most recent experience and key takeaways I walked away with.</p>
<h2 id="heading-summary">Summary</h2>
<p>The software development industry has a lot of steps to take in its interview process.  Frequently, you have multiple interview rounds, and a coding challenge of some sort, some of which are live in front of your interviewer(s).</p>
<p>Recently, I was interviewed and had to do a live coding challenge over the web.  I was comfortable, in my own home, yet, I still had some pretty major failures that made it so I wasn't able to show my true colors as a software developer.</p>
<p>I want to go over what happened over the course of the interview, as well as what my takeaways were after some reflection about how it went.</p>
<p>Coding Interview Sections</p>
<ul>
<li><a class="post-section-overview" href="#background">First 5 minutes - Background</a></li>
<li><a class="post-section-overview" href="#coding-challenge">Last 45 minutes - Coding Challenge</a></li>
<li><a class="post-section-overview" href="#takeaway">Takeaways</a></li>
</ul>
<h2 id="heading-background">Background <span id="background"></span></h2>
<p>The first part of the interview was extremely short, and was the easy part.  The interviewer, who was really kind and friendly, asked me to <em>introduce myself and my developer background</em>.  So, I dove right in and explained where I'd come from, what technologies I'd used up to now, and what I was currently working on.  Awesome, things were going alright so far, and I had nothing that was bothering me yet.</p>
<p>Good good...</p>
<p>Then the next question is where I probably could have selected something better.  I was asked to <em>describe a recent project that I'd been working on</em> and I chose a Node.js project that I'd worked on solo a while back to help someone move data from a database to a 3rd party service.</p>
<p>I explained everything that was involved with that project, like how I was able to validate the data moved successfully.  It was a good conversation, yet, I didn't feel good about my choice of project discussion.  The role I was applying for wouldn't really take advantage of the skills I was talking about...</p>
<p>Lesson Learned - When I get asked this question next time, I'll <em>select a project relevant to the role I want</em>.</p>
<h2 id="heading-coding-challenge">Coding Challenge <span id="coding-challenge"></span></h2>
<p><em>...The Coding Challenge...</em></p>
<p>The general format of the coding challenge section of the interview felt pretty good and fair.  It started out with the interviewer explaining the puzzle that was to be solved during the interview.  After the puzzle was explained, I could ask any clarifying questions, and begin to solve the puzzle in whatever way I chose. I was also able to choose one of many different programming language options, which was great.</p>
<p>I began by creating some pseudocode-comments and spoke out loud what my thought process was.  During this portion of the coding challenge, I feel like I actually did "ok" on a first draft attempt at the solution.  I had some data structure usage in mind to help solve it, which I talked through with the interviewer.  We went back and forth a little bit in discussion but agreed it sounded like an OK plan overall.</p>
<p>After feeling like I found something that might work, I began to actually write some code.  Of course, this felt ok right at the start but as I started to dive in I realized I definitely had some weaknesses I didn't realize I had.  Only through this type of interview would I have learned I need to strengthen certain areas.</p>
<p><em>...The Environment...</em></p>
<p>The coding environment was in the browser, and of course, this means it was pretty much a text editor that I was writing code in.  I felt like I was writing code BLIND...  IDEs provide a really good environment to work in, but I've relied on their help to use the various APIs so much that <em>I had to look up the docs frequently in the interview</em>, which thankfully was allowed.</p>
<p>In the real world day to day, I've not had to memorize all the order of parameters of various APIs, but oh man it would have helped me to perform better in the interview.  I'm strongly considering taking some time to specifically <em>code "blind" without the IDEs help</em> so I can find out what APIs I actually know.</p>
<p><em>...Finishing? the Challenge...</em></p>
<p>As the challenge continued, I got down into the depths of the puzzle, started to struggle a little bit, and the interviewer chimed in with helpful hints here and there.  While somewhat helpful, some of the hints actually swayed me away from my initial design that we talked through in the beginning.  Because there were now a few very different designs going into the algorithm I started to really struggle in my solution.  The pieces weren't fitting together how I was hoping, and the answers just weren't coming together.  I really should have kept going with my initial design and thought.  <em>If you are pretty confident in a solution, don't let the interviewer sway your design</em>.</p>
<p>The key here being, the interviewer doesn't know your whole solution.  They might not know you've already got a solution to a piece they haven't thought of, so when the give you a hint, make sure it fits your design and you don't have to implement their idea.</p>
<p><em>...Times Up...</em></p>
<p>Unfortunately, the challenge ended, and I didn't have a working solution in the allotted time.  Of course, this comes with feelings of <em>shame, regret, failure, imposter syndrome, etc</em>.  It's wild how emotion plays into the interviewing experience as a developer, and it really can do a number on your confidence when you fail to show what you can do.</p>
<p>Now, I know <em>I am totally capable of solving many problems</em>, moving data around, integrating 3rd parties, creating reusable components, building web pages and styling for mobile devices etc.  But after the coding puzzle and performance, I don't know if I'd hire me either if I was the interviewer that ran the coding challenge.</p>
<p>As hard as it is to not just feel bad about the whole thing, I knew I needed to take a step back and not let a bad interviews kill my drive.</p>
<p><em>...After Math...</em></p>
<p>After finishing up with the interview, I didn't stop solving the challenge and walk away with it unsolved.  I wasn't about to let some silly puzzle in a timed challenge beat me.  I took some more time and FINISHED the puzzle and wrapped it into a nice little bow to prove to myself that I am absolutely capable of delivering the desired solution.  <em>I specifically allowed my failures to strengthen my weaknesses</em> directly after the interview.</p>
<p>The best part is, for this particular problem, I now know what kind of data structure will support what I needed to solve.  If I run into something similar later I'll be able to remember this as a strengthening moment, not a complete failure.</p>
<h2 id="heading-takeaways">Takeaways <span id="takeaway"></span></h2>
<p>Here's a quick rundown of the key takeaways and tips</p>
<ul>
<li>When asked to give a background, highlight the role's requirements you're interviewing for</li>
<li>Have a project example ready which is <em>directly relevant for the job</em> you're interviewing for</li>
<li>Know your crutches, since live coding typically isn't inside of your own IDE</li>
<li>Be sure to know your APIs, like how to use various string and array APIs without looking things up</li>
<li>Code "blind" to find out what you really know in a language</li>
<li>Freshen up or strengthen your algorithm skills, even if it is only for interviews.  I typically don't have to iterate through strings the same way and unscramble words in my job, but many code challenges will have you doing it.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>These timed coding experiences often feel very different from the real world work that needs to be done.  For example...  In my career I've been building parts of CRM products, back-end office websites, or handling MySQL and Mongo data structures, but all of that hasn't felt anything like the live-coding challenges you get into the interviews.</p>
<p>I learned a lot over the course of this single coding interview.  Some about me, and some more about the interview process in general.  I now know what I need to practice and study in order to perform well in the time-crunched coding experience.</p>
<p>Coding Interviews are the standard it seems for most organizations, so I'll be practicing these types of problems until I feel very comfortable with the process.  In doing so, I hope to open more doors of opportunity for my career and social network as I speak with more brilliant engineers.</p>
]]></content:encoded></item><item><title><![CDATA[The Pragmatic Programmer Is A Great Book]]></title><description><![CDATA[The Pragmatic Programmer is a great resource I just started to read!
Summary
Over the last few days I've started to read the book, The Pragmatic Programmer, and I don't know why I let it sit closed for so long... (Got it back in December)
It's a grea...]]></description><link>https://blog.codinglogan.dev/the-pragmatic-programmer-is-a-great-book</link><guid isPermaLink="true">https://blog.codinglogan.dev/the-pragmatic-programmer-is-a-great-book</guid><category><![CDATA[books]]></category><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 15 May 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>The Pragmatic Programmer is a great resource I just started to read!</p>
<h2 id="heading-summary">Summary</h2>
<p>Over the last few days I've started to read the book, <a target="_blank" href="https://www.amazon.com/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052/ref=pd_lpo_14_t_0/145-1066234-6416535?_encoding=UTF8&amp;pd_rd_i=0135957052&amp;pd_rd_r=1dd1e413-81d5-4bee-b691-831b009571ed&amp;pd_rd_w=fqPGk&amp;pd_rd_wg=toThk&amp;pf_rd_p=a0d6e967-6561-454c-84f8-2ce2c92b79a6&amp;pf_rd_r=8VMW8R34NHAGVJ0Z0V4E&amp;psc=1&amp;refRID=8VMW8R34NHAGVJ0Z0V4E">The Pragmatic Programmer</a>, and I don't know why I let it sit closed for so long... (Got it back in December)</p>
<p>It's a great resource for learning about best practices for software developers, and it's just an overall refreshing read created by those who really care about software.</p>
<p>I'm almost 2 chapters in, and I'm already singing it's praises, I'll give you a taste of what they've mentioned so far, in my own words of course.  Pick up the book if you haven't already, you won't regret it.</p>
<h2 id="heading-care-about-your-software">Care About Your Software</h2>
<p>There are many levels to what this means, but to have a good piece of software that lasts over the tests of time, you'll need to <em>take care of it</em>.</p>
<p>First, start where you are at, and <em>don't cause more harm</em> to your code.  Just because it's faster to copy something "for now", and you've already <em>seen this duplication before</em>, it doesn't mean you should follow suit and add to the problem.</p>
<p>Instead fix the duplication or other problem you're seeing as you run into it.  Or, bare minimum when in a crunch for time, call it out for future developers in a comment so it's flagged as a problem.</p>
<p>The main idea being, be sure to think about your software, critically think about your code, and face those harder choices when you need to.  It will make your project mature in good ways.</p>
<p>Don't neglect your code.  Like bad milk, it will spoil, and be a smelly experience dealing with the mess it causes.  It's better to clean it as you find problems.</p>
<h2 id="heading-easy-to-change">Easy To Change</h2>
<p>Something significant that was mentioned is the idea that a good design typically makes it easier to make changes to the code.  There's a ton that can go into "design", but as an overall concept, this is really great!</p>
<p>The reason I like this so much, is it kind of helps a developer identify when a system might not be designed well, and when to point something out to the team.  If an area of code is hard to change, or unexpected side effects happen because of a change...  It might be time to reconsider the design of that system.</p>
<p>It may even be appropriate to call a meeting together to make sure everyone is aware of the side effects and what problems you're facing.  The result of the meeting may create a better developer experience, and who knows, you might be a hero by saying something.</p>
<h2 id="heading-dry-duplication">DRY Duplication</h2>
<p>Most software developers have heard of this acronym before.  <em>Don't Repeat Yourself</em>!  The idea being, well... don't repeat yourself, right?  Most times this is resolved by creating abstractions in your code so you don't have repeated logic in your codebase.</p>
<p>However, this is not all it is meant to mean.</p>
<p>What the authors brought to light in the first few chapters of this book, is that it's way more than just abstractions into functions and classes.  It is a much broader concept and way of thinking.  Rather, it includes all aspects of duplication.  Code, documentation, data, API interfacing, third party library's providing the same services, etc.  All of these have levels of duplication you need to be aware of it all so you can minimize it.</p>
<p>It isn't just about creating functions and classes.  It's about reducing any level or system of duplication that surrounds your software.</p>
<h2 id="heading-orthogonality">Orthogonality</h2>
<p>This concept really hooked me as I read through it.  It's one of those ideas and systematic thinking I've tried to implement as I code, but it was amazing to read it well defined in a book.</p>
<p><em>The idea of Orthogonality is that a change to one thing, does not affect or change another.</em></p>
<p>If you are able to change an area of code and nowhere else in the system "cares" about that change, it probably means your system is well designed.  On top of that, it's easier to write tests for that code because it is so isolated from the other systems.</p>
<p>So, the tip being, write your code in a way that changes to one feature/system don't cause side effects to other areas of the software.  It remains isolated.</p>
<p>I've been in code bases where this is very much NOT the case, and I've been in others where it is.  Orthogonal systems are so much more rewarding to work in, and the stress you get when making changes is much much lower.  (also, tests are typically written in well designed systems so that's a HUGE bonus)</p>
<p>Push your system designs forward in a way where changes to one area, don't affect another.</p>
<h2 id="heading-reversibility">Reversibility</h2>
<p><em>If a system or library you've relied on suddenly goes away, what will happen to your software?</em></p>
<p>The idea of reversibility is to allow yourself the flexibility to change the underlying implementations to those types of problems.  To do so, you can abstract your usage of those libraries into your own interfaces and APIs.</p>
<p>An example, would be to abstract what kind of database you use.  Right now you might be implementing your code directly with only MySQL, but what if you were required to move to Microsoft SQL next week?  Will your software crumble, or are you flexibly designed to minimize the required change?</p>
<p>These types of considerations need to be taken into account, and in the long run a design with reversibility makes your software more robust.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>There are so many other things they've been sharing in the book, I'm excited to uncover what next.</p>
]]></content:encoded></item><item><title><![CDATA[Chrome Extension Documentation]]></title><description><![CDATA[I spent a few hours building a Chrome Extension this weekend, and I have a few thoughts and/or tips that I've encountered as I learn about this dev environment...
Summary
In the last two weeks (during weekend hours) I've created of very simple Chrome...]]></description><link>https://blog.codinglogan.dev/chrome-extension-documentation</link><guid isPermaLink="true">https://blog.codinglogan.dev/chrome-extension-documentation</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sun, 02 May 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I spent a few hours building a Chrome Extension this weekend, and I have a few thoughts and/or tips that I've encountered as I learn about this dev environment...</p>
<h2 id="heading-summary">Summary</h2>
<p>In the last two weeks (during weekend hours) I've created of very simple Chrome Extension that downloads a CSV file of data on a very specific website page.  It's been fun to have an extension that I built in my browser, but I definitely spent a lot of time in the Chrome Extension docs in order to get things rolling forward.</p>
<p>I wanted to go over <em>a few tips</em> that people should probably be aware of when they dive into creating Chrome Extension.  It's been some trial and error for me to get to where I'm at, and hopefully this will give you a good heads up.</p>
<p>This is a pretty short read, but here's the outline</p>
<ul>
<li><a class="post-section-overview" href="#manifest-version">Manifest Version</a></li>
<li><a class="post-section-overview" href="#online-examples">Online Examples</a></li>
<li><a class="post-section-overview" href="#understand-the-components">Understand The Components</a></li>
</ul>
<h2 id="heading-manifest-version">Manifest Version <span id="manifest-version"></span></h2>
<p>To create the most updated version of a Chrome Extension you should be using <em>Manifest Version 3</em>.  It is the latest version of the manifest, therefore, it wil be the most supported version going forward.  <em>If you can, use this version of the manifest</em>!  It will keep you updated (as of May 2021) and help you avoid the need to migrate too soon after creating your extension.</p>
<p>Start with v3 first.</p>
<p>According to the docs, there are some things that are not in V3, like browser actions, and page actions (sad faces).  Some of these features have been moved to the <em>actions api</em>, but there are also some parts that just don't exist in v3 yet if I understand the docs correctly.</p>
<p>So, if you start in V3, and find you actually need V2, only then, should you actually start in V2 instead.  The only downside here is you'll have to be in an understanding that you'll be migrating up to V3 at some point.</p>
<p>Start in V2 if you can't use V3 for something specific.</p>
<h2 id="heading-online-examples">Online Examples <span id="online-examples"></span></h2>
<p>In my short experience, most examples I've run into online have been for the previous manifest version (2).  Keep this in mind when you are looking to do something specific, and you've been reading up in a tutorial or video made by somebody else.</p>
<p>Keep in mind if you are using V3, you may run into things that won't work for you the way tutorials say they should.</p>
<p>In particular for me, I've been having trouble figuring out how to <em>disable and grey out my extension</em> on specific page.  My understanding is that I can use the <em>chrome.action.disable()</em> (chrome action API), but it doesn't actually grey out the icon...  It does disable my extensions UI from popping up on click, but it doesn't grey out the icon like I expect it to.  It feels like it only does half of what is supposed to happen.</p>
<p>(Maybe I've just totally missed it in the docs, and I understand the docs wrong, but it seems that's when you call disable() it is supposed grey out the icon and prevent the popup from appearing.  If anyone has done this with V3, please share!)</p>
<h2 id="heading-understand-environment-isolation">Understand Environment Isolation <span id="understand-the-components"></span></h2>
<p>I jumped straight in, no mentor, no previous knowledge, ready to make a mess of things :D.  It went something like this:</p>
<ol>
<li>Looked up Chrome Developer Extensions in Google</li>
<li>I wrote some JavaScript that does what I needed, loosely following some examples.</li>
<li>I successfully made the extension do what I wanted and got it to show in the browser (bare minimum viable product)</li>
<li>Used my extension, showed it off to a few people who might also use it, that's always fun to do :) .</li>
<li>I reviewed my code knowing it's in a messy state, since I didn't deep dive into the concepts while making it.  (Like I mentioned, I just dove straight in)</li>
<li>I'm now learning the concepts of the extension ecosystem so I can provide a clean modern extension for myself and my small target user-base.</li>
</ol>
<p>A great place to start is the <a target="_blank" href="https://developer.chrome.com/docs/extensions/mv3/getstarted/">Getting Started</a> directly from Google.</p>
<p>If you breeze through that Getting Started extension example above, it indeed builds you an extension, but it doesn't really solidify the concepts of what is going on.  To understand the concepts you actually need to follow the links, read up more on what is going on, and overall be interested in learning more about how the architecture actually works.  If you follow the additional links you'll have a better chance at building something solid and less thrown together.</p>
<p>In particular, the distinction that <em>execution environments are isolated</em> makes simple enough sense in theory.  But depending on your extension's purpose, you might need to understand it more in depth to accomplish your goals.  The extension's execution environment is separate from the page's execution environment, so you have to plan for that in your design.</p>
<p>For example, my extension really does a very minimal amount of work, but it does need to know about both environments.  Here's what it does.</p>
<ol>
<li>Extension has a <em>download button</em> in its UI that can be clicked</li>
<li>Queries the page's DOM for data in a specific table</li>
<li>Uses the data to create a downloadable CSV for the user's device</li>
</ol>
<p>For each of those steps above, I had to understand where that work was being done before I was able to get it to work correctly.  I changed my code around a few times before I understood it correctly.</p>
<ol>
<li>Extension Environment (download button)</li>
<li>Page Environment (table of data on the page)</li>
<li>Page Environment (use data to create download)</li>
</ol>
<p>In order for my extension to start acting on the page, I had to use script injection.  In particular, when the extension button is clicked, I inject a script into the page that does the rest of the work, on the page.</p>
<p>Extension Environment --&gt; script --&gt; Page Environment</p>
<p><em>TIP</em> - When injecting a script into a page, you can't use functions that are declared in your extension's js file.  They won't be defined when the page environment tries to use them, since the environments are isolated.  You have to inject the functions into the page, as well as the code that uses them.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I've been having fun building an extension, even if it's the only one I ever build.  I use chrome a lot, so it's fun to see my extension icon floating up there next to my staples that I always have!</p>
<p>Anyway, extensions so far feel very different to develop, and I'm still learning about them, but so far, I know to</p>
<ul>
<li>Watch out for the correct manifest version in the docs</li>
<li>Carefully choose examples to follow, keeping manifest version in mind</li>
<li>Pay attention to which environment a piece of code should run</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Generate Files Using JavaScript]]></title><description><![CDATA[Ever wondered how to generate a file's data and download it using JavaScript? I recently used a Blob object and the a tag with the download attribute to accomplish what I needed.
Summary
This will be a very quick post, getting straight to the point. ...]]></description><link>https://blog.codinglogan.dev/generate-files-using-javascript</link><guid isPermaLink="true">https://blog.codinglogan.dev/generate-files-using-javascript</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sun, 25 Apr 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Ever wondered how to generate a file's data and download it using JavaScript? I recently used a <em>Blob object</em> and the <em>a</em> tag with the <em>download</em> attribute to accomplish what I needed.</p>
<h2 id="heading-summary">Summary</h2>
<p>This will be a very quick post, getting straight to the point.  There's not too much fluff to get lost in, so let's just dive right into the code example!</p>
<p>I will show how to</p>
<ul>
<li>Create a Blob from a string (Blobs work well with the download attribute of the a tag)</li>
<li>Create an Object URL for your downloadable blob.</li>
<li>Create an a tag which powers the download</li>
<li>Trigger the download programmatically, (or attach the link to the DOM if you want)</li>
<li>Side note - It's best to release the URL afterward</li>
</ul>
<pre><code class="lang-js"><span class="hljs-comment">// Create the blob (file data) and trigger download:</span>
<span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">new</span> Blob([csv], { <span class="hljs-attr">type</span>: <span class="hljs-string">"text/csv;charset=utf-8;"</span> });
<span class="hljs-keyword">const</span> url = URL.createObjectURL(blob);

<span class="hljs-comment">// This simple recipe uses the &lt;a&gt; tag, ends up something like:</span>
<span class="hljs-comment">// &lt;a href="bloburl" download="filename.csv"&gt;&lt;/a&gt;</span>
<span class="hljs-keyword">const</span> a = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"a"</span>);
a.href = url;
a.download = <span class="hljs-string">"filename.csv"</span>;

<span class="hljs-comment">// Trigger the download</span>
a.click();
</code></pre>
<h2 id="heading-create-a-blob-for-download">Create a Blob for download</h2>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">new</span> Blob([csv], { <span class="hljs-attr">type</span>: <span class="hljs-string">"text/csv;charset=utf-8;"</span> });
</code></pre>
<p>There are a few assumptions about the above snippet</p>
<ol>
<li>You want to generate a CSV file for download</li>
<li>You already have a javascript string formatted into a CSV string. (There are libraries and many other ways to accomplish this, so I will leave this out)</li>
</ol>
<p>You could really create a file of many types, you'll just have to read up a little on your specific case.</p>
<p>If you want to know more about Blobs, the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">mozilla docs about Blobs</a> are the way to read up!</p>
<h2 id="heading-create-an-object-url">Create an Object URL</h2>
<p>This one is in preparation for setting up the <em>download attribute of the a tag</em></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> url = URL.createObjectURL(blob);
</code></pre>
<p>If you want to know more, the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL">mozilla docs about createObjectURL</a> are what I used.</p>
<h2 id="heading-create-the-a-tag">Create the a tag</h2>
<pre><code class="lang-js"><span class="hljs-comment">// This simple recipe uses the &lt;a&gt; tag, ends up something like:</span>
<span class="hljs-comment">// &lt;a href="bloburl" download="filename.csv"&gt;&lt;/a&gt;</span>
<span class="hljs-keyword">const</span> a = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"a"</span>);
a.href = url; <span class="hljs-comment">// It's pointing to our Blob!</span>
a.download = <span class="hljs-string">"filename.csv"</span>;
</code></pre>
<p>Go here to learn more about the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes">download attribute</a></p>
<p>Then, as a final step you can actually download the file (without even attaching the element to the DOM!) using:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Trigger the download</span>
a.click();
</code></pre>
<p>You can optionally attach the tag to the DOM, or manipulate an existing tag that is already on the DOM, etc.  This is just one of your options.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I had to create a simple downloadable CSV template for a work assignment, so I figured I'd share this simple recipe of how to accomplish it.</p>
<p>I will also note, that the Mozilla Docs recommend <em>releasing the Object URL</em> once you are done with it for proper memory management.  I'll leave that to you for further reading.</p>
<p>Anyway, I hope this helps somebody, including myself, in the future when dealing with downloads!</p>
]]></content:encoded></item><item><title><![CDATA[JavaScript And Pokemon Data Scraping]]></title><description><![CDATA[This weekend I had some fun with some light-weight data scraping from popular Pokemon sites.  In this post I'll describe what data I needed and how I scraped it off the sites for my own use.
Summary
I have an upcoming personal project that deals with...]]></description><link>https://blog.codinglogan.dev/javascript-and-pokemon-data-scraping</link><guid isPermaLink="true">https://blog.codinglogan.dev/javascript-and-pokemon-data-scraping</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 10 Apr 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>This weekend I had some fun with some light-weight data scraping from popular Pokemon sites.  In this post I'll describe what data I needed and how I scraped it off the sites for my own use.</p>
<h2 id="heading-summary">Summary</h2>
<p>I have an upcoming personal project that deals with ordering Pokemon in various ways.  Since there are so many Pokemon, I wanted to take some shortcuts to get all the data I needed.  Luckily for me there are many sites out there that already have most of the info I need.  Pokemon has many fans, so a big <em>thanks to all of you data contributors</em> out there!</p>
<p><em>Side Note - There's probably already a spreadsheet, or json file somewhere that has what I need, but I wanted to data-scrape just for fun</em></p>
<p>Now, let's get to what in the world I was doing :D. </p>
<h2 id="heading-decide-on-data">Decide On Data</h2>
<p>Ok data, let's talk data... what do I need in order to complete my project? 🤔</p>
<ul>
<li>A list of Pokemon by national pokedex number</li>
<li>A list of Pokemon by Johto pokedex number</li>
<li>Multiple lists of Pokemon trading card sets</li>
</ul>
<p>So, almost a direct correlation, here are the sites I got info from in my adventure this weekend.</p>
<ul>
<li>pokemondb.net (A list of all Pokemon by national pokedex number)</li>
<li>pokemon.fandom.com (A list of all Pokemon by Johto-dex number)</li>
<li>pokellector.com (Lists of Pokemon card sets, which is a major piece of my project)</li>
</ul>
<p>So, why is this information going to be useful?  For those that aren't familiar, Pokemon are all assigned a unique number for identification, and these number-to-pokemon correlations make up what is called a pokedex.  Basically a dictionary listing them all out.  My project's purpose is to help in ordering pokemon card sets in their pokedex order, so this information will be vital for success.</p>
<p>Alright, so now that we know what data we are after and where we can get some of it, let's go get it!</p>
<h2 id="heading-inspect-the-page">Inspect the page</h2>
<p>I went to <a target="_blank" href="https://pokemondb.net/pokedex/all">pokemondb.net</a> to get the list of all pokemon...  Open that page if you're curious enough to see what the table looks like.  In order to scrape the data with JavaScript I need to know the structure of the page so I can select the appropriate pieces from it, so let's take a look.</p>
<p><em>Inspect the DOM of page</em></p>
<p>Right-click on the table and inspect it.  Here's a snippet of what it looked like.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"pokedex"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cell-num cell-fixed"</span> <span class="hljs-attr">data-sort-value</span>=<span class="hljs-string">"1"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"infocard-cell-img"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> 
                <span class="hljs-attr">class</span>=<span class="hljs-string">"img-fixed icon-pkmn"</span> 
                <span class="hljs-attr">src</span>=<span class="hljs-string">"https://img.pokemondb.net/sprites/sword-shield/icon/bulbasaur.png"</span>
                <span class="hljs-attr">alt</span>=<span class="hljs-string">"Bulbasaur icon"</span>
            &gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"infocard-cell-data"</span>&gt;</span>001<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cell-name"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> 
            <span class="hljs-attr">class</span>=<span class="hljs-string">"ent-name"</span> 
            <span class="hljs-attr">href</span>=<span class="hljs-string">"/pokedex/bulbasaur"</span>
            <span class="hljs-attr">title</span>=<span class="hljs-string">"View Pokedex for #001 Bulbasaur"</span>
        &gt;</span>
            Bulbasaur
        <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    ...
<span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
</code></pre>
<p>I want 2 pieces of information from this table, the name, and the national number.  Using the above inspect information, I can construct various selectors to get it!</p>
<h2 id="heading-run-console-commands">Run console commands</h2>
<p>All of the following code was placed directly into the Chrome Dev Tools, no servers, no Node, or anything else is required.  The only other tool I used was VSCode for writing code before placing it into the console.  (syntax highlighting and proper editing!)</p>
<p>First, let's figure out how to select all the rows of our pokemon.  I ended up constructing something like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">// An array of nodes, each holding a &lt;tr&gt; with a Pokemon's data</span>
<span class="hljs-keyword">const</span> rowNodes = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'table#pokedex tbody tr'</span>)
</code></pre>
<p>Awesome, that's how we get the <em>tr elements</em> that each hold a Pokemon.  The next few pieces of information assume we have a <em>rowNode</em> variable available to us in JavaScript to act on.  Specifically, I looped through the above nodes array in a <em>forEach</em> and used a rowNode variable for the element argument.</p>
<p>Alright we're moving forward, let's get the actual info now.  In order to get the number:</p>
<pre><code class="lang-js"><span class="hljs-comment">// This will select the number text</span>
rowNode.querySelector(<span class="hljs-string">'td:first-child span.infocard-cell-data'</span>)?.innerText
</code></pre>
<p>In order to get the name:</p>
<pre><code class="lang-js"><span class="hljs-comment">// This will select the name text</span>
rowNode.querySelector(<span class="hljs-string">'td:nth-child(2) a'</span>).innerText
</code></pre>
<p>Now you can gather up the Pokemon data into a list using those pieces of data!</p>
<pre><code class="lang-js">pokedex.push({
    name,
    nationalNumber,
});
</code></pre>
<p>Alright, with those pieces explained so you can better understand what's going on, here's my code that grabs the full table, and turns in into <em>console printable json</em>, which I can then copy-paste into a new file and save for my own purposes.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Pokemondb.net/pokedex/all Screen Scrape</span>
<span class="hljs-comment">// returns object of pokemon</span>
<span class="hljs-comment">// optionally print the JSON to console</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">grabPokedex</span>(<span class="hljs-params">printJson = false</span>) </span>{   
    <span class="hljs-keyword">let</span> pokedex = [];
    <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'table#pokedex tbody tr'</span>).forEach(<span class="hljs-function">(<span class="hljs-params">rowNode</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> nationalNumber = rowNode.querySelector(<span class="hljs-string">'td:first-child span.infocard-cell-data'</span>)?.innerText || <span class="hljs-number">0</span>;
        <span class="hljs-keyword">const</span> name = rowNode.querySelector(<span class="hljs-string">'td:nth-child(2) a'</span>).innerText || <span class="hljs-string">""</span>;
        pokedex.push({
            name,
            nationalNumber,
        });
    });

    <span class="hljs-keyword">if</span> ( printJson ) {
        prettyPrint(pokedex)
    }

    <span class="hljs-keyword">return</span> pokedex;
}

<span class="hljs-comment">// Just a bonus for fun</span>
<span class="hljs-comment">// This helps print the whole object to the console</span>
<span class="hljs-comment">// This make it copy friendly</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">prettyPrint</span>(<span class="hljs-params">anyValue</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(anyValue, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>));
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>It was a fun little adventure.  In general for screen scraping, all you need to do is</p>
<ol>
<li>Identify what you need (find the site and page with your info)</li>
<li>Find the structure of the data (inspect the page)</li>
<li>Build JavaScript to select the right pieces of data (then copy paste)</li>
</ol>
<p>I followed a similar process for each site I scraped data from.  Now I have enough information to start compiling it together in the format I actually want it for my project.  If I wanted, I could even drop it straight into a database like Mongo!</p>
<p>For fun, I also made a CSV output of the same data using the same concept.  I just didn't want to bore you with more detail than was needed.</p>
<p>Anyway, hopefully you've got at least an idea of what it might take to do a small amount of screen-scraping if you ever find the need to.  Have fun out there, until next time!</p>
<p>Bonus: It would be more automated to just have it download a file directly, but browser limitations block this behavior without a server doing that work.</p>
]]></content:encoded></item><item><title><![CDATA[Making React Components Testable]]></title><description><![CDATA[Sometimes React components end up being written too complex as requirements change.  When this happens I like to create custom hooks in order to make them easier to understand and test.
Summary
In order to Unit test a React component you need to be a...]]></description><link>https://blog.codinglogan.dev/making-react-components-testable</link><guid isPermaLink="true">https://blog.codinglogan.dev/making-react-components-testable</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Tue, 30 Mar 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Sometimes React components end up being written too complex as requirements change.  When this happens I like to create custom hooks in order to make them easier to understand and test.</p>
<h2 id="heading-summary">Summary</h2>
<p>In order to Unit test a React component you need to be able to control the props and the state that it deals with.  Otherwise, it's really hard to be able to know what to expect in the tests you write.  So how do we deal with components that are too coupled with business logic?</p>
<p>So far in my experience, <em>separating the business logic out into custom hooks</em> allows for better and easier testing, and reusable logic.  In this post I will go over refactoring a React Component by separating out some logic into a custom hook. This enables you to later user that logic elsewhere <em>(avoiding copy pasta)</em>, and to mock that hook for testing the specific parts of the component.  (This post won't go into the actual testing, just getting ready for it)</p>
<h2 id="heading-a-complex-component">A Complex Component</h2>
<p>Take a look at this pseudocode component, it has few things going on</p>
<ul>
<li>Its purpose is to display a list of users</li>
<li>Admins are the only ones who should see other admins</li>
<li>It knows how to grab the users</li>
<li>It gets a permission, applies some logic, and filters the list</li>
</ul>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserList</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// State, holds the user data</span>
    <span class="hljs-comment">// Determine if admins can be shown</span>
    <span class="hljs-keyword">const</span> [users, setUsers] = useState([])
    <span class="hljs-keyword">const</span> [hasAdmin, setHasAdmin] = useState(<span class="hljs-literal">false</span>)
    <span class="hljs-keyword">const</span> [filteredUsers, setFilteredUsers] = useState([])

    <span class="hljs-comment">// Get the users in a useEffect since it is an async task</span>
    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Some async code that grabs the users</span>
        <span class="hljs-comment">// ...code...</span>
        setUsers(newUsersResult)
    }, [])

    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Async call to get the permission</span>
        <span class="hljs-comment">// ...code...</span>
        setHasAdmin(newPermissionValueResult)
    }, [])

    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Admin users can view them all</span>
        <span class="hljs-keyword">if</span> ( hasAdmin ) {
            setFilteredUsers(users)
        }

        <span class="hljs-comment">// Non-admin users get a filtered list</span>
        <span class="hljs-keyword">const</span> nonAdminList = users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> {
            <span class="hljs-keyword">return</span> user.isAdmin ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>
        })
        setFilteredUsers(nonAdminList)
    }, [users, hasAdmin])

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            {
                // Map over all the remaining users so
                // they can be displayed
                filteredUsers.map( (user) =&gt; {
                    return (
                        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                    )
                })
            }
        <span class="hljs-tag">&lt;/&gt;</span></span>
    )
}
</code></pre>
<p>It knows... too much...  Let's make it a little more dumb, and a little less smart. 🙃</p>
<p>Up above you can see that React Component currently has some http fetch type logic directly inside of it, and it handles some business logic for admins.  What I'd like to do is make these pieces of logic exist in a separate hook to keep the component clean and focused on what it should actually be doing, just displaying users.</p>
<p>Again, doing this will allow me to do a few things (I think I've mentioned these before...):</p>
<ul>
<li>Reuse the same hook in other components that need an admin-permissioned list</li>
<li>Test the component by mocking the hook with returned list of Users</li>
</ul>
<h2 id="heading-a-custom-hook">A Custom Hook</h2>
<p>Give a gander at this new organization of the code.  See if you can spot the difference, it's really not too different at all.  I just moved some chunks around.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useAdminRestrictedList</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// State, holds the user data</span>
    <span class="hljs-comment">// Determine if admins can be shown</span>
    <span class="hljs-keyword">const</span> [users, setUsers] = useState([])
    <span class="hljs-keyword">const</span> [hasAdmin, setHasAdmin] = useState(<span class="hljs-literal">false</span>)
    <span class="hljs-keyword">const</span> [filteredUsers, setFilteredUsers] = useState([])

    <span class="hljs-comment">// Get the users in a useEffect since it is an async task</span>
    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Some async code that grabs the users</span>
        <span class="hljs-comment">// ...code...</span>
        setUsers(newUsersResult)
    }, [])

    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Async call to get the permission</span>
        <span class="hljs-comment">// ...code...</span>
        setHasAdmin(newPermissionValueResult)
    }, [])

    useEffect( <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// Admin users can view them all</span>
        <span class="hljs-keyword">if</span> ( hasAdmin ) {
            setFilteredUsers(users)
        }

        <span class="hljs-comment">// Non-admin users get a filtered list</span>
        <span class="hljs-keyword">const</span> nonAdminList = users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> {
            <span class="hljs-keyword">return</span> user.isAdmin ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>
        })
        setFilteredUsers(nonAdminList)
    }, [users, hasAdmin])

    <span class="hljs-keyword">return</span> filteredUsers
}

<span class="hljs-comment">// The UserList now only needs to know one thing...</span>
<span class="hljs-comment">// What hook to call to get the correct list :D</span>
<span class="hljs-comment">// The users will just be displayed</span>
<span class="hljs-comment">// (You could also pass them in as a prop to really</span>
<span class="hljs-comment">// separate that logic out)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserList</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> users = useAdminRestrictedList()

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            {
                // Map over all the remaining users so
                // they can be displayed
                users.map( (user) =&gt; {
                    return (
                        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                    )
                })
            }
        <span class="hljs-tag">&lt;/&gt;</span></span>
    )
}
</code></pre>
<p>See how much dumber the <em>UserList</em> component is now?  It doesn't need to know</p>
<ul>
<li>how to filter the list</li>
<li>it isn't holding onto the full user list</li>
</ul>
<p>It only needs to know the users to show, and now we have that.</p>
<p>This is an extremely simple example, but hopefully you can see how I've separated out the business logic into a hook instead of keeping it within the component.  Now to get a list of users that should be viewable into any React component you only have to call that hook.  (Goodbye copy pasta, we won't miss you)</p>
<p>For example an EditableUserList might render editable fields for the users, not just display their name.  Now you have two components that can share the same hook, and the <em>admins won't show up</em> for users who shouldn't see them.</p>
<h2 id="heading-mock-the-hook-and-test">Mock the Hook and Test</h2>
<p>I'm not going to go over the testing of the component here, but I did want to make it a point of this article that now you can easily test the component.</p>
<p>Having the component separated from the business logic will allow me to test the component's functionality without worrying about the implementation of the hook, by mocking the hook's return value in a test.</p>
<p>To write a test for the component, all I have to do is generate any list of Users and have a mock of the hook return them.  Now I can focus on specifically what my component should be doing with that list.  (and depending on your use case, you could even just have the <em>users passed in via a prop</em> instead.  There are always options to consider)</p>
<p>To write a test for the hook... like most, I'll be looking up what the standard is currently, but there's a library for that no doubt.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I like keeping my components as clean as I can.  Separating logic out in this way is my preference because I can easily look at the component code and decipher what it's actually supposed to do.</p>
<p>My rule of thumb is if I can't glance at the code for under a few minutes and then understand what's being rendered...  There's probably too much logic going on inside of the component.  That's me though, let me know if you feel the same.</p>
<p>Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[Confidence Through Automated Testing]]></title><description><![CDATA[Automated testing provides confidence!
Summary
When I say testing I actually mean automated testing through code in this post.  I don't mean having someone manually clicking around in the application trying to notice any problems.  What I'm talking a...]]></description><link>https://blog.codinglogan.dev/confidence-through-automated-testing</link><guid isPermaLink="true">https://blog.codinglogan.dev/confidence-through-automated-testing</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 27 Mar 2021 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Automated testing provides confidence!</p>
<h2 id="heading-summary">Summary</h2>
<p>When I say <em>testing</em> I actually mean <em>automated testing through code</em> in this post.  I don't mean having someone manually clicking around in the application trying to notice any problems.  What I'm talking about is explicit pieces of code that test the software for exact output.</p>
<p>Here are three questions I'd like to explore</p>
<ul>
<li><a class="post-section-overview" href="#who-benefits">Who benefits from automated testing?</a></li>
<li><a class="post-section-overview" href="#testing-benefits">What benefits do you get from automated testing?</a></li>
<li><a class="post-section-overview" href="#costs">What cost makes automated testing possible?</a></li>
</ul>
<h2 id="heading-who-benefits">Who Benefits <span id="who-benefits"></span></h2>
<p>The benefits of automated testing are "many", and it can benefit many different people.  So, with automated testing in place what individuals actually end up benefiting from it?</p>
<p>The person, organization, or company who owns the software ultimately benefits the most from implementing automated testing since they sit at the highest level.  The goal of this party is to deliver a working product to a paying customer.  Hopefully, a customer who will pay again for the services to keep that revenue stream flowing.  In order to deliver a product that works as expected there are many teams and man-hours involved.</p>
<p>At a very high level (leaving out a lot), these are some of the teams and resources that may be managed by an organization, and <em>all</em> can benefit uniquely from automated testing.</p>
<ul>
<li>Software/Product Design &amp; UX</li>
<li>Developers</li>
<li>Quality Assurance</li>
<li>Data Management</li>
<li>Software Training</li>
<li>General Personnel training</li>
<li>Customer Satisfaction</li>
</ul>
<p>Each of those teams takes ownership of the software at a different lifecycle. They each have to apply their time and effort every single day to meet the demands of the customers.  If each of these groups has to <em>manually validate everything they do</em>, every single day, with every process, scaling into a larger company will become a <em>gigantic hurdle</em>.</p>
<p>Some questions to consider</p>
<ul>
<li>Is it better to hire more people so the company can scale, since there is so much to do?</li>
<li>Should a company require overtime hours on the weekend to make sure things are working?</li>
<li>With each delivery of the product does the whole team have to be <em>on call just in case</em> something goes wrong?</li>
</ul>
<p>The old saying <em>"work smarter, not harder.."</em> really applies to this scenario.  If a company requires more hours, and more effort than a normal workday from its employees, <em>burnout</em> may become a real problem, I've seen it.</p>
<h2 id="heading-testing-benefits">Testing Benefits <span id="testing-benefits"></span></h2>
<p>These are the primary benefits I see with automated testing</p>
<ul>
<li>Confidence</li>
<li>Consistency</li>
<li>Bug Prevention</li>
<li>Clean Code Design</li>
<li>Features can be clearly explained</li>
</ul>
<h3 id="heading-confidence">Confidence</h3>
<p>When software is properly tested you can be confident that the time, money, and other resources spent on it will have been worth it.  The goal after all, is to provide value to the people that use it.</p>
<p>Proper testing provides the confidence that what is said about the application's features is actually what they get.  If they get what was promised from it, they'll be confident in their choice to trust it.</p>
<h3 id="heading-consistency">Consistency</h3>
<p>What does the software do today?  Can it promise that all working features will still work tomorrow when new features are released?</p>
<p>Sometimes features in software are intertwined in the <em>data in the back end, or the UI components of the front</em>, so how can software stay consistent for its users while evolving forward?</p>
<p>With proper tests that cover the functionality that shouldn't be changing, it can deliver a consistent product with confidence, even while features are added.</p>
<h3 id="heading-bug-prevention">Bug Prevention</h3>
<p>Software bugs...  Some are harmless (and even hilarious), but some are devastating.</p>
<ul>
<li>Consider a scenario where a system accidentally charges a customer $10,000 when it was meant to charge $1,000 or $100...  Ouch.</li>
<li>Or another scenario where a bug fix was delivered to production, but another area gets broken unknowingly... (I just thought of this term now, so bear with me, but this could be described as a <em>wormhole bug</em>.  The software went from having a bug in one place, to having one pop up somewhere else.)  In my experience, these are not fun to deal with, as it means code was coupled in a way that wasn't obvious to the developer, and it may need a considerable refactor to fix.</li>
</ul>
<p>If the software is tested thoroughly, the chances of these scenarios happening are <em>considerably less</em>.</p>
<h3 id="heading-clean-code-design">Clean Code Design</h3>
<p>This is an interesting benefit, but is one that I'm most familiar with since I'm in the code daily.  For a software product to be properly tested, it also needs to be designed and written to be <em>test friendly</em>.  I don't want to dive deeply into this topic in this post, but I'll go over some of the main points.</p>
<p>Software can be tested at various levels, and these are some mentioned by <em>Kent C Dodds</em> who has a course about <a target="_blank" href="https://testingjavascript.com/">testing javascript code</a>.  I'm using my own words to describe them.</p>
<ul>
<li>Static: Using editor tools to help the code be clean from the start.  This helps catch the simplest bugs.</li>
<li>Unit: Testing the smallest pieces of code in isolation.  Like testing a single function or class for its expected behavior at the simplest level.</li>
<li>Integration: Testing multiple pieces (Units) of code together as one.</li>
<li>End to End: Testing the app like users would (Just like manually clicking through the application to make sure it is acting correctly)</li>
</ul>
<p>In order to test code at the Unit level, the code must written in a way that it <em>can be tested in isolation</em> from the rest of the code.  For example, if you want to test a function that displays a name a certain way, you don't want to also get the name from the database, render a page, and update records.  You want to have the code's concerns separated enough to <em>do just one thing</em> so you can test just that one thing.</p>
<p>Integration tests would be similar, just at a higher level.  The concerns should be separated enough so the system can test ONLY the feature being worked on.  Maybe it is best to leave out the 3rd party APIs for this kind of test, so the code should be written so it can be tested that way without calling those particular APIs.</p>
<p>A great benefit of having clean code with separated concerns, is a developer will have a better idea of what is happening when reading through it.  Separation of concerns allows the developer to not have to understand the entire system as a whole before they can start making changes and fix that bug.</p>
<h3 id="heading-features-can-be-explained">Features can be explained</h3>
<p>Everyone involved with building or supporting the software should be aware of the feature and what it will do.</p>
<p>The great part about having to write tests, is that a developer <em>has to understand the feature in order to test it</em>.  This means all teams involved from design, to programming, to QA, to customer support, all need to know what's going on so the expectation is clear.</p>
<p>Before developers start on the feature, there should be an explicit expectation about what it should do.  That way a test of the feature can cover exactly that, it <em>runs the software and expects the result</em> of the feature to be what the developer tells it to be.  The clear expectation should have been agreed upon by those requesting the feature.  If it isn't clear more discussions are needed.  If unclear expectations of a feature are given to a developer it will be impossible for them to write a proper test for it (and to build the feature correctly anyway).</p>
<p>The process of writing tests can also help discover unknown scenarios surrounding the feature.  It's likely that Customer Support employees may be questioned about these scenarios.  I've run into plenty of <em>"what if..."</em> questions during development that nobody considered before production started.  After these were found, they could be distributed and discussed to all teams to keep things clear for everyone.</p>
<p>In summary of this section... By discussing feature expectations and writing proper tests, all the teams involved will gain a better understanding of the scenarios that exist inside of the software.</p>
<h2 id="heading-costs">Costs <span id="costs"></span></h2>
<p>Hopefully you've been able to see some of the benefits of testing software, but what are the costs to getting this all going?  Mostly <em>time, education, and money</em></p>
<h3 id="heading-time">Time</h3>
<p>This one is <em>hard to swallow if you're just getting started with testing</em> and already have an application in use.  Sometimes the amount of time it would take to "just fix" a problem would be <em>minutes</em>, but if a test needs to be written in software that's not designed with testing in mind, <em>it could take hours</em> or longer...  So it's obvious that a manager would hesitate to allow the time for testing.  They have other things they need to deliver and get done.</p>
<p>There is not one-size-fits-all answer of how to convince management to allow the time, but I would say the <em>up front time IS costly, but the time NOT SPENT rehashing future issues will make up for it in the long run</em></p>
<h3 id="heading-education">Education</h3>
<p>There are many courses and tons of technologies to learn in order to test your whole application.  You will need to invest in learning, on or off the job, to be able to do it effectively.</p>
<p>Each programming language will have its own tools and libraries for writing tests, so you will have to research what fits best for your software and team.</p>
<h3 id="heading-money">Money</h3>
<p>Some testing may require a whole new infrastructure to support it.  This should definitely be part of the considerations and discussions.</p>
<p>For example, entire testing environments can be set up with databases, APIs, etc, so the entire application can be tested from End to End.  Basically, everything is set up like your production app, but just for testing and keeping data isolated.  (Though, depending on set up, it may only need to run during the tests running time so cost can be minimized)</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Automated Testing...  I feel like the benefits far outweigh the costs!</p>
<ul>
<li>Static Tools: Help me avoid simple mistakes and typos</li>
<li>Unit Tests: give me confidence that I wrote good code</li>
<li>Integration Tests: give confidence that other areas don't break because of my changes</li>
<li>End to End Tests: MORE CONFIDENCE</li>
</ul>
<p>Not all developers write all levels of tests, as I've written mostly Unit Tests.  Sometimes entire teams write Integration and End to End tests, like qualified Quality Assurance Engineers who specialize in it.</p>
<p>I love that when features are properly tested, I (as a developer) don't have to worry about unknowingly breaking something that I didn't intentionally touch.</p>
<p>My suggestions for you...</p>
<p>If you aren't testing your software or application currently, I would urge you to look into how you can get started at any level.  You'll love the confidence it gives you.</p>
<p>If you want to learn more about testing and what it can do, I'd check out <a target="_blank" href="https://testingjavascript.com">testingjavascript.com</a>, and expand your research from there.  Though it is a JavaScript focused page and course he does explain the benefits very well on that site, so read over his reasoning of why testing is great if nothing else.</p>
]]></content:encoded></item><item><title><![CDATA[Developer Retrospective]]></title><description><![CDATA[I've had a lot of ideas lately, in fact, so many that I've been a little overwhelmed with what route I should take next for learning.  I wanted to make a quick post about the things that I have been juggling because it all sounds like a lot of fun!
S...]]></description><link>https://blog.codinglogan.dev/developer-retrospective</link><guid isPermaLink="true">https://blog.codinglogan.dev/developer-retrospective</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 13 Feb 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I've had a lot of ideas lately, in fact, so many that I've been a little overwhelmed with what route I should take next for learning.  I wanted to make a quick post about the things that I have been juggling because it all sounds like a lot of fun!</p>
<h2 id="heading-so-many-ideas">So Many Ideas</h2>
<p>What should we spend our free programming time on?  We only get a finite amount of it, so we shouldn't make the decision too lightly.  But, in my opinion, we should definitely have fun.</p>
<p>I have had many software ideas over the last weeks, but I haven't yet started down the path for any of them...  I am having a hard time deciding what I actually want to focus on, for learning and content to share.  If I start down one path will it be the right one, will I get bored, or will it work out really well and everything will be amazing?  The only way for me to decide what to do is to actually think through what options I have, so, here they are.</p>
<p>One thing I have to keep in mind is that I'll soon be changing jobs, so that weighs heavily into my decision.</p>
<h3 id="heading-idea-1-card-collecting-software">Idea 1 - Card Collecting Software</h3>
<p>Lately, I have been getting back into the hobby of collecting trading cards.  Because I've been so excited about it, that's where my mind space has been.  I've taken a <em>trip down memory lane</em> with Pokemon Cards, and I've been introduced into the current state of the hobby.  While collecting cards there are many things you need to track, manage, and organize if you want to have a well kept collection.</p>
<p>Unfortunately, when figuring out the state of my old cards I spent quite a bit of time putting cards into a binder, taking them back out, and placing them back into the binder again...  I've gone through a few different organizations of my binder because I didn't realize fully what cards were in each set.  <em>I'd love to have a good piece of software that would help me organize it right the first time</em>.</p>
<p>The great thing is, these needs fit naturally with what software can do.  Here are some of the ideas I've juggled in my head, but haven't seen done very well in any tracking system I've tried so far.</p>
<ul>
<li>Advanced Sorting<ul>
<li>Rarity (Rare, Uncommon, Common, etc)</li>
<li>Printing (holographic, reverse holo, normal)</li>
<li>Type (Fire, Water, Grass, etc)</li>
<li>Set (Base, Jungle, Fossil, etc)</li>
</ul>
</li>
<li>Collection Tracking (mark as have when you physically have it)</li>
<li>Estimated Collection Value</li>
<li>Marking cards as "wanted" with a reason</li>
<li>Images</li>
<li>Marking your cards to be a certain condition (and condition explanations)</li>
</ul>
<h3 id="heading-idea-2-2d-game-development">Idea 2 - 2D Game Development</h3>
<p>The reason I actually got into programming was potentially getting into <em>game development</em> some day.  Way back in the day playing <em>StarCraft</em> I built custom maps, and used their <em>trigger system</em> to create special events in the game.  These gave me a taste of what if statements were and how programming worked in simple terms without realizing it was programming at the time.</p>
<p>I thought it was soo cool to imagine an effect of something happening based on a condition, and then to actually see it play out in the game.  Now I have that same desire, but to create my own game entirely rather than a piece of one.</p>
<p>I have already purchased <em>Game Maker Studio 2</em>, followed a few tutorials, and gotten a taste of what it's like to make some 2D games in the software.  And, it feels good!  Who doesn't want to create their own game, that just sounds awesome, right?</p>
<p>The problem?  There's a lot of work involved, but that also means I'll be able gain some very unique skills to games.  Anyway, here's what I'd have to do for games.</p>
<ul>
<li>Design Work</li>
<li>Art</li>
<li>Sounds</li>
<li>Music</li>
<li>Specific Programming Language (Game Maker Language)</li>
<li>Game organization and performance considerations</li>
<li>Other unknowns</li>
</ul>
<p>I'd love to create a game, but there are a LOT of unknowns so I don't know if this should be my primary path or not.  At least, maybe not when I'm hopping into a new job position soon.</p>
<h3 id="heading-idea-3-job-skills">Idea 3 - Job Skills</h3>
<p>Of course, learning is always important for your current job position.  If you're not actively learning new things in your position you may start to feel stale, and it can affect your performance in your assignments.</p>
<p>I will soon be changing jobs, which is exciting!  It also means I'll be changing what I'm using from day to day.  Currently I've been using front end React, css, and HTML pretty much exclusively.  In my new role this will change, and I will be touching all sorts of different technology on the front and back end.</p>
<p>So...  Maybe it's wise for me to wait a few weeks before diving in too deep with either of my hobby paths, and go down the professional path to improve my job performance right from the start.  I love jumping in to new projects and new tech, and sometimes it takes some extra learning before you can really be effective.</p>
<p>I have a track record of being able to jump in and get going quickly, and this would be a great path to accelerate that even more, and would provide these benefits overall.</p>
<ul>
<li>Fast Start to a new job</li>
<li>Practice with <em>new tech</em></li>
<li>Validate my on the job skills</li>
<li>Greater Confidence<ul>
<li>Confidence in myself</li>
<li>Confidence of my Employer in the decision to hire me</li>
</ul>
</li>
<li>Provide value to the company</li>
</ul>
<h2 id="heading-so-little-time">So Little Time</h2>
<p>We all have lives, and every waking hour shouldn't be spent at the computer.  I want to enjoy hobbies, family, friends, and solo time.  The greatest challenge is balancing the time to get what you want out of it, and where to include skill improvement and hobbies like programming.  Here are some pros and cons of where I should spend some of my free time.</p>
<h3 id="heading-prioritize-hobby-software">Prioritize Hobby Software?</h3>
<p>Pros</p>
<ul>
<li>I may be able to enjoy my card collecting even more!  As it's on my mind, this would be an immediate reward for me, the passion for it is already there.</li>
<li>I have multiple friends who might also benefit from it (real testers!)</li>
<li>If I create a game, I can share in the fun with family and friends</li>
<li>I may find strategies in these projects that are useful for my job, while having fun.</li>
<li>My brother is also interested in building games, this could be a way to bond with him AND to gain some new skills.</li>
<li>So much fun to be had!</li>
<li>There is a chance I could learn some hard skills to transfer to my job as well.</li>
</ul>
<p>Cons</p>
<ul>
<li>I might regret not spending more time learning targeted career and job specific skills to perform better in the new position.  When jumping into a project for the first time I've found there are always strategies or new tech to learn and become familiar with.</li>
<li>While working I might find my mind wandering to my hobby projects instead if I dive in too deep.</li>
</ul>
<h3 id="heading-prioritize-professional-skills">Prioritize Professional Skills?</h3>
<p>Pros</p>
<ul>
<li>Better job performance</li>
<li>Less stress when learning the projects</li>
<li>Less post-job-day stress, leisure time will be more rewarding</li>
<li>A hard days work earns a good days leisure</li>
</ul>
<p>Cons</p>
<ul>
<li>Card collection management might be slower</li>
<li>I probably won't get a game created too soon.</li>
</ul>
<h3 id="heading-pro-and-con-summary">Pro and Con Summary</h3>
<p>I've included a sample of my thoughts above, so hopefully you get the idea.  There's a lot to consider when plotting out your time.  There are only a few moments in each day, if any, that can be spent toward personal projects.  I've got to juggle a few younglings, a house, time to spend with my amazing wife, etc, so what should I spend my time on?</p>
<h2 id="heading-which-idea-my-conclusion">Which Idea - My Conclusion</h2>
<p>There are books to read, tutorials to follow, and unlimited amounts of things that can be learned, but what brings the biggest win right now?</p>
<p>Luckily, I've got a few weeks before my new job starts, so in that time I will <em>enjoy my hobbies</em>.  If I can manage it, I'll spend some time making some games, or creating a collection management program.  Most of it depends on how involved I can get my brother in the process of making games.</p>
<p>Either way, I'll focus on the biggest win and reward for me at this time.  Once my new position starts, I'll re-evaluate so that I'll be able to perform at my new job the best that I can, I'm really looking forward to it!</p>
]]></content:encoded></item><item><title><![CDATA[How To Use VSCodes Comparison Feature]]></title><description><![CDATA[It is not uncommon to come across code that looks very similar to other bits of code, but it's hard to pick out exactly what is duplicate and what is actually different.  I want to share how I use VS Code to help me deduplicate my code.
Summary
This ...]]></description><link>https://blog.codinglogan.dev/how-to-use-vscodes-comparison-feature</link><guid isPermaLink="true">https://blog.codinglogan.dev/how-to-use-vscodes-comparison-feature</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 06 Feb 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>It is not uncommon to come across code that looks very similar to other bits of code, but it's hard to pick out exactly what is duplicate and what is actually different.  I want to share how I use VS Code to help me deduplicate my code.</p>
<h2 id="heading-summary">Summary</h2>
<p>This post will have a few short sections.</p>
<ul>
<li><a class="post-section-overview" href="#example-code">Example Code</a> - showing a few similar pieces of code that could be refactored.</li>
<li><a class="post-section-overview" href="#using-vs-codes-compare-feature">Using VS Code's Compare Feature</a> - This helps you visualize what is actually the same in two different snippets of code.</li>
<li><a class="post-section-overview" href="#move-similar-code-to-a-function">Move Similar Code to a Function</a> - This shows the refactored version of the code.</li>
</ul>
<h2 id="heading-example-code">Example Code <span id="example-code"></span></h2>
<p>Here is a snippet of code, note, it hasn't actually been tested or used, but is for an example.  Two main sections, both loading data into elements on the page.  You may notice that the code is essentially doing the same thing in both sections.</p>
<pre><code class="lang-js"><span class="hljs-comment">// loading super nintendo console</span>
<span class="hljs-keyword">const</span> snesData = {
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Super Nintendo Entertainment"</span>,
    <span class="hljs-attr">games</span>: [
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Super Mario World"</span>},
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Donkey Kong Country"</span>},
    ]
}

<span class="hljs-keyword">const</span> snesDescription = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'snes'</span>)
snesDescription.innerText = snesData.description

<span class="hljs-keyword">let</span> snesGamesList = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'ul'</span>)
snesData.games.forEach(<span class="hljs-function">(<span class="hljs-params">game</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> gameElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>)
    gameElement.innerText = game.title
    snesGamesList.appendChild(gameElement)
})
<span class="hljs-keyword">const</span> snesGames = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'snesGames'</span>)
snesGames.innerHTML = snesGamesList.toString()


<span class="hljs-comment">// loading nintendo 64</span>
<span class="hljs-keyword">const</span> n64Data = {
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Nintendo 64"</span>,
    <span class="hljs-attr">games</span>: [
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Super Mario 64"</span>},
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Donkey Kong 64"</span>},
    ]
}

<span class="hljs-keyword">const</span> n64Description = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'n64'</span>)
n64Description.innerText = n64Data.description

<span class="hljs-keyword">let</span> n64GamesList = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'ul'</span>)
n64Data.games.forEach(<span class="hljs-function">(<span class="hljs-params">game</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> gameElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>)
    gameElement.innerText = game.title
    n64GamesList.appendChild(gameElement)
})
<span class="hljs-keyword">const</span> n64Games = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'n64Games'</span>)
n64Games.innerHTML = n64GamesList.toString()
</code></pre>
<h2 id="heading-using-vs-codes-compare-feature">Using VS Code's Compare Feature <span id="using-vs-codes-compare-feature"></span></h2>
<p>It would be nice to visually see what exactly is different between the two sections, and VS Code provides such a feature.</p>
<p>In order to use the feature, do the following</p>
<ol>
<li>Copy the text of the first section into a new file (you don't have to save it)</li>
<li>Copy the text of the second sections into a new file as well</li>
<li>In the top left of VS Code, you can see your Open Editors (files).  You will see your two unsaved documents listed there.</li>
<li>Right click one of them, and select <em>Select for Compare</em></li>
<li>Right click the other one, and select <em>Compare with Selected</em></li>
<li>A new two-paned editor will open showing you the changes between the two files.</li>
</ol>
<p><img src="/images/fileCompare.PNG" alt="A two paned window showing differences of text between the two" /></p>
<p>You can see in the image above, that it highlights the words and lines that are different between the two.  Using that information as a hint for yourself, you can then refactor both sections of code in a way that you see fit.</p>
<p>This is a very simple example, where a lot of the lines are similar.  In other <em>real world</em> scenarios it might not be quite as obvious, and there may be extra lines in the left file that don't exist in the right and vice versa.  The idea behind the feature and this strategy is to be able to quickly observe the differences without painstakingly reading each line of both sections.</p>
<h2 id="heading-move-similar-code-to-a-function">Move Similar Code to a Function <span id="move-similar-code-to-a-function"></span></h2>
<p>For my code above, I'm able to refactor it to this based on the hints in the two panes.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> snesData = {
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Super Nintendo Entertainment"</span>,
    <span class="hljs-attr">games</span>: [
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Super Mario World"</span>},
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Donkey Kong Country"</span>},
    ]
}

<span class="hljs-keyword">const</span> n64Data = {
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Nintendo 64"</span>,
    <span class="hljs-attr">games</span>: [
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Super Mario 64"</span>},
        {<span class="hljs-attr">title</span>: <span class="hljs-string">"Donkey Kong 64"</span>},
    ]
}

updateConsoleInformation(<span class="hljs-string">'snes'</span>, <span class="hljs-string">'snesGames'</span>, snesData)
updateConsoleInformation(<span class="hljs-string">'n64'</span>, <span class="hljs-string">'n64Games'</span>, n64Data)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateConsoleInformation</span>(<span class="hljs-params">consoleId, gamesId, consoleData</span>) </span>{
    <span class="hljs-keyword">const</span> descriptionElement = <span class="hljs-built_in">document</span>.getElementById(consoleId)
    descriptionElement.innerText = consoleData.description

    <span class="hljs-keyword">let</span> gamesList = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'ul'</span>)
    consoleData.games.forEach(<span class="hljs-function">(<span class="hljs-params">game</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> gameElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>)
        gameElement.innerText = game.title
        gamesList.appendChild(gameElement)
    })
    <span class="hljs-keyword">const</span> gamesElement = <span class="hljs-built_in">document</span>.getElementById(gamesId)
    gamesElement.innerHTML = gamesList.toString()
}
</code></pre>
<p>You can see in the above snippet, that I was able to entirely eliminate a section of DOM related code.  The hints provided in the two-paned comparison show that most of the code was actually duplicate, but just different variable names, ids, and data.  So, I threw those differences into a function via the parameters.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>When you see a few pieces of code that look fairly similar, and you want to know at a glance what actually is duplicate, give VS Codes <em>compare feature</em> a try.</p>
]]></content:encoded></item><item><title><![CDATA[Thoughts On Duplicate Code]]></title><description><![CDATA[A lot of time over the course of my career has been spent de-duplicating code.  I want to go over a few different kinds of duplication that I've seen.  Many approaches can be taken to reduce duplication, and it's helpful to know what kinds of duplica...]]></description><link>https://blog.codinglogan.dev/thoughts-on-duplicate-code</link><guid isPermaLink="true">https://blog.codinglogan.dev/thoughts-on-duplicate-code</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Mon, 25 Jan 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>A lot of time over the course of my career has been spent de-duplicating code.  I want to go over a few different kinds of duplication that I've seen.  Many approaches can be taken to reduce duplication, and it's helpful to know what kinds of duplication you may run into.</p>
<p> </p>
<h2 id="heading-summary">Summary</h2>
<p><a class="post-section-overview" href="#duplicate-lines">Duplicate Lines</a></p>
<p><a class="post-section-overview" href="#duplicate-functions">Duplicate Functions</a></p>
<p><a class="post-section-overview" href="#duplicate-modules">Duplicate Modules</a></p>
<p> </p>
<h2 id="heading-duplicate-lines">Duplicate Lines <span id="duplicate-lines"></span></h2>
<p>The most frequent kind of duplication that I've seen is lines of code within the same file.  More often than not, they aren't quite "duplicated", but they are changed just ever so slightly from each other.</p>
<p>Take this as an example, where we want to disable a few buttons, and the only difference is the ID being used in the selector.  Everything else is the same, repeating the document.getElementById multiple times along with other logic that looks repeated.</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'bigButton'</span>)
    .disabled = <span class="hljs-literal">true</span>
<span class="hljs-comment">// other duplicated logic</span>

<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'medButton'</span>)
    .disabled = <span class="hljs-literal">true</span>
<span class="hljs-comment">// other duplicated logic</span>

<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'smallButton'</span>)
    .disabled = <span class="hljs-literal">true</span>
<span class="hljs-comment">// other duplicated logic</span>
</code></pre>
<p>When I see code that looks similar like this my first approach is to create a reusable function to simplify the file.  It makes it look more like this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButton</span>(<span class="hljs-params">id</span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(id)
        .disabled = <span class="hljs-literal">true</span>
    <span class="hljs-comment">// other duplicated logic</span>
}

disableButton(<span class="hljs-string">'bigButton'</span>)
disableButton(<span class="hljs-string">'medButton'</span>)
disableButton(<span class="hljs-string">'smallButton'</span>)
</code></pre>
<p>Now there's no need to re-read through all that logic multiple times each time you have to edit the page.  You can read the function, and then just read where it's used.</p>
<p>Now, there are multiple ways you could handle this code, it all comes to preference and need.</p>
<ul>
<li>As a first step, you can always find and keep the similar logic, put it in the function, and add parameters for the parts that change.</li>
<li><p>Since the logic that's going on is exactly the same, you could even have the parameter be <em>an array of ids</em> to operate on and create a loop in the function instead of calling the function multiple times.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButtons</span>(<span class="hljs-params">ids</span>) </span>{
  ids.forEach(<span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> {
      <span class="hljs-built_in">document</span>.querySelector(id).disabled = <span class="hljs-literal">true</span>
      <span class="hljs-comment">// Other duplicate logic</span>
  })
}
disableButtons([
  <span class="hljs-string">'bigButton'</span>,
  <span class="hljs-string">'medButton'</span>,
  <span class="hljs-string">'smallButton'</span>
])
</code></pre>
</li>
<li><p>You could use querySelectorAll to get a list of Nodes you can iterate through to disable.</p>
</li>
<li>etc.</li>
</ul>
<p>A lof of the decision just depends on your specific application, but personally, I feel that de-duplicating lines in at least one way is always worth it for readability, and maintenance reasons.</p>
<p> </p>
<h2 id="heading-duplicate-functions">Duplicate Functions <span id="duplicate-functions"></span></h2>
<p>Sometimes when you are reading through code, and writing some of your own, you'll find that there are multiple functions doing the exact same thing, but they are declared in different places and named slightly different.  The problem comes in when both are actually used in various places.</p>
<p>Following our example above, lets say we have two functions that are disabling buttons and running some other code, that take the string id as a parameter.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButtonById</span>(<span class="hljs-params">id</span>) </span>{
    ...
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButton</span>(<span class="hljs-params">id</span>) </span>{
    ...
}
</code></pre>
<p>Having two functions like this will just be confusing for a developer to maintain.  If I encounter this situation I have multiple questions going through my mind</p>
<ul>
<li>Which one is most current?</li>
<li>Which one should I use?</li>
<li>Are both of these used?</li>
<li>Why is one better than the other?</li>
<li>etc.</li>
</ul>
<p>To reduce duplication you'll have to deprecate one, and choose to use the other one.  One strategy I've used to resolve this is to <em>function wrap</em> one within the other and then mark the deprecated one as <em>deprecated</em>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This is more descriptive, let's keep this</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButtonById</span>(<span class="hljs-params">id</span>) </span>{
    ...
}

<span class="hljs-comment">/**
* <span class="hljs-doctag">@deprecated </span>- use disableButtonById
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">disableButton</span>(<span class="hljs-params">id</span>) </span>{
    <span class="hljs-comment">// Remove all previous code and call</span>
    <span class="hljs-comment">// the function you want to keep.</span>
    <span class="hljs-comment">// Once you've tested that this doesn't</span>
    <span class="hljs-comment">// break anything of course</span>
    disableButtonById(id)
}
</code></pre>
<p>With this strategy, you can take an incremental approach to removing the usage of the old function.  If it's simple enough you could just remove the one and keep the other without the deprecation and function wrapping, but sometimes the scope of your task just doesn't allow you to do it all at once.  Or, the usage of the function is a public API so just removing it would be dangerous for your users.</p>
<p>You'll need to take care to test all areas as you deprecate it's usage, and then plan to chop the function out of your code in a future version when all code has been moved to the direct usage of the <em>chosen one</em>.</p>
<p> </p>
<h2 id="heading-duplicate-modules">Duplicate Modules <span id="duplicate-modules"></span></h2>
<p>With this one, I don't mean two of the same module, but rather two modules that solve the same problem.  It's very possible that you could remove one and not the other.</p>
<p>This one is a little more tricky to handle, and it will come down to coordination with your team.  Sometimes people prefer certain packages, but to reduce your code's bloat, you'll need to come to a decision of what to keep, and why.</p>
<ul>
<li>Is it worth cutting one of the modules that solve the same problem, or do they have unique situations that it's worth keeping both?</li>
<li>Is the module size worth fighting over?</li>
<li>Is it just a dev dependency, or is it bloating up your production application?</li>
</ul>
<p>The main point here is, communicate what duplication you see and question the choices that have been made if you're not sure.  You might end up reducing your code when you do.  Chances are, <em>no one knows why it is included</em> if you are in an older code base, so questioning it will lift the whole team up.</p>
<p> </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I went over Line Duplication, Function Duplication, and Module Duplication, and some strategies I've been involved with for resolving them.</p>
<p>I love when I can clean up some code, and most often, it's all about reducing duplication, get out there and have fun reducing your code!</p>
]]></content:encoded></item><item><title><![CDATA[Getting It Into GitHub]]></title><description><![CDATA[GitHub is an amazing tool, and there are a few situations you can be in when looking to set up a repository in it.  You might have already started a code project locally, or you can create a repository in GitHub before you write any code.  I want to ...]]></description><link>https://blog.codinglogan.dev/getting-it-into-github</link><guid isPermaLink="true">https://blog.codinglogan.dev/getting-it-into-github</guid><category><![CDATA[Git]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Sat, 16 Jan 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>GitHub is an amazing tool, and there are a few situations you can be in when looking to set up a repository in it.  You might have already started a code project locally, or you can create a repository in GitHub before you write any code.  I want to make a quick post about dealing with both of those situations.</p>
<h2 id="heading-before-code-has-been-written">Before code has been written</h2>
<p>If you already know you will want to put a new project in GitHub, creating the repository from GitHub itself is very easy.  All you'll have to do afterward is clone the project from GitHub onto your device, and then you can code locally and push your changes to GitHub in the cloud.</p>
<ol>
<li>Navigate to <a target="_blank" href="https://www.github.com">GitHub</a> and sign in.</li>
<li>Create a new repository.  At the time of writing there is a <em>+</em> symbol you can click on the top right, and choose <em>New Repository</em></li>
<li>Provide a new repository name that will identify your project</li>
<li>Choose public or private depending on your preference</li>
<li>I'd recommend adding a README file, unless you know for some reason it will cause you issues. Check the box to create the repository with a file.  Eventually this file should describe your project, how to get set up, and any meaningful notes about your project.</li>
<li>Finally, click <em>Create Repository</em></li>
</ol>
<p>Now GitHub has a git repository ready for you to start working in, you just have to get it locally on your machine.  You do this using the <em>git clone</em> command.  You should have been taken to a page that shows your new git repository's information.  What you need to find is your git repository address.  You can find it in a few ways</p>
<ul>
<li>Address Bar of Browser: use the URL of the page, and add <em>.git</em> to the end</li>
<li>Look for a <em>Green Code Button</em> (at the time of writing): clicking on it should reveal your repository address, with <em>.git</em> already added to the end of the URL, copy that to your clipboard.</li>
</ul>
<p>The address you find will look something like <em>https://github.com/codingLogan/temp-test.git</em>  Using that address, you can now <em>git clone</em> your repository to your local machine.</p>
<ol>
<li>Open a terminal and navigate to a folder that you'd like your project to exist in.</li>
<li>Run the following git clone command<pre><code>git clone &lt;address-<span class="hljs-keyword">of</span>-git-repository&gt;
</code></pre></li>
</ol>
<p>For me it would look like this</p>
<pre><code>git clone https:<span class="hljs-comment">//github.com/codingLogan/temp-test.git</span>
</code></pre><ol>
<li>You should now have a folder named the same as your repository.</li>
</ol>
<p>You can open up that folder and begin coding as you would normally, making commits, branches etc, using <em>git</em>.  The only difference now, is you can use <em>git push</em> to get your local changes of your current branch up to GitHub.</p>
<h2 id="heading-after-code-has-been-written">After code has been written</h2>
<p>In this situation you've already been coding locally and you have a set of files you want to get into GitHub.  To get this project into GitHub, you just have to be sure it's being tracked locally by git, and also create a repository on GitHub to push to.</p>
<p>(Pre-requisite) If it hasn't been done already, you need to be tracking your files in a git repository locally before you can push them to GitHub.  Navigate in the terminal to the root of your project and run these commands.</p>
<pre><code>git init
git add .
git commit -m <span class="hljs-string">"First commit"</span>
</code></pre><p>Now your files are ready to be pushed to GitHub, so let's set up a repository for GitHub to track it.</p>
<ol>
<li>Navigate to <a target="_blank" href="https://www.github.com">GitHub</a> and sign in.</li>
<li>Create a new repository.  At the time of writing there is a <em>+</em> symbol you can click on the top right, and choose <em>New Repository</em></li>
<li>Provide a new repository name that will identify your project</li>
<li>Choose public or private depending on your preference</li>
<li>(important) Be sure to <em>NOT ADD ANY FILES</em> when creating the repository on GitHub.  You'll run into conflicts with your local files if you do</li>
<li>Finally, click <em>Create Repository</em></li>
</ol>
<p>Situation Review</p>
<ul>
<li>You have a <em>blank repository</em> on GitHub</li>
<li>You have a local git project you want to push to GitHub</li>
</ul>
<p>To push your project up into GitHub, use these commands, which are actually provided to you on the GitHub website as well.  This will connect your local project with your remote repository in the cloud.  (It also renames your current branch to main and then pushes up the branch named <em>main</em> to GitHub)</p>
<pre><code>git remote add origin &lt;address-<span class="hljs-keyword">of</span>-git-repository&gt;
git branch -M main
git push -u origin main
</code></pre><p>Now, you can continue editing your files, making commits, new branches, and then use <em>git push</em> to put your changes into the cloud.</p>
<h2 id="heading-summary">Summary</h2>
<p>I showed two scenarios which you may be in, and how to set up GitHub for them.</p>
<p>Before project code has been written</p>
<ul>
<li>Set up GitHub first (create at least a README.md)</li>
<li>Clone that repository locally and start working</li>
</ul>
<p>After project code has been written</p>
<ul>
<li>Start tracking your project locally with git</li>
<li>Set up GitHub with a blank repository</li>
<li>Push your project up to the blank repository</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How To Lift State Up In React]]></title><description><![CDATA[In React you will eventually find a need to share state between components.  Here is one example of how you can share state between two components that share a common parent.
Overview
Here are the sections of this article
End Goal
The Component Tree
...]]></description><link>https://blog.codinglogan.dev/how-to-lift-state-up-in-react</link><guid isPermaLink="true">https://blog.codinglogan.dev/how-to-lift-state-up-in-react</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Tue, 05 Jan 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>In React you will eventually find a need to share state between components.  Here is one example of how you can share state between two components that share a common parent.</p>
<h2 id="heading-overview">Overview</h2>
<p>Here are the sections of this article</p>
<p><a class="post-section-overview" href="#end-goal">End Goal</a></p>
<p><a class="post-section-overview" href="#the-component-tree">The Component Tree</a></p>
<p><a class="post-section-overview" href="#lift-state-up">Lift State Up</a></p>
<h2 id="heading-end-goal">End Goal <span id="end-goal"></span></h2>
<p>The goal of this post is to show how you can <em>communicate between two different depth child components</em>.  I want an event fired by one child component to trigger a specific action on the other child.  One way to do this is to create some form of state in the <em>parent component</em> that both children can access via their props.</p>
<p>I'm using this pattern to create a set of controls that are always visible to the user (up, down, left, right, accept, and decline buttons), but depending on the current Screen and the currently active item on that screen, those actions can behave differently.</p>
<p>For clarity, in a recent project I'm emulating a old school GameBoy interface, which is pretty unique, but I'll try to expose the fundamentals of the pattern in this post so it is useful for all cases.</p>
<h2 id="heading-the-component-tree">The component tree <span id="the-component-tree"></span></h2>
<p>Let's assume we have a component tree that looks like this</p>
<pre><code>[Parent component]
  |           |
[Controls]  [other children]
              |
             [Screen]
</code></pre><p>Components</p>
<ul>
<li>Parent: Holds the <em>state</em> of what items are available for navigation, and creates a handler function to pass down to children so items can be interacted with.</li>
<li>Controls: Child of Parent who's specific purpose is to fire an action.  The example I'd like to use in this post is firing a "move down" event when a button is clicked.</li>
<li>Screen: Creates the items you can interact with, and renders them.</li>
</ul>
<h3 id="heading-example-event-desires">Example event desires</h3>
<p>Ok, so lets think through what we want to happen.  On my Screen, I want to have a "currently selected item", and when the down button is pressed on the Controls, the active menu item should move to the next available item if it can.</p>
<p>Visually...</p>
<pre><code>first menu item &lt;-- active
second menu item
</code></pre><p>Pressing down</p>
<pre><code>first menu item
second menu item &lt;-- active
</code></pre><p>Ok, looking at the two components we want to interact, we have these two specific things we want to happen, but they aren't hook up to work together yet.</p>
<ol>
<li>Controls component fires "down" event</li>
<li>Screen should create a list of items to interact with and render them, and re-render them when the active item changes</li>
</ol>
<h2 id="heading-lift-state-up">Lift state up <span id="lift-state-up"></span></h2>
<p>Let's play matchmaker and get these two components "hooked up".  To do that we will use the <em>lift state up</em> strategy.  These components need to interact with a common piece of <em>state</em> that we'll place <em>into the parent component</em>.</p>
<h3 id="heading-parent">Parent</h3>
<p>On the parent we are going to do two things.</p>
<ol>
<li>Set a piece of state in Parent called "navItems", and we'll pass this state as a props to Screen</li>
<li>Create a downHandler function that we'll pass to Controls as a prop so it can fire the event</li>
</ol>
<p><em>navItems</em>: Object containing the list of items you can navigate through, and the currently active item's index.</p>
<p><em>downHandler function</em>: This function will be called by Controls to signify the "down action" has taken place.  The <em>items state</em> will be used in the function to determine what the effect of that action should be.</p>
<p>Code snippet for Parent</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [items, setItems] = useState({ <span class="hljs-attr">activeIndex</span>: <span class="hljs-literal">null</span>, <span class="hljs-attr">items</span>: [] });

<span class="hljs-keyword">const</span> downHandler = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (navItems.activeIndex &lt; navItems.items.length - <span class="hljs-number">1</span>) {
        setNavItems({
            <span class="hljs-attr">items</span>: navItems.items,
            <span class="hljs-attr">activeIndex</span>: navItems.activeIndex + <span class="hljs-number">1</span>,
        });
    }
};
</code></pre>
<p>Parent markup snippet</p>
<pre><code class="lang-js">&lt;Controls
    downHandler={downHandler}
/&gt;
</code></pre>
<p>Notice, we are not actually setting the items to anything but an empty array.  It will be up to the Screen to do that.  All we are doing in the function is changing the active index to be the next one in the list if we can.</p>
<h3 id="heading-controls">Controls</h3>
<p>Use the handler function (which should be passed as a prop) from Parent in your markup.  This will make Controls call the function that is defined Parent.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Controls</span>(<span class="hljs-params">{downHandler}</span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{downHandler}</span>&gt;</span>Down<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    )
}
</code></pre>
<h3 id="heading-screen">Screen</h3>
<p>Ok then, Screen needs to set the items that are available, while also accepting the items from the parent so it knows which one is active.</p>
<p>(side note - As I am writing this I'm realizing that the Screen component probably only needs the index information passed to it from the parent, not all the items, I'll play with that later)</p>
<p>Here's a snippet of the setup for Screen</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ScreenContent</span>(<span class="hljs-params">{ navItems, setNavItems }</span>) </span>{

    <span class="hljs-comment">// Define the items that should appear on the screen</span>
    <span class="hljs-keyword">const</span> initialItems = [
        {
            <span class="hljs-attr">text</span>: <span class="hljs-string">"View Games"</span>,
        },
        {
            <span class="hljs-attr">text</span>: <span class="hljs-string">"Borrowers"</span>,
        },
    ];

    <span class="hljs-comment">// Only on FIRST RENDER, set the initialItems on the Parent</span>
    useEffect(<span class="hljs-function">() =&gt;</span> {
        setNavItems({
            <span class="hljs-attr">activeIndex</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">items</span>: initialItems,
        });
    }, []); <span class="hljs-comment">// This empty array signifies the "first render only"</span>

    <span class="hljs-comment">// Render the list of items</span>
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            {navItems.items.map((item, index) =&gt; (
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{navItems.activeIndex</span> === <span class="hljs-string">index</span> ? "<span class="hljs-attr">active_item</span>" <span class="hljs-attr">:</span> ""}&gt;</span>
                    {item.text}
                <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            ))}
        <span class="hljs-tag">&lt;/&gt;</span></span>
    );
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>And there you have it.  You have two separate children of Parent talking to the same data through their parent.</p>
<p>We set up a Parent component with</p>
<ul>
<li>a handler function to pass down to children</li>
<li>a piece of application state, that the handler uses, and the other child component consumes.</li>
</ul>
<p>I hope you found this useful in your React adventures.  This is just one way to set of sharing state, as there are other ways like using the Context providers as well.  But, this is how I achieved what I needed for my little side project that I'm having a blast with.</p>
<p>Go out there and have fun with React!</p>
]]></content:encoded></item><item><title><![CDATA[Developer Advice To Myself]]></title><description><![CDATA[There are some many things I've learned over the years, a few, I wish I would have learned and applied earlier.
Summary
There are three main points I bring up in this article

Be practical
Don't get too comfortable
Keep learning

Be Practical
There a...]]></description><link>https://blog.codinglogan.dev/developer-advice-to-myself</link><guid isPermaLink="true">https://blog.codinglogan.dev/developer-advice-to-myself</guid><category><![CDATA[devtip]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Fri, 01 Jan 2021 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>There are some many things I've learned over the years, a few, I wish I would have learned and applied earlier.</p>
<h2 id="heading-summary">Summary</h2>
<p>There are three main points I bring up in this article</p>
<ul>
<li>Be practical</li>
<li>Don't get too comfortable</li>
<li>Keep learning</li>
</ul>
<h2 id="heading-be-practical">Be Practical</h2>
<p>There are so many ways to create things as a developer, and there is not one right way to accomplish anything.  Rather, there are <em>infinite ways</em> to create a feature and it is up to you to <em>balance the effort</em> of your chosen path with the requirements of your project that you've been assigned.  You need to ask the right questions to multiple parties as you continue moving forward working on your assignment.  Be sure to gather your requirements, execute on a minimum viable product, and then polish and improve on what works.</p>
<p><em>Gathering requirements is absolutely critical</em> to the work you will doing for the next chunk of time.  Many points of the success of the project depend directly on having accurate requirements when you start.  One way to gather good requirements is to get enough details so that you understand exactly what problem is going to be solved by your work.  If you can't describe the problem, how will you come up with a good solution?  Frequently, you will also be asked "how long will this take?", and you can't answer that question at all without understanding the problem.  So please, gather good requirements, and don't start work or promise a deliverable until you understand the problem.  (yes, this has happened for real in the past, and it's not fun to deal with)</p>
<p>Once you have valid requirements create an MVP (Minimum Viable Product) as soon as you can.  Also, know that estimation is ALWAYS hard to get right because there are so many paths you can take.  You will always be wrong, and that is ok.  Your first goal after giving an estimate to a stakeholder should be to <em>create a MVP</em>.  What this means is that it solves the problem, even if some of the bells and whistles are missing.  Maybe the styling is off a little bit, or maybe that <em>one extra feature</em> hasn't been implemented yet that they asked for.  That's ok at this point.  At first, <em>you just want to solve the core problem</em> and then add to it.</p>
<p>A frequent problem I have had here, is that I get stuck in doing a project the <em>right way</em>, the industry standard way, or the popular way, etc.  My best advice is to do what feels like it will work for the MVP.  If needed you can always refactor your code later because no software is ever "done".  It will get changed and reviewed by you and others later anyway.  Your job is to deliver a solution to a problem, so focus on that one thing first and try to not get hung up in the "right way".  The stakeholder cares more if the problem they have is being solved.</p>
<p>Polishing your code can take some time.  You can refactor your code, write tests, and restyle your components all day long, for weeks, or months.  Pump some extra estimation time into the project for all the back and forth that you'll do here.  Hopefully by this point, your project has solved the core problem, and it is mostly deliverable already.  Use your time to make it feel good to you in the code, rename variables so you can code search more easily later when you find a bug (trust me, it will happen).  Make it as easy for your later self as you can.  <em>If it feels dirty, clean it up</em>, you probably won't know how to read through it later if you can't even read through it now.</p>
<p>In a few bullets, let's summarize</p>
<ul>
<li>Remember to gather your requirements for more accurate estimation</li>
<li>Build an MVP and don't overthink the design too much.  Find something that will work and commit to it.</li>
<li>Polish with the remaining time that you have, clean it up for your future self and other developers.</li>
</ul>
<h2 id="heading-dont-get-too-comfortable">Don't Get Too Comfortable</h2>
<p>This sounds like a downer section, but it does have some good pointers at the end at least.  These opinions may reflect only my specific experience, and might not be the same for other companies, so take this section with a few "grains of salt".</p>
<p>This was one of the hardest lessons I've learned in my career.  <em>DO NOT get too comfortable with your great position at any company</em>.  Once you've landed a job, don't sink in and forget about yourself outside of that position.  If a company has a need to let people go, for better or worse, they won't hesitate to keep their business flowing without you in that position.  Finances win in a business, and if you're making too much of a dent on their payroll, cuts will be made, and you have to be ready when that happens.</p>
<p>Something to consider...</p>
<p>Companies hire you with many promises and benefits coming your way.</p>
<ul>
<li>They might say over and over how great they treat their employees.</li>
<li>They promise that you'll "be taken care of", and that they treat employees like family, etc.</li>
<li>You might receive many great benefits that you feel like you couldn't live without.</li>
<li>On site gym, insurance, etc...</li>
<li>Competitive Salary</li>
<li>The list goes on</li>
</ul>
<p>All benefits grouped together are just <em>Golden Handcuffs</em>, and you have the power to wear them, or not, you have the key.  A company keeps you employed by enticing you with these things that are very desireable to have, so you may willingly keep the handcuffs on, and I kept mine on for too long.</p>
<p>There were multiple times where I considered moving positions, mostly just to try something new because I was starting to feel stale in my position (I wasn't learning much of anything new).  But, every time I was really thinking of leaving I'd somehow get a raise or a promotion, or I'd consider the value of the Golden Handcuffs and decide I was fine where I was.  I felt like the company really valued my work, and in turn I felt very loyal to the company.  They were taking care of me, and I was doing my best to push the company forward.</p>
<p>But, hard times came, and I was ultimately let go, even though I thought <em>I was actively making a difference</em> and that they said <em>they were very appreciative of my work</em>.  This can happen to the best and worst of employees, and it was a complete shock to me and my family when <em>I came home jobless</em>.  I was not ready for starting a job search...  So I want to share some tips to avoid the pain that I went through.</p>
<p>My tips for avoiding some of the harsh reality of being let go when you thought you were safe and comfortable</p>
<ul>
<li>Always be ready to enter the job market, comfortable job, or not</li>
<li>Practice software development OUTSIDE of work (all my portfolio work was in private repositories so I had nothing to show to potential employers...)</li>
<li>Create and update a public portfolio to showcase your best work</li>
<li>Journal or blog about what you've been learning</li>
</ul>
<p>Your goal in a job application, or interview, is to reduce the risk a company takes in hiring you, so show your work and progress in any way that you can!</p>
<h2 id="heading-keep-learning">Keep Learning</h2>
<p>The <em>biggest game changer of my entire career</em>, which has completely changed how I feel about myself as a developer, has been creating a habit of <em>daily developer practice outside of work</em> and blogging about it.  The goal here is that you are able to share all of that development experience with potential employers once you hit the job market again.  Don't stop learning, once you do, you'll get comfortable, and as I explained up above, getting too comfortable can be a scary situation if the stars align wrong.</p>
<p>I try to work on side projects before work, for 1 hour a day.  Do what works best for you, but find a good consistent time so you are always improving yourself and improving your marketability.</p>
<p>Ok, so, you want to keep learning, but what should you build?</p>
<ul>
<li>Build something that provides you with experience in the tech you're interested in.</li>
<li>Solve a problem you currently have, with code</li>
<li>Do extra practice similar to a difficult work project so you can excel during work hours (might get you noticed at work).</li>
<li>Combine a non-technical hobby with tech.  (Example, I created a parallax learning project with images of Pokemon Cards to figure out how perspective works in CSS).</li>
</ul>
<p>If you can keep learning, you are employable, and companies will be lucky to have you.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you were able to grab a few good tips from my thoughts.  Just a a reminder and recap...</p>
<ul>
<li>Be Practical with your work</li>
<li>Don't Get Too Comfortable at one position and company</li>
<li>Keep Learning new things</li>
</ul>
<p>As I do these three things, I'm finding myself happier and consistently becoming a more capable developer.</p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Parallax Gotchas]]></title><description><![CDATA[I explain a few gotchas that I ran into when developing a parallax effect for a work project.  Css background, and a Firefox specific issue I ran into.
Summary
Recently I've been working on a project at work where I've been applying this 3d effect to...]]></description><link>https://blog.codinglogan.dev/parallax-gotchas</link><guid isPermaLink="true">https://blog.codinglogan.dev/parallax-gotchas</guid><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Wed, 23 Dec 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I explain a few gotchas that I ran into when developing a parallax effect for a work project.  Css background, and a Firefox specific issue I ran into.</p>
<h2 id="heading-summary">Summary</h2>
<p>Recently I've been working on a project at work where I've been applying this 3d effect to a set of mountain ranges and some clouds, with a sunset gradient background.  During it I ran into a few things that I'd like to share if it helps anyone else, including myself in the future.</p>
<p><em>Key Points of the article</em></p>
<p>Css Backgrounds should be applied to the parent that sets the perspective, otherwise you'll be painting the background in front of your other elements.</p>
<pre><code>.parallax-parent {
    <span class="hljs-attr">perspective</span>: <span class="hljs-number">1</span>px;
    background: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">your-gradient</span> <span class="hljs-attr">or</span> <span class="hljs-attr">color</span>, <span class="hljs-attr">or</span> <span class="hljs-attr">image</span>&gt;</span>;
}</span>
</code></pre><p>You can actually view the parallax examples in this post on GitHub at my <a target="_blank" href="https://github.com/codingLogan/pokemon-parallax">pokemon-parallax</a> repository.  Look at the README and you can follow links to see those examples.</p>
<p>Firefox tip - If you are nesting parallax effects deeply for whatever reason, you MUST apply a <em>transform-style: preserve-3d;</em> to every div that contains parallax elements or you'll lose your 3d perspective.  Chrome and Safari did not have this issue...</p>
<h2 id="heading-intro-to-parallax">Intro To Parallax</h2>
<p><em>Parallax</em> is really just another way of saying that you've applied a 3d-like view to your page.  As the page adjusts its scrolled position, the view and arrangement of the elements changes as well, as if you were in a real 3d environment.  It's all about the perspective.</p>
<p>For example, if you're looking at a mountain and you are standing <em>at its base</em>, you can only see the mountain, and maybe taller mountains behind it.</p>
<p>But, if you have a drone <em>up high</em>, the perspective is up high, where you can see the front mountain, and down into some canyons, and you can see more of the back mountains.</p>
<p>In addition, if you are moving and looking at the mountain, things close to you appear to move faster than things that are further away.</p>
<p>These are the kinds of things you can achieve with CSS perspective or <em>parallax</em>.</p>
<h2 id="heading-quick-css-to-start-using-parallax">Quick CSS To Start Using Parallax</h2>
<p>This is a very minimal intro to get you started.  If you want a really good article to learn how it works, check out <a target="_blank" href="https://keithclark.co.uk/articles/pure-css-parallax-websites/">Keith's Blog Post about Parallax</a>.  It's an incredible resource, and I don't want to copy his amazing content, credit is due where it is due and he's earned it.</p>
<p>To start using parallax there are a few things you'll need to set in CSS to get things rolling.  On a parent element containing your 3d-viewable elements, you should set these properties.</p>
<pre><code>.parallax-parent {
    <span class="hljs-attr">perspective</span>: <span class="hljs-number">1</span>px;
    height: <span class="hljs-number">100</span>vh;
    overflow-y: auto;
    overflow-x: hidden;
    perspective-origin: center center;
}
</code></pre><ul>
<li><em>perspective</em> sets what depth the users view is at.</li>
<li><em>height</em> and <em>overflow</em> helps you set up a scrolling area so that you can see the perspective work.  If the content of the parallax-parent isn't tall enough to need scrolling you won't see any of the 3d effects.  Set these how you need them.</li>
<li><em>perspective-origin</em> is used to set where the user's "eye" would be viewing the images from.  You'd adjust this depending on the desired effect, but center center is a good start.</li>
</ul>
<p>Then on any <em>child element</em> that you want to be part of the 3d effect, you have to apply a transform that pushes it to a different depth away from the user.</p>
<pre><code><span class="hljs-comment">/* Set layer to be same distance as user
   Example - close mountains
*/</span>
.layer1 {
    <span class="hljs-attr">transform</span>: translateZ(<span class="hljs-number">0</span>px);
}

<span class="hljs-comment">/* Push this element further away from the user
   Example - further mountains
*/</span>
.layer2 {
    <span class="hljs-attr">transform</span>: translateZ(<span class="hljs-number">-1</span>px);
}
</code></pre><p>Have fun and play around with these, and checkout out <em>Keith's article</em>, it's really informative.</p>
<p>Now, to the problems I ran into...</p>
<h2 id="heading-the-background-problem">The Background Problem</h2>
<p>You have to be careful how you apply a CSS background.  You may end up covering elements that have been pushed back further when you don't mean to.  Especially when you apply a background to a group of 3d positioned elements.</p>
<p>Potential Solutions</p>
<ul>
<li>Move the background CSS to the parallax parent, or higher to get the background you want behind all elements.</li>
<li>If you like the effect, you can create semi-transparent background colors to separate the sections.</li>
<li>Have fun!  Play with it until you like it.</li>
</ul>
<h2 id="heading-the-firefox-problem">The Firefox Problem</h2>
<p>Firefox needs some hand holding to let parallax effects drill down into groups.  If you have html markup like this, Firefox will not have 3d effects.  But, Chrome will still work just fine.</p>
<pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"parallax-parent"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bulbasaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"ivysaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"venusaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charmander.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charmeleon.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charizard.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"squirtle.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"wartortle.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"blastoise.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
&lt;/div&gt;
</code></pre><p>So, what gives?  After some digging, I found this gem in the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform-style">docs on MDN</a> that says</p>
<p><em>As this property is not inherited, it must be set for all non-leaf descendants of the element.</em></p>
<p>So, if we modify our above markup with a new CSS class for each grouping, it will fix Firefox, and preserve the 3d effect as expected.</p>
<pre><code>.parallax-group {
    transform-style: preserve<span class="hljs-number">-3</span>d;
}
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"parallax-parent"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parallax-group"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bulbasaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"ivysaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"venusaur.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parallax-group"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charmander.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charmeleon.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"charizard.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"parallax-group"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"squirtle.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer3"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"wartortle.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer2"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"blastoise.png"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"layer1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
&lt;/div&gt;
</code></pre><h2 id="heading-conclusion">Conclusion</h2>
<p>Parallax is a really cool effect to work with, and I'm still learning the tricks with it.  If you have anything you'd add to a gotcha list for parallax building, I'd love to discuss them, I look forward to hearing from you.</p>
]]></content:encoded></item><item><title><![CDATA[Quickly Create An Express React Node Project]]></title><description><![CDATA[This will be a pretty brief post, showing how you can quickly set up an Express app that can also be deployed to Heroku with minimal effort.
Summary (you're welcome)

Create a folder for your project and run git init inside it
Run npx express-generat...]]></description><link>https://blog.codinglogan.dev/quickly-create-an-express-react-node-project</link><guid isPermaLink="true">https://blog.codinglogan.dev/quickly-create-an-express-react-node-project</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Thu, 17 Dec 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>This will be a pretty brief post, showing how you can quickly set up an Express app that can also be deployed to Heroku with minimal effort.</p>
<h1 id="heading-summary-youre-welcome">Summary (you're welcome)</h1>
<ol>
<li>Create a folder for your project and run <em>git init</em> inside it</li>
<li>Run <em>npx express-generator</em> to create a basic Express app</li>
<li>Run <em>npm install</em></li>
<li>ignore _node<em>modules</em></li>
<li>Run <em>npx create-react-app client</em> to create a React client</li>
<li>Modify Express to serve React's static files</li>
<li>Create a root level package.json script to build client files, and run <em>npm run build</em></li>
<li>Run your entire app with <em>npm start</em>.</li>
</ol>
<p>In the end you will have a repository that is holding both your front end application AND your back-end server code.  It makes for really easy deploys of your code because it's all in one place.  This is how it will look at the top level when we're done.</p>
<pre><code>bin/
client/
 |-node_modules/ (ignored)
 |-public/
 |-src/
 |-.gitignore
 |-package-lock.json
 |-package.json
 |-README.md
node_modules/ (ignored)
public/
routes/
views/
.gitignore
app.js
package-lock.json
package.json
</code></pre><p>There are improvements that could be made with this FOR SURE, but this should get you going like it did for me.</p>
<p>Read on if you want more details for each step.</p>
<h2 id="heading-create-your-project-folder">Create your project folder</h2>
<p>Lets start by creating a folder for our project and initializing it with git.</p>
<pre><code>mkdir your-app-name
cd your-app-name
git init
</code></pre><h2 id="heading-create-the-express-app">Create the Express app</h2>
<p>Now we need our express application, I found recently that you can generate one really quickly by running this command.  </p>
<p>(note - the npx package runner lets you run commands even if you don't have the packages installed with npm.  See <a target="_blank" href="https://www.freecodecamp.org/news/npm-vs-npx-whats-the-difference/">this great article</a> for more info)</p>
<pre><code>npx express-generator
</code></pre><p>This will create a folder structure that looks something like this.  Feel free to modify these files to your needs, but out of the box it's a <em>fully functional Express server</em>.</p>
<pre><code>bin/
public/
routes/
views/
app.js
package.json
</code></pre><p>Now... this automated generation added the proper dependencies for your express app to package.json, but did not install them via npm.  Install them now by running <em>npm install</em></p>
<h2 id="heading-sanity-check-make-sure-it-runs">Sanity check, make sure it runs</h2>
<p>Run <em>npm start</em> to start up your new express server</p>
<p>Go to <a target="_blank" href="http://localhost:3000/">http://localhost:3000/</a> and check to see if you get a friendly "Welcome to Express" message.  If you do, you're good to go!</p>
<h2 id="heading-git-management">Git management</h2>
<p>You'll want to create a <em>.gitignore file at the root</em> of your project to ignore various files...  Specifically, for any npm project it's _recommended to ignore node<em>modules</em>, so let's add this to a .gitignore file so we're not saving tracking info for installed packages.</p>
<pre><code>node_modules
</code></pre><p>At this point, you have a bunch of files generated for Express, and you should be ignoring node_modules, I'd recommend doing a git commit at this point but you do you.</p>
<h2 id="heading-create-a-react-client-for-your-app">Create a React client for your app</h2>
<p>Creating a React app structure has been made easy (makes me feel spoiled), by running this command from the root of the project.</p>
<pre><code>npx create-react-app client
</code></pre><p>If successful you will have a new folder in your project called <em>client</em> and it will have these contents</p>
<pre><code>client/
 |-node_modules/ (ignored)
 |-public/
 |-src/
 |-.gitignore
 |-package-lock.json
 |-package.json
 |-README.md
</code></pre><p>Now, we're going to need to build the React app.  For convenience, lets create a build script at the root level, that will go into the client folder and run the build.</p>
<p>Open up your root level package.json and make the scripts look like this</p>
<pre><code><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"node ./bin/www"</span>,
    <span class="hljs-string">"start-client"</span>: <span class="hljs-string">"npm start --prefix client"</span>
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"npm run --prefix client build"</span>
},
</code></pre><ul>
<li><em>start</em> will run your Express server</li>
<li><em>start-client</em> will run your client only</li>
<li><em>build</em> will build your client files</li>
</ul>
<p>I created the build and start-client commands on my own, and I'm not the most familiar with the syntax, but here's my shot at the explanation.  The command work for the client because when you run an npm command with the --prefix flag it runs the command (in our case <em>npm run</em>) as if you were in the <em>client</em> folder.</p>
<p>Anyway, try it out, running <em>npm run build</em> from the root of your project should generate a new <em>build</em> folder inside of client.</p>
<p>Then run <em>npm run start-client</em> to see your React app running.</p>
<p>You can still run <em>npm start</em> and see your Express app running.</p>
<h2 id="heading-make-express-serve-the-react-app">Make Express serve the react app</h2>
<p>All you need to do to serve React's files is tell Express to look for them in the right place.  This is all I've had to do so far in a simple React app.</p>
<p>Open up app.js and find the <em>express.static(</em> line.  Make it look something like this, pointing to your React-built files</p>
<pre><code><span class="hljs-comment">// Serve React's files instead of default public folder </span>
<span class="hljs-comment">// app.use(express.static(path.join(__dirname, 'public')));</span>
app.use(express.static(path.join(__dirname, <span class="hljs-string">'client/build'</span>)));
</code></pre><p>Now when you start Express, it will first look for your /client/build/index.html file.  If it finds it, it will serve React for you.</p>
<p>To validate everything is working run <em>npm start</em> and you will see React instead of Express</p>
<h2 id="heading-notes-on-heroku-deployment">Notes on Heroku deployment</h2>
<p>The additional scripts we added earlier will allow Heroku to <em>build</em> and <em>start</em> your server thats holding your React files.  It looks for those two scripts when you deploy a Node project.</p>
<p>A few more configs</p>
<ul>
<li>To deploy to Heroku, they also want you to specify the Node version in your package.json, so lets add that.</li>
<li>And, unless you add your client app as a dependency you'll get errors when trying to run the above build command.  The root level package.json should have a dependency of your <em>client</em>.<pre><code><span class="hljs-string">"dependencies"</span>: {
  ...other entries...
  <span class="hljs-string">"client"</span>: <span class="hljs-string">"file:client"</span>
},
<span class="hljs-string">"engines"</span>: {
  <span class="hljs-string">"node"</span>: <span class="hljs-string">"14.x"</span>
}
</code></pre></li>
</ul>
<p>When you update package.json with <em>new dependencies</em> be sure to run a fresh <em>npm install</em> to update your lock file accordingly.  Push your changes to GitHub and you're ready to deploy.</p>
<ol>
<li>Go to <a target="_blank" href="https://heroku.com">Heroku.com</a></li>
<li>Create a new app</li>
<li>Connect it to GitHub by choosing <em>Connect to GitHub</em> in the deployment method section</li>
<li>Then you can deploy it automatically or manually.  Once you do, your app should be visible.</li>
</ol>
<h2 id="heading-troubleshooting">Troubleshooting</h2>
<p>As I was learning how to do this Heroku was actually pretty helpful in showing me the errors.  If you run into issues, watch the logging.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Getting a basic site up and running isn't that bad when you have good tooling available to you, and free hosting like Heroku.</p>
<p>We just created a (M)ERN app without the M in a few minutes.</p>
]]></content:encoded></item><item><title><![CDATA[Git Essentials]]></title><description><![CDATA[Git is essential for every flavor of developer out there, so it's good to understand the basics.  In this post I explain my thoughts on what every developer should know about git.
If you want to use git, you must first install it by following the ins...]]></description><link>https://blog.codinglogan.dev/git-essentials</link><guid isPermaLink="true">https://blog.codinglogan.dev/git-essentials</guid><category><![CDATA[Git]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Mon, 07 Dec 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Git is essential for every flavor of developer out there, so it's good to understand the basics.  In this post I explain my thoughts on what every developer should know about git.</p>
<p>If you want to use git, you must first install it by following the instructions at <a target="_blank" href="https://git-scm.com/">https://git-scm.com/</a></p>
<p> </p>
<h3 id="heading-what-git-is-and-is-not">What Git is and is not</h3>
<p>I want to start by clarifying a piece of confusion that I had when I first heard of Git years ago.  Git is <em>not the same thing as GitHub</em>.</p>
<p><em>Git is a version control system</em>.  It keeps track of the changes to your files.  As part of its tracking, it also provides you with an evolving history of each of file.  What this means is you can look into the past and see previous saved "states" of your file, which is called a <em>commit</em>.</p>
<p><em>GitHub is just one place you can store your code</em> in the cloud, there are many other options as well. To use Git, you do not even have to use GitHub, or any cloud service.  What these services allow you to do is share your code and collaborate with other people.</p>
<p>In this post I am going to just cover what Git is, and in a future post I'll cover the basics of using cloud services to collaborate with others.</p>
<p> </p>
<h3 id="heading-why-you-should-use-git">Why you should use Git</h3>
<p>I stated this already, but the benefits of using Git are these</p>
<h5 id="heading-changes-are-tracked">Changes are tracked</h5>
<p>Once you've initialized a folder as a Git repository, Git tracks all of the changes to your files within that folder.  "Changes" can be additional files, deleted files, more lines added to a file, lines removed from a file, etc.  Any changes to the files in the folder will now be tracked for you.  You choose when you want to save those changes to git by creating a <em>commit</em>.  Git will now use that commit as it's "clean" slate to track what has changed.</p>
<p>I will go over creating commits later in the post.</p>
<h5 id="heading-ability-to-see-history">Ability to see history</h5>
<p>Every commit you make is accessible in the future.  You can go back and view the differences between commits, or, if you want, you can actually get an old version of the file back on your system by using the <em>checkout</em> command.</p>
<p>This is the basis of how libraries and frameworks have multiple versions you can choose from, different commits are flagged as those versions.</p>
<h5 id="heading-freedom-to-experiment">Freedom to Experiment</h5>
<p>By default Git creates a default branch called "master" or "main".  With Git you can create as many branches of your code as you wish.  Essentially, when you create a branch you are creating a new version of your code where you can make whatever changes you'd like, <em>without affecting your previous work</em>.  This is useful if you want to add a new feature, or try something completely different.  Often in practice a branch is created by a developer when they begin work on a particular task.</p>
<p>When work has been completed in a branch you can "merge" the branch back into the "main/master" branch so your work is all back in one place again.</p>
<p> </p>
<h3 id="heading-create-a-git-repository">Create a Git repository</h3>
<p>To initialize a folder of yours as a Git repository, you can use this simple command while currently in the folder</p>
<pre><code>git init
</code></pre><p>It will create a folder named <em>.git</em>, and that's where all the <em>magic tracking</em> information is stored.  I have never had to dive into the folder, but that's how you know if a folder is being tracked by Git or not.</p>
<p> </p>
<h3 id="heading-track-some-files">Track some files</h3>
<p>When you're tracking files in Git you can have the files in a few different states</p>
<p><em>Untracked Files</em>:
Git will show you when files are completely Untracked.</p>
<p><em>Working or Un-staged Changes</em>:
These are files that have differences compared to the most recent commit or staged changes.  You will typically only "stage" your changes when you are confident that the changes are what you'll want to save in a commit.</p>
<p><em>Staged Changes</em>:
These are changes that are being batched up in preparation to make a real commit.  When you make a commit, you are telling Git to put all of your staged changes into a commit and save it to the history of your project.</p>
<p>It's worth noting, most developer tools will help you readily see your changes. When I work in VS Code frequently, there's a sidebar that shows me all of this information.</p>
<p> </p>
<h4 id="heading-tracking-the-state-of-your-files">Tracking the state of your files</h4>
<p>In order to accurately track files with Git, it's good to know how to check on the status of your new files, working changes and staged changes.</p>
<p>Use this command to see what files are new, deleted, or modified, or currently staged for a commit.</p>
<pre><code>git status
</code></pre><p>If I use git status right now for this post I have in progress, I get this output showing that I have a modified file, and it gives instructions for how to stage or commit them.</p>
<pre><code>codingLogan.github.io$ git status
On branch git-basics
Your branch is up to date <span class="hljs-keyword">with</span> <span class="hljs-string">'origin/git-basics'</span>.

Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
        <span class="hljs-attr">modified</span>:   _posts/<span class="hljs-number">2020</span><span class="hljs-number">-12</span><span class="hljs-number">-07</span>-git-essentials.md

no changes added to commit (use <span class="hljs-string">"git add"</span> and/or <span class="hljs-string">"git commit -a"</span>)
</code></pre><p>If you want to review the actual changes made to that file, you use the <em>git diff</em> command.  Honestly, it's kind of hard to read, but it shows additions and deletions made to the file.  There are many tools that make viewing the diff much easier.</p>
<pre><code>git diff &lt;filename&gt;
</code></pre><p>To stage a file to git for the first time or to stage a file's modifications use:</p>
<pre><code>git add &lt;file&gt;
</code></pre><p>To unstage a file, Git shows that you can use</p>
<pre><code>git restore --staged &lt;file&gt;
</code></pre><p>Once you have staged all the changes you want to save to Git history, you can commit them.</p>
<pre><code>git commit
</code></pre><p>When you use the command like this it will open an editor to add a message to your commit.  The editor may be different for you, but typically it's a <em>vim editor</em></p>
<p>In order to write a message in a vim editor you'll have to do the following</p>
<ol>
<li>Hit the "i" key to enter <em>Insert Mode</em></li>
<li>Type your message</li>
<li>Hit "Esc" to exit Insert Mode</li>
<li>Type a ":wq" and hit Enter (saying you want to write and quit)</li>
</ol>
<p>You can optionally give the commit a message from the command line</p>
<pre><code>git commit -m <span class="hljs-string">"Finish commit example message"</span>
</code></pre><p> </p>
<h3 id="heading-hide-some-secrets">Hide some secrets</h3>
<p>What do I mean by secrets?  Well, there are projects that contain secrets, or API keys, or passwords, etc, that are needed in order to communicate with other services.  Sometimes these are stored in files in the project, which is ok, but...</p>
<p><em>DO NOT COMMIT ANY SECRETS TO GIT!</em></p>
<p>I'll say it one more time, I want to be sure it's clear...  Saving secrets to Git will permanently save those secrets to Git's history.  If you don't want the world to know your secrets, don't ever commit any.</p>
<p><em>PLEASE, DO NOT COMMIT ANY SECRETS TO GIT!</em></p>
<p>When a project needs to hold any secrets you should ignore those files and set them up manually wherever you need them.  Luckily Git provides you with a mechanism to prevent you from saving them in Git.</p>
<p>Introducing the <em>.gitignore</em> file.  The "." is part of the filename, as it's a hidden file.</p>
<p>A very fast example for you.  Let's say we have a file named secrets.json, and we want to prevent Git from tracking it.</p>
<ol>
<li>create a .gitignore file at the root of your project</li>
<li>Edit .gitignore and add <em>secrets.json</em> to it<pre><code> secrets.json
</code></pre></li>
</ol>
<p>Now, Git will not tell you about changes that happen to that file 👍.  (Phew... crisis averted)</p>
<p> </p>
<h3 id="heading-add-a-feature-branch">Add a feature branch</h3>
<p>Branches are basically different volumes of code. I like to think of branches like library books because you</p>
<ul>
<li>Can only have <em>one branch checked out at a time</em>, similar to library cards limiting you to a certain number of books.</li>
<li>Check them out to start working on them</li>
<li>Commit to them when you're done</li>
<li>Checkout another branch.</li>
</ul>
<p>Here are some useful commands with branches</p>
<p>To view all branches you have on your machine</p>
<pre><code>git branch
</code></pre><p>To create a branch, but don't check it out yet, then checkout the branch with the second command</p>
<pre><code>git branch &lt;branchname&gt;
git checkout &lt;branchname&gt;
</code></pre><p>To create a branch and check it out immediately, it's the same thing as running both commands above (I use this one all the time)</p>
<pre><code>git checkout -b &lt;branchname&gt;
</code></pre><p>Here's a concrete example to create a branch called "fantastic-feature" and start working on that branch</p>
<pre><code>git branch fantastic-feature
git checkout fantastic-feature
</code></pre><p>Remember, you can always verify what branch you are on by using either of these commands (I prefer git branch, but both work)</p>
<pre><code>git branch
git status
</code></pre><p>Once you have created a branch, made some commits, and you feel the work is done, you are probably going to want to merge your code back into the "main/master" branch.  Unless you want to indefinitely have separate versions of your code (like Linux).</p>
<p> </p>
<h3 id="heading-merge-a-feature-branch">Merge a feature branch</h3>
<p>To get your changes into a branch we need to do a few things</p>
<ol>
<li>Checkout the <em>destination branch</em> you want all code to end up in</li>
<li>Attempt a merge of your <em>feature branch</em> into your <em>destination branch</em><ul>
<li>(Maybe a future post) If the two branches have conflicting changes git won't be able to merge them automatically.  When this happens you'll need to resolve the conflicts manually.  This usually happens if both branches have changes to the same area of a file, so it doesn't know how to choose which change to keep.</li>
</ul>
</li>
</ol>
<p>Use this set of commands to merge your branch</p>
<pre><code>git checkout &lt;destination&gt;
git merge &lt;feature&gt;
</code></pre><p>or concretely...</p>
<pre><code>git checkout master
git merge fantastic-feature
</code></pre><p>Master will now have ALL of your work, congrats!!! 👏👏👏</p>
<p> </p>
<h3 id="heading-store-it-in-the-cloud">Store it in the cloud</h3>
<p>I mostly wanted to bring to attention what options you have for storing your code for collaboration with other people.</p>
<p>Popular choices are</p>
<ul>
<li><a target="_blank" href="https://github.com/">GitHub</a></li>
<li><a target="_blank" href="https://bitbucket.org/">BitBucket</a></li>
<li><a target="_blank" href="https://about.gitlab.com/">GitLab</a> I'm not too familiar with this one, but I've seen it around</li>
</ul>
<p> </p>
<h3 id="heading-conclusions">Conclusions</h3>
<p>I hope this post helped in explaining a few of the basics of Git for you.</p>
<ul>
<li>What Git is</li>
<li>How to track changes</li>
<li>How to create branches</li>
<li>How to merge branches back together</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Every Dev Should Do 100DaysOfCode]]></title><description><![CDATA[Why I think every developer should accept the challenge to code for 1 hour, for 100 days.  I've been participating for about 30 days, and I wish I would have done it (years) sooner!
What is 100DaysOfCode?
At it's core, it's a commitment to code for 1...]]></description><link>https://blog.codinglogan.dev/every-dev-should-do-100daysofcode</link><guid isPermaLink="true">https://blog.codinglogan.dev/every-dev-should-do-100daysofcode</guid><category><![CDATA[100DaysOfCode]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Wed, 02 Dec 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Why I think every developer should accept the challenge to code for 1 hour, for 100 days.  I've been participating for about 30 days, and I wish I would have done it (years) sooner!</p>
<h3 id="heading-what-is-100daysofcode">What is 100DaysOfCode?</h3>
<p>At it's core, it's a commitment to code for 1 hour for 100 days.</p>
<p>First, I'll say the <em>official rules</em> are at <a target="_blank" href="https://www.100daysofcode.com/">100daysofcode.com</a> if you want to check them out, but I'll summarize them here for you.</p>
<ul>
<li>Tweet the hashtag #100DaysOfCode to commit to the challenge</li>
<li>It is recommended that you read <a target="_blank" href="https://www.freecodecamp.org/news/join-the-100daysofcode-556ddb4579e4/">this article</a> to familiarize yourself with the purpose of the challenge.</li>
<li>Make a rough plan for what you want to build during your challenge time</li>
<li>Code for 1 hour a day for the next 100 days, and tweet your progress using #100DaysOfCode to encourage yourself and the community</li>
</ul>
<p>If you actually read the article above they mention that they were NOT counting time following tutorials as part of their completion of the challenge.  I <em>have not</em> applied that to my challenge, as I learn well from structured formats, especially in unfamiliar territory I've never touched in depth, like android.</p>
<p>Use the rules above as guidelines to tailor the best experience for you and your learning style, and have some fun with it!  This <em>primarily for you</em> anyway.  For example, I take a day off here and there to refresh my mind, but I get right back to it the next day.  (I've got kids, an amazing wife, and real life to take care of too, can't always be coding, right?)</p>
<h3 id="heading-challenge-benefits">Challenge Benefits</h3>
<p>I highly recommend all developers to accept the challenge, or a shorter version if 100 days is just too much, I'll leave that up to you.  But commit, push forward, and learn!  I've also connected with many developers that have also accepted the challenge on Twitter.  The community on there is amazing, and very supportive!</p>
<p>The reason I wish I would have done this years ago, is because I was really <em>feeling stale</em> in my webdev position.  I wasn't learning much anymore because all the tickets coming through felt the same day after day.  But I was comfortable, so I didn't mind too much, but I should have.  I knew I wanted more, I was hungry to learn, but I just didn't do anything about it.  Accepting this challenge is keeping my inner developer entertained and curious about new technology, I love it!</p>
<p>Benefits</p>
<ul>
<li>Learn New Skills</li>
<li>Develop Habit of Learning</li>
<li>Time management</li>
<li>Opportunity to experiment in code (outside of work)</li>
<li>Networking with other challengers</li>
</ul>
<h3 id="heading-my-first-30-days">My First 30 Days</h3>
<p>In my career, I've been a web developer the whole time.  I worked in the traditional LAMP stack for multiple years.  Just recently, I've moved to a position using <em>primarily javascript using React</em> and a node back-end.  Because I won't get asked to create an android app at work, I chose to learn android on my own during the challenge, and to learn kotlin along with it.  Kotlin is apparently the choice for android development now.</p>
<p>I have been enjoying this challenge WAY more than I thought I would.  It has taken my free time, and transformed a piece of it into productive developer time where I sharpen theoretical blade of skills every single day.  Thirty days ago, I had never touched the <em>kotlin</em> programming language, and for the most part had not really touched <em>android</em> either.  It's been multiple years since I've really done anything with Android. So I could just say that prior to the challenge I've "never" developed for the android platform...  It was only during a school course, and used Java instead...</p>
<p>Anyway, now I'm using both of those technologies daily, and I'm creating small little apps just for fun!  In particular, outside of tutorials I'm following, I created a small little app in an attempt to help me generate a new username.  It was done in android using kotlin, applying everything I'd learned up to that point.  It feels so cool to hold a phone that is running code that I wrote in my hands.  I'm kind of getting addicted to the fact that my phone can be utilized for my designs!  (...excellent...)</p>
<p>Is it a good addiction though?... I think so!</p>
<h3 id="heading-looking-forward-to-days-31-100">Looking Forward to Days 31 - 100</h3>
<p>Most of my time so far has been spent in tutorials, but I learn really well that way.  I have a very well structured tutorial created by Google that I'm following on Udacity to learn best practices for the android platform.  I don't think I'll just happen to find the best practices that they're sharing on my own, so I'm going to continue all the way through it.  Good exposure to best practices is priceless, and will help me in the long run.</p>
<p>One thing I will change as I go further into the challenge is to go tutorial free, like the original challenger did.  I have a few ideas brewing and I'm looking forward to building more things of my own design, and encountering my own unique issues that I have to work through.</p>
<p>This has been a GREAT experience, I highly recommend, 10/10 I will do it again.</p>
]]></content:encoded></item><item><title><![CDATA[Hello Android With Kotlin]]></title><description><![CDATA[Learning Android is a lot less intimidating when you are introduced to the basics.  Here are the basics I was taught recently by following a free Udacity tutorial to build a dice roller app (a link to it is at the end).  Also, this post doesn't reall...]]></description><link>https://blog.codinglogan.dev/hello-android-with-kotlin</link><guid isPermaLink="true">https://blog.codinglogan.dev/hello-android-with-kotlin</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[100DaysOfCode]]></category><category><![CDATA[Android]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Mon, 23 Nov 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Learning Android is a lot less intimidating when you are introduced to the basics.  Here are the basics I was taught recently by following a free Udacity tutorial to build a dice roller app (a link to it is at the end).  Also, this post doesn't really have a lot of Kotlin specific, but is more geared toward understanding a very basic Android App.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>Starting to dive into unfamiliar tech can be overwhelming, luckily, there's really not that much prerequisite to getting started with Android.</p>
<h3 id="heading-what-you-need">What you need</h3>
<p>Personal opinion, you'll want to have a computer that is fairly powerful and has plenty of RAM to spare.  I've heard Android Studio can <em>potentially</em> be a resource hog, but it's not a requirement to have a beast of a machine.</p>
<p>Actual Needs</p>
<ul>
<li>Download the latest version of <a target="_blank" href="https://developer.android.com/studio">Android Studio</a></li>
<li>Android Device - Android Studio does provide you an <em>emulator</em> if you don't have a physical device.</li>
</ul>
<h3 id="heading-create-a-project">Create a Project</h3>
<p>Once you've got Android Studio installed you can create a project, which, actually sets up an entire "Hello World!" for you with a layout file, a kotlin file, and more.</p>
<ul>
<li>Start up Android Studio</li>
<li>Follow the prompts to create a new Project<ul>
<li>For simplicity, start with a <em>Blank Activity</em> (it's as basic as it gets)</li>
<li>In one section of the options you can choose either <em>java or kotlin</em>, I'm choosing kotlin.</li>
<li>With your first app, most of the options can, and should, be left at <em>defaults</em>.</li>
</ul>
</li>
</ul>
<p>After you've created your first project it might take <em>a few minutes</em> to build as it sets up all the files.  Once your files are all generated see <a target="_blank" href="https://developer.android.com/training/basics/firstapp/running-app">Run Your App</a> in Google's docs to get a device set up.</p>
<p>At this point you can hit the <em>play</em> button in the IDE and it will <em>build, install, and launch</em> your app on the emulator or physical device, whichever you have set up.  And it will give you the all too common "Hello World!" on your screen, but it's really fun to see it pop up on your phone!  (I use a real device)</p>
<h3 id="heading-file-structure">File Structure</h3>
<p>Once your project has built, you can finally take a peek at the file structure.  For me, it helps to at least be aware of what the folders are, even if I don't need to touch them yet.</p>
<p><em>It's good to understand the magic going on so you can really own your project</em></p>
<p>In the left side of the IDE you'll see the files of your new project.  You'll also notice at the top area above the files, it has a dropdown to select <em>different views</em> of the project's files.</p>
<ul>
<li><em>Project</em>: Shows the files as they are in the filesystem. (This view is good to know about, but less useful in my short time with it)</li>
<li><em>Android</em>: Shows a friendly view of the various folders which house different content. Note - it's NOT the actual folder structure of the files on disk, it's just organized in this way to be useful for developers.</li>
<li>(others I've not explored yet)</li>
</ul>
<p>Moving forward in my Android experience I will be using the Android view as it seems to be the easiest to work with, until I find some reason not to.</p>
<p>Here are the essential folders to be aware of in your project (there are lots more).</p>
<ul>
<li><em>manifests</em>: Essential app details the OS needs to launch your app.</li>
<li><em>java</em>: All kotlin/java code to control your app goes here</li>
<li><em>java(generated)</em>: Files generated by the IDE, there's no need to modify these files</li>
<li><em>res</em>: Folders with resources you can use in your app<ul>
<li><em>drawable</em>: contains images/vectors</li>
<li><em>layout</em>: contains xml files that describe screens of your app</li>
<li><em>values</em>: contains strings, and other static values</li>
</ul>
</li>
</ul>
<h2 id="heading-key-parts-of-android">Key Parts of Android</h2>
<p>In the most basic app, I learned that there are really 3 basic building blocks to get something working in an Android App.  There's the <em>xml layout</em>, the controlling <em>java/kotlin Activity code</em>, and optionally some <em>resources</em> to reference, like strings.</p>
<p>If you are in the <em>Android View</em> of your project they are in these folders</p>
<ul>
<li>xml layouts -&gt; app/res/layout</li>
<li>activities -&gt; app/java</li>
<li>resources -&gt; app/res</li>
</ul>
<h3 id="heading-layout-xml">Layout (XML)</h3>
<p>This is where you actually build the components that the user will see.  It's defined in XML, and there are many different components you can place into the layout.  I will introduce you to a few by sharing my _activity<em>main.xml</em> layout file so you can see what one looks like, but rather than seeing all the details, let's start without all the Android specifics.</p>
<p>Let's start by how you can think about the design of a layout.  In a simple app, lets say we want just a few elements that appear 1 by 1 vertically</p>
<pre><code>Paragraph <span class="hljs-keyword">of</span> text
Image
Button to press and respond to
</code></pre><p>Now that we know what we want, we just need to search in the docs for what can give us the functionality we want. After finding the XML elements that match your needs lay them out in XML.</p>
<ul>
<li><em>LinearLayout</em> gives me the vertical 1 by 1 I want if I place elements inside of it</li>
<li><em>TextView</em> shows text</li>
<li><em>ImageView</em> shows an image</li>
<li><em>Button</em> is an Android button for interactions</li>
</ul>
<pre><code>{% raw %}
&lt;LinearLayout&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>/&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ImageView</span>/&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span>/&gt;</span></span>
&lt;/LinearLayout&gt;
{% endraw %}
</code></pre><p>Now that we know the elements we need, we'll need to research and fill in all the Android details, (or just follow a tutorial that teaches them to you 👍)</p>
<p>Here's what it looks like all filled out, some was boilerplate, some was manual injection by me, but it's important to see the structure is what I thought up before even <em>thinking in Android's terms</em>.</p>
<pre><code>{% raw %}
&lt;LinearLayout xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">xmlns</span>:tools=<span class="hljs-string">"http://schemas.android.com/tools"</span>
    <span class="hljs-attr">xmlns</span>:app=<span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span>
    <span class="hljs-attr">android</span>:layout_width=<span class="hljs-string">"match_parent"</span>
    <span class="hljs-attr">android</span>:layout_height=<span class="hljs-string">"wrap_content"</span>
    <span class="hljs-attr">android</span>:orientation=<span class="hljs-string">"vertical"</span>
    <span class="hljs-attr">android</span>:layout_gravity=<span class="hljs-string">"center_vertical"</span>
    <span class="hljs-attr">tools</span>:context=<span class="hljs-string">".MainActivity"</span>&gt;

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
        <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@string/roll_description"</span>
        <span class="hljs-attr">android:textAlignment</span>=<span class="hljs-string">"center"</span>
        /&gt;</span></span>

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ImageView</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
        <span class="hljs-attr">app:src</span>=<span class="hljs-string">"@drawable/your_image"</span>
        <span class="hljs-attr">tools:src</span>=<span class="hljs-string">"@drawable/your_design_image"</span>
        <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/action_image"</span>/&gt;</span></span>

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
        <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@string/roll"</span>
        <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/roll_button"</span>/&gt;</span></span>

&lt;/LinearLayout&gt;
{% endraw %}
</code></pre><p>Very concise recap...  We have a ViewGroup LinearLayout element, holding the other elements that give us the layout we thought up, now with Android details.</p>
<p>I feel it might be worth going over some of the android attributes, because when I see them, it feels overwhelming.</p>
<p>First, the <em>root element</em> of a layout can specify what namespaces are used with the <em>xmlns</em> attributes. I'm not going to claim I know a lot about these, but here's what I'm using in the LinearLayout (root) element so I can use the attributes from those namespaces.</p>
<ul>
<li>xmlns:android="http://schemas.android.com/apk/res/android" provides android attributes</li>
<li>xmlns:tools="http://schemas.android.com/tools" provides build time tools, and the usages of it are removed from elements during build time of your app.</li>
<li>xmlns:app="http://schemas.android.com/apk/res-auto" in my usage provides backwards compatibility for the ImageView to draw vector graphics.  I followed the tutorial on this one, and definitely need to research to understand this more.</li>
</ul>
<p>android attributes</p>
<ul>
<li>layout_width: the width of your element</li>
<li>layout_height: the height of your element</li>
<li>orientation: vertical | horizontal for LinearLayout</li>
<li>layout_gravity: where to position the view/element</li>
<li>text: display text</li>
<li>gravity: helps align the contents of the view/element</li>
<li>id: This is used to allow your kotlin/java code to reference the element to do something with it. If you want that button to do something, the id attribute is essential.<ul>
<li>When declaring an id, do it like this _android:id="@+id/your_id<em>name"</em>.  Under the hood Android Studio will create an integer id for you to reference using the R class in your Activity code (I'll show you this later).</li>
</ul>
</li>
</ul>
<h3 id="heading-activity-kotlin">Activity (Kotlin)</h3>
<p>An activity file is where you actually define the behavior of the app.  For example...</p>
<ul>
<li>You can define what happens when a button is clicked by the user.</li>
<li>Should text appear at the bottom of the screen confirming to the user that something happened?</li>
<li>Randomly generate a number, like a dice roll</li>
<li>etc</li>
</ul>
<p>Ok, so at it's core, we want our user to click the button, and have something happen.  You'd add something like this to your Activity in it's onCreate() method (probably <em>app/java/[your package name]/MainActivity.kt</em> if you just created your project)</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">// Using findById, get reference to a button</span>
<span class="hljs-keyword">val</span> actionButton: Button = findViewById(R.id.your_button_id)

<span class="hljs-comment">// tell it what to do when clicked</span>
actionButton.setOnClickListener {
    <span class="hljs-comment">// Your actions go here, be creative!</span>
    <span class="hljs-comment">// Create a message</span>
    <span class="hljs-comment">// Change some text of an existing element</span>
    <span class="hljs-comment">// Generate a number</span>
    <span class="hljs-comment">// Have fun with it...</span>
}
</code></pre>
<p>There are a lot of things you can do, I'll leave it to you to look up what's possible.  If you want something simple, you could look at using a Toast() popup 👍</p>
<h3 id="heading-resources-imagestext">Resources (images/text)</h3>
<p>I want to go over the two resources I used, images, and strings.  The larger your projects gets, the more you'll gather up, so it's good to know how they're used.</p>
<h4 id="heading-images">Images</h4>
<p>Images that you want to use in your app go in the <em>drawable</em> folder.  Simply copy your images into the <em>res/drawable</em> folder and then you can reference the image in your layout xml files.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ImageView</span> <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@drawable/your_image"</span> /&gt;</span>
</code></pre>
<h4 id="heading-string-resource-located-at-appresvaluesstringsxml">String Resource (located at app/res/values/strings.xml)</h4>
<p>The strings resource files has contents like this, which you can either enter manually, or, you can use the IDE helper lightbulb to place it in for you (very handy).</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">resources</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">string</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"app_name"</span>&gt;</span>Your App Name Goes Here<span class="hljs-tag">&lt;/<span class="hljs-name">string</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">string</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"roll"</span>&gt;</span>Seek Your Fate!<span class="hljs-tag">&lt;/<span class="hljs-name">string</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">string</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"roll_description"</span>&gt;</span>Each day of life is a roll of the dice... Make the best of it no matter what you get!<span class="hljs-tag">&lt;/<span class="hljs-name">string</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">resources</span>&gt;</span>
</code></pre>
<p>Use strings in your layouts like this. It will grab the string from the strings.xml file and place them into the view for you.  This is nice because it keeps your xml layout file more concise, especially if you have paragraphs of text.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">TextView</span> <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@string/roll_description"</span> /&gt;</span>
</code></pre>
<h2 id="heading-gradle-build-system">Gradle Build System</h2>
<p>I mostly wanted to mention this because it really does feel like a magic box that puts everything together.  Gradle provides these features for your app, I'll leave a link to their site at the end if you want to learn more.</p>
<ul>
<li>Target particular Android devices</li>
<li>Compiles your app to executable code</li>
<li>Dependency management</li>
<li>App Signing for Google Play</li>
<li>Automated Tests</li>
</ul>
<p>There is a .gradle file for</p>
<ul>
<li>Each module of your app</li>
<li>Your entire project</li>
</ul>
<h2 id="heading-industry-tips">Industry Tips</h2>
<p>There were a couple things mentioned in the Udacity course that I'd love to pass along.</p>
<ol>
<li>Reduce Calls to findViewById. If at all possible reduce the calls to findViewById, it can be an expensive operation and cause lag if misused.</li>
<li>Always move strings to the resource file.  The makes it easier to deal with all of your strings because they are all in one place, especially if you want to translate your app to <em>other languages</em></li>
<li>View Binding - The instructor had notes recommending using this instead of using findViewById.  They mentioned these advantages.<ul>
<li>You get a reference to the full xml layout, and can still reference the id you need</li>
<li>Type Safety, you don't have to guess what type a view element is</li>
<li>Null Safety, you don't pass a resource number, so you can't guess wrong</li>
</ul>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>That was a LOT of information, even as I read back over my post I realize how much of a wall of information it was.  Hopefully you might have picked up a few things you didn't know before, let me know if you did find it helpful!</p>
<h2 id="heading-learning-resources">Learning Resources</h2>
<ul>
<li><a target="_blank" href="https://classroom.udacity.com/courses/ud9012">Udacity Course - Developing Android Apps With Kotlin</a></li>
<li><a target="_blank" href="https://developer.android.com/studio">Android Studio</a></li>
<li><a target="_blank" href="https://gradle.org/">Gradle</a></li>
<li><a target="_blank" href="https://developer.android.com/topic/libraries/view-binding">View Binding</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Basic Git Rebase Exercise]]></title><description><![CDATA[Here is an example of how to use git rebase to create a clean branch history. This post follows the format of an exercise you can follow to understand the concepts, or you can just read through it, you do you 👍
Visual Summary of Moving your branch's...]]></description><link>https://blog.codinglogan.dev/basic-git-rebase-exercise</link><guid isPermaLink="true">https://blog.codinglogan.dev/basic-git-rebase-exercise</guid><category><![CDATA[Git]]></category><category><![CDATA[Gitcommands]]></category><dc:creator><![CDATA[Logan Rasmussen]]></dc:creator><pubDate>Thu, 19 Nov 2020 19:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Here is an example of how to use git rebase to create a clean branch history. This post follows the format of an exercise you can follow to understand the concepts, or you can just read through it, you do you 👍</p>
<h3 id="heading-visual-summary-of-moving-your-branchs-base-to-another">Visual Summary of Moving your branch's base to another</h3>
<p>Go from this</p>
<pre><code>-(<span class="hljs-number">0</span>)--(<span class="hljs-number">1</span>)--(<span class="hljs-number">2</span>) master
    \ 
    (R1)--(R2) rebase1
</code></pre><p>To This</p>
<pre><code>You<span class="hljs-string">'ll get something like this:
-(0)--(1)--(2) master
                \ 
                (R1)--(R2) rebase1</span>
</code></pre><p>Bonus: after a clean rebase, you can merge <em>rebase1</em> to <em>master</em> cleanly</p>
<pre><code>You<span class="hljs-string">'ll get something like this:
-(0)--(1)--(2)--(R1)--(R2) master</span>
</code></pre><h3 id="heading-steps-summary">Steps Summary</h3>
<ul>
<li>Make a feature branch</li>
<li>Make commits on feature branch</li>
<li>Make commits on master</li>
<li>Rebase feature branch (move the branch start to the tip of master)</li>
<li>Move the feature branch into master (merge, with no extra commit)</li>
</ul>
<h2 id="heading-exercise">Exercise</h2>
<h3 id="heading-make-a-feature-branch">Make a feature branch</h3>
<p>Create a new <em>rebase1</em> branch off of <em>master</em></p>
<pre><code>git checkout master
git branch rebase1
git checkout rebase1
</code></pre><h3 id="heading-make-commits-on-feature-branch">Make commits on feature branch</h3>
<p>Make a few commits while on the <em>rebase1</em> branch.  For convenience, make commit messages something like the following so you can easily follow your own messages from each branch</p>
<pre><code>rebase1 R1
rebase1 R2
etc...
</code></pre><h3 id="heading-make-commits-on-master">Make commits on master</h3>
<p>Make a few commits on the <em>master</em> branch.  This will allow us to see how our history moves when we rebase.  Follow a similar commit message format</p>
<pre><code>master <span class="hljs-number">1</span>
master <span class="hljs-number">2</span>
</code></pre><p>Stop and observe what your commits currently look like.  You can use <em>git log</em> while on each branch to see the recent commits.  I'm a very visual person so here's a diagram of what it should be</p>
<pre><code>-(<span class="hljs-number">0</span>)--(<span class="hljs-number">1</span>)--(<span class="hljs-number">2</span>) master
    \ 
    (R1)--(R2) rebase1
</code></pre><h3 id="heading-rebase-feature-branch-move-rebase1s-base-to-the-tip-of-master">Rebase feature branch (move rebase1's base to the tip of master)</h3>
<p>Rebase <em>rebase1</em> to the <em>master</em> branch.  What you're really asking git to do is <em>"attempt to move the start of my branch to the current HEAD of master"</em></p>
<pre><code>git checkout rebase1
git rebase master

You<span class="hljs-string">'ll get something like this:
-(0)--(1)--(2) master
                \ 
                (R1)--(R2) rebase1</span>
</code></pre><ul>
<li>Using <em>git log</em> while on <em>rebase1</em> you'll see all 5 commits in that order</li>
</ul>
<h3 id="heading-move-the-feature-branch-into-master-merge-with-no-extra-commit">Move the feature branch into master (merge, with no extra commit)</h3>
<p>Once you've done a rebase successfully with no conflicts, you can now do a <em>merge</em> and it won't leave any extra commits in your history since no additional change was made</p>
<pre><code>git checkout master
git merge rebase1

You<span class="hljs-string">'ll get something like this:
-(0)--(1)--(2)--(R1)--(R2) master</span>
</code></pre><ul>
<li>use <em>git log</em> to checkout your commit messages if you want to verify this really happened</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Using rebase properly can result in a very clean looking branch history.</p>
]]></content:encoded></item></channel></rss>