<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ 100DaysOfCode - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ 100DaysOfCode - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 08 May 2026 14:35:29 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/100daysofcode/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ #100DaysOfCode Challenge for 2024 – Discord Edition ]]>
                </title>
                <description>
                    <![CDATA[ freeCodeCamp always gets a huge rush of ambitious learners on New Year's Day. And each year, I try to create challenge that will help people stick with their learning. In the past, we've had cloud certification challenges, gamedev challenges, and bac... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/100daysofcode-challenge-2024-discord/</link>
                <guid isPermaLink="false">66b8d1b82755c964523f0511</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Sun, 24 Dec 2023 21:37:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/100-Days-of-Code-2024.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>freeCodeCamp always gets a huge rush of ambitious learners on New Year's Day. And each year, I try to create challenge that will help people stick with their learning.</p>
<p>In the past, we've had cloud certification challenges, gamedev challenges, and back end development challenges.</p>
<p>This year, we're going back to basics, with the popular #100DaysOfCode challenge.</p>
<p>This challenge was created in 2015 by freeCodeCamp alumni Alexander Kallaway. (I've written a detailed <a target="_blank" href="https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/">history of #100DaysOfCode</a> if you're curious.)</p>
<blockquote>
<p>“Every day you code is the day you’ve won.” — Alexander Kallaway</p>
</blockquote>
<p>Here's how the challenge works. There are just 2 simple rules:</p>
<ol>
<li>You commit to coding for at least 1 hour each day – and then posting about it – for 100 consecutive days.</li>
<li>You also commit to encouraging at least 2 people each day by replying to their posts.</li>
</ol>
<p>This second rule is important, because it ensures that everyone feels supported.</p>
<p>The hardest thing about learning to code is sticking with it. I've said this many times and I'll say it again: <strong>learning to code is not a technical challenge – it is a motivational challenge.</strong></p>
<p>If you get enough practice expanding your coding skills, you <em>will</em> eventually become a decent developer. And that's what #100DaysOfCode is all about: getting 100 days worth of practice.</p>
<h3 id="heading-discord-is-the-new-twitter">Discord is the new Twitter</h3>
<p>Social media has kind of been on the decline for a while. Nowadays, many people prefer group chats, forums, Discord servers, and other smaller communities that are based around shared interests.</p>
<p>You could argue that Twitter always was a bunch of separate communities spread across one giant, general purpose platform. You had tech twitter, learn-to-code twitter, Nigerian Dev Twitter, and so many other cohorts of developers.</p>
<p>I am still optimistic about Twitter, and I'm not leaving the platform. But these days I spend a LOT more time on Discord.</p>
<p>So I wanted to formally expand the #100DaysOfCode rules to also include posting on Discord for everyone who prefers it over Twitter.</p>
<p>freeCodeCamp has a #100DaysOfCode chat room on our community Discord server where we're going to be posting our daily updates. You can <a target="_blank" href="https://discord.gg/freecodecamp-org-official-fi-fo-692816967895220344">join freeCodeCamp's Discord</a>.</p>
<h3 id="heading-how-do-i-commit-to-the-100daysofcode-challenge">How do I commit to the #100DaysOfCode Challenge?</h3>
<p>Simple. Just post: "I'm committing to the #100DaysOfCode Challenge starting today" on either <a target="_blank" href="https://twitter.com/search?q=%23100DaysOfCode%20-%23coding%20-%23ai%20-%23telegram%20-%23cybersecurity%20-%23whatsapp%20-%23dataanalytics&amp;src=typed_query&amp;f=live">Twitter</a>, <a target="_blank" href="https://www.linkedin.com/feed/hashtag/?keywords=100daysofcode">LinkedIn</a>, or in <a target="_blank" href="https://discord.gg/freecodecamp-org-official-fi-fo-692816967895220344">the freeCodeCamp Discord</a> #100DaysOfCode chatroom.</p>
<p>Then start posting each day after you finish your coding, like this:</p>
<blockquote>
<p>"#100DaysOfCode Day 1: I completed the freeCodeCamp JavaScript Role Playing Game project, and watched part of a Phaser.js tutorial." </p>
</blockquote>
<p>Or whatever it is you did that day.</p>
<p>Then be sure to interact with at least two other people who posted. </p>
<p>That's it. Rinse and repeat for 99 more days.</p>
<h3 id="heading-what-do-i-learn-each-day">What do I learn each day?</h3>
<p>If you haven't already, I recommend just going through the <a target="_blank" href="https://www.freecodecamp.org/learn">freeCodeCamp Core Curriculum</a> from top to bottom. This represents a shortest path from beginner to intermediate, and you'll get tons of practice building projects.</p>
<p>Note that freeCodeCamp also has more than 1,000 free full length courses on our <a target="_blank" href="https://youtube.com/freecodecamp">community YouTube Channel</a>. And dozens of free books on <a target="_blank" href="https://www.freecodecamp.org/news">freecodecamp.org/news</a>. </p>
<p>This said, I strongly recommend focusing your time on our interactive curriculum, so you can get hands-on experience coding with tests to guide you.</p>
<p>Remember: practice makes perfect. Above all else, the freeCodeCamp curriculum is there to give you thousands of hours of coding practice. And for the #100DaysOfCode challenge, you'll get at least 100 hours.</p>
<p>Learning to code properly will take a lot of time. The way the human brain works, you want to code just a little every day (1 hour is fine) consistently for several years to really become intermediate and then advanced. </p>
<p>It is usually a mistake to try and learn "intensively" by coding all day every day. There are diminishing returns to how much you can learn in a single day.</p>
<p>This is where the true genius of #100DaysOfCode comes in: it helps you get into the rhythm of coding a little each day. And it provides peers who can support you, and keep you motivated to stay consistent.</p>
<p>Here's hoping that you can finish the challenge, take a day or two off, then get right back into the rhythm of coding a little every day.</p>
<p>Well, what are you waiting for? Commit to the #100DaysOfCode challenge. I'll see you on <a target="_blank" href="https://discord.gg/freecodecamp-org-official-fi-fo-692816967895220344">Discord</a>, <a target="_blank" href="https://www.linkedin.com/feed/hashtag/?keywords=100daysofcode">LinkedIn</a>, and <a target="_blank" href="https://twitter.com/search?q=%23100DaysOfCode%20-%23coding%20-%23ai%20-%23telegram%20-%23cybersecurity%20-%23whatsapp%20-%23dataanalytics&amp;src=typed_query&amp;f=live">Twitter</a>. Happy coding. 🏕️</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Difference between logical operators AND and OR ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida AND && and OR || are logical operators in JavaScript which you can use for performing different logical expressions. In this article, I'll explain the difference between them. The goal of this article is for you to understand how th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/difference-between-logical-operators-and-and-or/</link>
                <guid isPermaLink="false">66d84ee629e30bc0ad47756b</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 27 Jun 2023 08:15:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/31-and-or.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>AND <code>&amp;&amp;</code> and OR <code>||</code> are logical operators in JavaScript which you can use for performing different logical expressions. In this article, I'll explain the difference between them.</p>
<p>The goal of this article is for you to understand how these operators work and how they are different.</p>
<p>To understand these operators, it's important to understand the concept of <strong>truthy</strong> and <strong>falsy</strong> values in JavaScript.</p>
<h2 id="heading-truthy-and-falsy-values">Truthy and Falsy values</h2>
<p>In JavaScript, many values can be represented by their boolean equivalents. A value that is represented by <code>false</code> is a falsy value and a value that is represented by <code>true</code> is a truthy value. Let's see some examples:</p>
<pre><code class="lang-js"><span class="hljs-number">0</span>
<span class="hljs-literal">false</span>
<span class="hljs-literal">undefined</span>
<span class="hljs-literal">null</span>
<span class="hljs-string">""</span> <span class="hljs-comment">// empty string</span>
</code></pre>
<p>The values <code>0</code>, <code>false</code>, <code>undefined</code>, <code>null</code>, and empty string <code>""</code> are falsy values because their boolean representations are <code>false</code>.</p>
<p>As for truthy values, any value that is not <code>falsy</code> is <code>truthy</code>. This means truthy values include <code>true</code>, <code>1</code>, <code>[3. 4]</code>, <code>{}</code>, <code>"hello"</code>.</p>
<p>Now that we have that out of the way, let's see how these tie into the <code>AND</code> and <code>OR</code> operators.</p>
<p>I have a <a target="_blank" href="https://youtu.be/HZ-X6JVqfhQ">video version of this topic</a> if you're interested in that.</p>
<h2 id="heading-the-and-operator">The <code>AND</code> operator</h2>
<p>The logical <code>AND</code> operator is used between two operands in an expression like this:</p>
<pre><code class="lang-js">operand1 &amp;&amp; operand2
</code></pre>
<p>The operator returns the second operand <strong>if the first operand is a truthy value</strong>. If the first operand is a falsy value, the operator would return the first operand instead. As we have seen, a truthy value is a value that evaluates to <code>true</code>.</p>
<p>Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> exp1 = <span class="hljs-number">5</span>
<span class="hljs-keyword">const</span> exp2 = <span class="hljs-string">"Dillion"</span>

<span class="hljs-keyword">const</span> result = exp1 &amp;&amp; exp2

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// "Dillion"</span>
</code></pre>
<p>In this example, we have <code>exp1</code> with a value of <strong>5</strong> and <code>exp2</code> with a value of <strong>"Dillion"</strong>. Then we have the <code>result</code> variable which holds the returned value from using the <code>&amp;&amp;</code> operator between <code>exp1</code> and <code>exp2</code>.</p>
<p>What happens here is that the operator, from the left, checks if <code>exp1</code> is a <strong>truthy value</strong>. <strong>5</strong> is a truthy value, so the operator returns the value on the right. That's why <code>result</code> holds the value of <strong>"Dillion"</strong>.</p>
<p>Let's see another example where we use the <code>AND</code> operator multiple times:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">returnFalsy</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>
}

<span class="hljs-keyword">const</span> exp1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
<span class="hljs-keyword">const</span> exp2 = returnFalsy()
<span class="hljs-keyword">const</span> exp3 = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Dillion"</span> }

<span class="hljs-keyword">const</span> result = exp1 &amp;&amp; exp2 &amp;&amp; exp3

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// ""</span>
</code></pre>
<p>As we can see in this example, we have:</p>
<ul>
<li><code>exp1</code> with an array</li>
<li><code>exp1</code> with the returned value of calling <code>returnFalsy()</code> (which is an empty string--a <strong>falsy value</strong>)</li>
<li><code>exp3</code> with an object</li>
</ul>
<p>Lastly, we have the <code>result</code> variable which holds the returned value from using the <code>&amp;&amp;</code> operator between <code>exp1</code> and <code>exp2</code> and between <code>exp2</code> and <code>exp3</code>.</p>
<p>What we have here is <code>exp1 &amp;&amp; exp2</code> as operand 1 and operand 2. Then the result of this expression will become operand 1 for the next expression: <code>result &amp;&amp; exp3</code>. <code>exp3</code> here is the second operand in the second expression.</p>
<p>What happens here is that the operator, from the left, checks if <code>exp1</code> is a <strong>truthy value</strong>. In this case, we have an array, which is a truthy value, which means the second operand <code>exp2</code> will be returned. <code>exp2</code> becomes the first operand, and <code>exp3</code> becomes the second operand for the second expression.</p>
<p>The second <code>&amp;&amp;</code> operator checks if <code>exp2</code> is a truthy value. In this case, the empty string <strong>""</strong> is a falsy value, so the operator returns <code>exp2</code>. It doesn't bother checking <code>exp3</code> because the fact that <code>exp2</code> is falsy, means the operator would stop checking from left to right.</p>
<p>What happens here is <strong>short-circuiting</strong> which you can learn more about in my <a target="_blank" href="https://dillionmegida.com/p/short-circuit-in-programming-simplified/">article on short-circuit operators</a></p>
<h2 id="heading-the-or-operator">The <code>OR</code> operator</h2>
<p>The logical <code>OR</code> operator is used between two operands in an expression like this:</p>
<pre><code class="lang-js">operand1 || operand2
</code></pre>
<p>The operator returns the first operand <strong>if the first operand is a truthy value</strong>. If the first operand is a falsy value, the operator would return the second operand instead.</p>
<p>Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> exp1 = <span class="hljs-number">5</span>
<span class="hljs-keyword">const</span> exp2 = <span class="hljs-string">"Dillion"</span>

<span class="hljs-keyword">const</span> result = exp1 || exp2

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// 5</span>
</code></pre>
<p>In this example, we have <code>exp1</code> with a value of <strong>5</strong> and <code>exp2</code> with a value of <strong>"Dillion"</strong>. Then we have the <code>result</code> variable which holds the returned value from using the <code>||</code> operator between <code>exp1</code> and <code>exp2</code>.</p>
<p>What happens here is that the operator, from the left, checks if <code>exp1</code> is a <strong>truthy value</strong>. <strong>5</strong> is a truthy value, so the operator returns it. That's why <code>result</code> holds the value of <strong>5</strong>.</p>
<p>The <code>OR</code> operator doesn't bother checking <code>exp2</code> because it already found a truthy value. This is the opposite of the <code>AND</code> operator. <code>AND</code> keeps going from left to right as long as <code>true</code>. But <code>OR</code> stops (again, <a target="_blank" href="https://dillionmegida.com/p/short-circuit-in-programming-simplified/">short-circuiting</a> once it sees a <code>true</code>--it only keeps going from left to right as long as <code>false</code></p>
<p>Let's see another example where we use the <code>OR</code> operator multiple times:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">returnFalsy</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>
}

<span class="hljs-keyword">const</span> exp1 = <span class="hljs-literal">null</span>
<span class="hljs-keyword">const</span> exp2 = returnFalsy()
<span class="hljs-keyword">const</span> exp3 = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Dillion"</span> }

<span class="hljs-keyword">const</span> result = exp1 || exp2 || exp3

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// { name: "Dillion" }</span>
</code></pre>
<p>As we can see in this example, we have:</p>
<ul>
<li><code>exp1</code> with a value of <code>null</code> (a <strong>falsy value</strong>)</li>
<li><code>exp1</code> with the returned value of calling <code>returnFalsy()</code> (which is an empty string--a <strong>falsy value</strong>)</li>
<li><code>exp3</code> with an object</li>
</ul>
<p>Lastly, we have the <code>result</code> variable which holds the returned value from using the <code>||</code> operator between <code>exp1</code> and <code>exp2</code> and between <code>exp2</code> and <code>exp3</code>.</p>
<p>What we have here is <code>exp1 || exp2</code> as operand 1 and operand 2. Then the result of this expression will become operand 1 for the next expression: <code>result || exp3</code>. <code>exp3</code> here is the second operand in the second expression.</p>
<p>What happens here is that the operator, from the left, checks if <code>exp1</code> is a <strong>truthy value</strong>. In this case, we have <code>null</code>, which is a falsy value, which means the second operand <code>exp2</code> will be returned. <code>exp2</code> becomes the first operand, and <code>exp3</code> becomes the second operand for the second expression.</p>
<p>The second <code>||</code> operator checks if <code>exp2</code> is a truthy value. In this case, the empty string <strong>""</strong> is a falsy value, so the operator returns <code>exp3</code>. As you notice here, the <code>OR</code> operator keeps going as long as it comes across false values. It only stops once it finds a truthy value or when it comes to the end of the expressions.</p>
<h2 id="heading-using-and-and-or-in-if-statements">Using <code>AND</code> and <code>OR</code> in <code>if</code> statements</h2>
<p><code>if</code> statements allow you to create conditional statements where you determine what would be executed based on a condition.</p>

<p>Let's see an example where we use <code>AND</code> in an <code>if</code> statement:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isLoggedIn = <span class="hljs-literal">true</span>
<span class="hljs-keyword">const</span> cart = []

<span class="hljs-keyword">if</span> (isLoggedIn &amp;&amp; cart.length) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cart not empty"</span>)
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cart is empty"</span>)
}
</code></pre>
<p>Can you guess the result of executing this code? The result is:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Cart is empty</span>
</code></pre>
<p>Here's why. The condition for the <code>if</code> statement is <code>isLoggedIn &amp;&amp; cart.length</code>. The left operand is <code>isLoggedIn</code> which evaluates to <code>true</code>. Remember that the <code>&amp;&amp;</code> operator returns the right operand if the left operand is <code>true</code>. It only returns the left operand if the left operand is <code>false</code>. In this case, the operator would return <code>cart.length</code>, which evaluates to 0 since the <code>cart</code> array is empty.</p>
<p>Which means the <code>if</code> block is executed as <code>if(0)</code>.</p>
<p>The <code>if</code> statement would coerce <code>0</code> to a boolean value. As we saw earlier, <code>0</code> is a <strong>falsy value</strong>. So the <code>if</code> statement seeing that the condition expression <code>0</code> is <code>false</code>, would execute the <code>else</code> block: <code>console.log("Cart is empty")</code>. You can learn more about <a target="_blank" href="https://www.freecodecamp.org/news/coercion-and-type-conversion-in-javascript/">type coercion in this article</a>.</p>
<p>Let's say <code>OR</code> was used instead:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isLoggedIn = <span class="hljs-literal">true</span>
<span class="hljs-keyword">const</span> cart = []

<span class="hljs-keyword">if</span> (isLoggedIn || cart.length) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cart not empty"</span>)
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Cart is empty"</span>)
}
</code></pre>
<p>Can you guess the result of this? Here it is:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Cart not empty</span>
</code></pre>
<p>Here's why. The condition for the <code>if</code> statement here is <code>isLoggedIn || cart.length</code>. The left operand is <code>isLoggedIn</code> which evaluates to <code>true</code>. Remember that the <code>||</code> operator returns the left operand if it is <code>true</code>. It only returns the right operand if the left operand is <code>false</code>. In this case, the operator would return <code>isLoggedIn</code> which evaluates to <code>true</code>.</p>
<p>Which means the <code>if</code> block is executed as <code>if(true)</code>.</p>
<p>In this case, coercion doesn't happen as <code>true</code> is already a boolean value. So the <code>if</code> statement seeing that the condition expression <code>true</code> is <code>true</code>, would execute the <code>if</code> block: <code>console.log("Cart not empty")</code>.</p>
<h2 id="heading-wrap-up">Wrap Up</h2>
<p>Here's a summary of the difference between <code>AND</code> and <code>OR</code>:</p>
<ul>
<li><code>AND</code> returns the right expression if the left expression is <code>true</code></li>
<li><code>AND</code> returns the left expression if the left expression is <code>false</code></li>
<li><code>OR</code> returns the right expression if the left expression is <code>false</code></li>
<li><code>OR</code> returns the left expression if the left expression is <code>true</code></li>
</ul>
<p>You notice that the <code>OR</code> is the inverse of <code>AND</code>? While <code>AND</code> keeps going to the right as long as the left is <code>true</code>, <code>LEFT</code> keeps going to the right as long as the left is <code>false</code> </p>
<p>If you enjoyed this article, please share it with others.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What does the "Maximum call stack exceeded" error mean? ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida Have you ever gotten an error similar to this? This error occurs because the call stack has exceeded its limit. But what does this mean? First, let's understand what the call stack is. The Call Stack The call stack is a data structu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-does-the-maximum-call-stack-stack-exceeded-error-mean/</link>
                <guid isPermaLink="false">66d84f69f6f7ca5a604624f3</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 30 May 2023 07:56:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/29-maximum-call-stack-exceeded.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>Have you ever gotten an error similar to this? This error occurs because the call stack has exceeded its limit. But what does this mean?</p>
<p>First, let's understand what the call stack is.</p>
<h2 id="heading-the-call-stack">The Call Stack</h2>
<p>The call stack is a data structure in JavaScript that contains the function(s) being executed. This structure is in a last-in-first-out format. Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printName</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Dillion"</span>)
}

printName()
<span class="hljs-comment">// Dillion</span>
</code></pre>
<p>At first, the call stack is empty. When <code>printName</code> is declared, the call stack is still empty. When <code>printName()</code> is to be executed, it is added to the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-47.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When the function completes, it is removed from the call stack. Function completion happens when:</p>
<ul>
<li>all the lines in the function have been executed OR</li>
<li>a <code>return</code> statement is encountered in the function</li>
</ul>
<p>This way, the call stack can keep track of what function is currently being executed, and from what scope.</p>
<p>Let's see another example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printName</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printFirstName</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Dillion"</span>)
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printLastName</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Megida"</span>)
  }

  printFirstName()
  printLastName()

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Dillion Megida"</span>)

}

printName()
<span class="hljs-comment">// "Dillion"</span>
<span class="hljs-comment">// "Megida"</span>
<span class="hljs-comment">// "Dillion Megida"</span>
</code></pre>
<p>In this example, we have declared a function called <code>printName</code>. In this function, we declare two other functions: <code>printFirstName</code> and <code>printLastName</code>. Both functions are called, and then the statement <code>console.log("Dillion Megida")</code>.</p>
<p>When <code>printName()</code> is to be executed, it is added to the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-49.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In <code>printName()</code>, when <code>printFirstName()</code> is to be executed, it is also added to the call stack (above <code>printName()</code> because it has not finished execution yet):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-53.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After <code>printFirstName()</code> has completed execution (which logs "Dillion" to the console), it is removed from the call stack. <code>printLastName()</code> is now to be executed, so it is added to the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-51.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After the execution of <code>printLastName()</code> (which logs "Megida" to the console), it is removed from the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-52.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>printName()</code> continues execution which now executes <code>console.log("Dillion Megida")</code>. You can see "Dillion Megida" in the console. <code>printName()</code> is now done, and removed from the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-54.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is how the call stack works to keep track of the current function(s) being executed. But the call stack has a maximum size. When you have more functions than is allowed in the call stack, you get the <strong>maximum call stack size exceeded</strong> error.</p>
<p>One popular case in which you can exceed the maximum call stack size is in <strong>recursion</strong></p>
<p>I have a <a target="_blank" href="https://youtu.be/D71LzJBdaKw">video explaining this</a> that you can also check out.</p>
<h2 id="heading-recursion-and-the-call-stack">Recursion and the call stack</h2>
<p>Take a look at this example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printNames</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Dillion"</span>)

  printNames()

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Megida"</span>)
}

printNames()
<span class="hljs-comment">// "Dillion" - first call</span>
<span class="hljs-comment">// "Dillion" - second call</span>
<span class="hljs-comment">// "Dillion" - third call</span>
<span class="hljs-comment">// "Dillion" - fourth call</span>
<span class="hljs-comment">// "Dillion" - fifth call</span>
<span class="hljs-comment">// and so on, until max</span>
</code></pre>
<p>In this example, we have declared <code>printNames</code>. In this function, we first have <code>console.log("Dillion")</code>, then we have <code>printNames()</code>.</p>
<p>Let's see what happens when we call <code>printNames()</code> after the function declaration.</p>
<p><code>printNames()</code>--this is added to the call stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-55.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>console.log("Dillion")</code> is executed. "Dillion" is logged to the console. Then <code>printNames()</code> is executed again, which is added to the call stack as the active function:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-56.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We have two functions in the call stack now. The first call of <code>printNames</code> and the second call of <code>printNames</code> which is called from the first one.</p>
<p>In this second call of the function, <code>console.log("Dillion")</code> is executed which logs "Dillion" to the console. Then the line <code>printNames()</code> is executed again. A third call, which is added to the call stack as the now active function:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-57.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we have three functions in the call stack. Since nothing stops these function calls, it's going to happen infinitely until "the call stack cannot take it anymore" 😂:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-58.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The call stack has a maximum size of functions that it can hold at the same time. This size might be different in different browsers. When that size has been exceeded, you get the <strong>maximum call stack size exceeded</strong> error.</p>
<p>This would also cause your JavaScript application to be unresponsive. And you definitely do not want this for your users.</p>
<p>When creating recursions in your JavaScript programs, you should also have a <strong>base case</strong>, which terminates the recursions after some calls. This is important so as not to exceed the call stack size and have your application crash.</p>
<p>Here's an example of a base case:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> counter = <span class="hljs-number">0</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printNames</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Dillion"</span>)
  counter++

  <span class="hljs-keyword">if</span> (counter &lt; <span class="hljs-number">5</span>) {
    printNames()
  }

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Megida"</span>)
}

printNames()

<span class="hljs-comment">// Dillion</span>
<span class="hljs-comment">// Dillion</span>
<span class="hljs-comment">// Dillion</span>
<span class="hljs-comment">// Dillion</span>
<span class="hljs-comment">// Dillion</span>
<span class="hljs-comment">// Megida</span>
<span class="hljs-comment">// Megida</span>
<span class="hljs-comment">// Megida</span>
<span class="hljs-comment">// Megida</span>
<span class="hljs-comment">// Megida</span>
</code></pre>
<p>I've updated the code now to have a base case. The base case here is that "if the counter variable is no longer less than 5, stop the recursion". So when the function is called, <code>printNames()</code> is added to the call stack. We have <code>counter</code> as 0, then we log "Dillion" to the console. After that, we increase <code>counter</code> by 1. We then have the condition "if counter is less than 5". Since <code>counter</code> is less than 5, we execute <code>printNames()</code>.</p>
<p>Now the call stack has the first and second <code>printNames()</code> calls.</p>
<p>On the fifth call of <code>printNames</code>, the call stack would have 5 calls of <code>printNames()</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-59.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Remember that the first 4 function calls have not finished. Before they finished, they called another function which was added to the call stack.</p>
<p>At this fifth call, "Dillion" is logged to the console for the fifth time. <code>counter</code>, at 4, is incremented by 1 to 5. Then the condition "if counter is less than 5" is checked. <code>counter</code> (as 5) is not less than 5, so this is the base case that <strong>tells the recursion to stop</strong>.</p>
<p>Since the function doesn't call itself again, it proceeds to the next line.</p>
<p>Then the next line in the function is executed which is <code>console.log("Megida")</code>. After this line, the fifth function in the call stack finishes its execution, and now leaves the call stack.</p>
<p>Now that the fifth function has finished execution, the fourth function can continue from where it stopped. The next line in the fourth function is <code>console.log("Megida")</code> which logs "Megida" to the console when executed. Then the fourth function leaves the stack:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-60.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And the remaining functions on the stack will finish execution until the stack becomes empty:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-61.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-62.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-wrap-up">Wrap up</h2>
<p>When you come across the error "Maximum call stack exceeded", the simple meaning is that "the call sack now contains more active functions than it can contain".</p>
<p>The call stack stores the currently executing function or functions. When there are too many functions being executed, the call stack might exceed its size and then throw an error. This usually occurs in cases of recursions that do not have base cases.</p>
<p>If you enjoyed this article, kindly share it with others :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to store objects or arrays in browser local storage ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida The local storage of browsers only accepts strings, but sometimes you want to store objects or arrays. How do you go about that? We'll see how in this article. The browser local storage, is a Web Storage API that allows us to store ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-store-objects-or-arrays-in-browser-local-storage/</link>
                <guid isPermaLink="false">66d84f1fe9c1a2c18adec093</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 30 May 2023 07:55:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/30-objects-arrays-localstorage.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>The local storage of browsers only accepts strings, but sometimes you want to store objects or arrays. How do you go about that? We'll see how in this article.</p>
<p>The browser local storage, is a Web Storage API that allows us to store data for a domain across browser sessions. Such data will be available and accessible by that domain forever, until it is deleted. It looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-81.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can access this view by inspecting any webpage, going to the Application section, then the Storage section, and selecting Local Storage. You would see all the data that has been saved in local storage for the domain of the webpage.</p>
<p>Local storage is useful for data that you want to quickly access, without having to make an API request to a backend server. A common use case is personalization settings for a user like color scheme or other settings that you do not want to always reach out to the server for.</p>
<p>However, you can only store strings in this storage:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"key"</span>, <span class="hljs-string">"value"</span>)
</code></pre>
<p>Any attempt to store an object or an array would result in the value being stringified. An object like <code>{name: "Dillion"}</code> would be stringified to <code>"[object Object]"</code> and an array like <code>[1,2]</code> will be stringified to <code>"1,2"</code>.</p>
<p>In the case of the array, you can retain the values, but for the object, those values are gone. So how do you correctly store an object and array?</p>
<p>I have a <a target="_blank" href="https://youtu.be/E2rvDpubmnA">video on this topic</a> which you can also check out.</p>
<h2 id="heading-stringifying-objects-and-arrays">Stringifying Objects and Arrays</h2>
<p>Since we know that local storage works with string values, we can stringify the objects and arrays ourselves, in such a way that the contents of the value are not lost. We do this using <code>JSON.stringify()</code> method.</p>
<p>The <code>stringify</code> method of the <code>JSON</code> object converts a value to a JSON string, which we can store instead. Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Dillion"</span>,
  <span class="hljs-attr">color_scheme</span>: <span class="hljs-string">"dark"</span>
}

<span class="hljs-keyword">const</span> stringifiedObj = <span class="hljs-built_in">JSON</span>.stringify(obj)

<span class="hljs-built_in">localStorage</span>.setItem(
  <span class="hljs-string">"userInfo"</span>,
  stringifiedObj
)
</code></pre>
<p>As you can see here, we convert <code>obj</code> to a JSON string, then store it in local storage. Here's what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-86.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When you click on the item in storage, your browser might also show you the value like an actual object below the table (as you can see above).</p>
<p>We can do the same for arrays:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> interests = [
  <span class="hljs-string">"football"</span>,
  <span class="hljs-string">"fashion"</span>,
  <span class="hljs-string">"cooking"</span>
]

<span class="hljs-keyword">const</span> stringifiedInterests =
  <span class="hljs-built_in">JSON</span>.stringify(interests)

<span class="hljs-built_in">localStorage</span>.setItem(
  <span class="hljs-string">"interests"</span>,
  stringifiedInterests
)
</code></pre>
<p>And the local storage view:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/image-85.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Again, you see that even though we actually stored a string, the browser recognizes that it's a stringified array, so by clicking on the item, you see the actual array.</p>
<p>Since they have the values as strings, how do we convert them back to objects and arrays when we want to use them?</p>
<h2 id="heading-parsing-stringified-objects-and-arrays">Parsing Stringified Objects and Arrays</h2>
<p>The <code>JSON</code> object also has a <code>parse</code> method which is to parse a JSON string into the original value. We can use this method to get the original object:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> userInfo =
  <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'userInfo'</span>)

<span class="hljs-keyword">const</span> userInfoParsed = <span class="hljs-built_in">JSON</span>.parse(userInfo)

<span class="hljs-built_in">console</span>.log(userInfoParsed.name)
<span class="hljs-comment">// Dillion</span>

<span class="hljs-built_in">console</span>.log(userInfoParsed.color_scheme)
<span class="hljs-comment">// dark</span>
</code></pre>
<p>And we can use it to get the original array:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> interests =
  <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'interests'</span>)

<span class="hljs-keyword">const</span> interestsParsed = <span class="hljs-built_in">JSON</span>.parse(interests)

<span class="hljs-built_in">console</span>.log(interestsParsed[<span class="hljs-number">1</span>])
<span class="hljs-comment">// fashion</span>

<span class="hljs-built_in">console</span>.log(interestsParsed[<span class="hljs-number">2</span>])
<span class="hljs-comment">// cooking</span>
</code></pre>
<h2 id="heading-wrap-up">Wrap up</h2>
<p>Storing objects in local storage allows you to store a group of properties together instead of having multiple items in the storage. For example, instead of storing <code>userName</code> and  <code>userColorScheme</code> separately in the storage, you can store one object with <code>name</code> and <code>color_scheme</code> properties.</p>
<p>But considering that local storage only allows string values, you have to convert your object or array into a string first.</p>
<p>In this article, we've seen how to do that, as well as get the original values when retrieving from the local storage.</p>
<p>If you enjoyed this article, please share it with others :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is the Nullish Coalescing Operator in JavaScript, and how is it useful ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida The Nullish Coalescing Operator is a new logical operator in JavaScript introduced in ES 2020. In this article, we'll understand how this operator works. There are over four logical operators in JavaScript: the AND &&, OR ||, NOT !,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-the-nullish-coalescing-operator-in-javascript-and-how-is-it-useful/</link>
                <guid isPermaLink="false">66d84f725a0b456f4d32146b</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 05 May 2023 06:55:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/28-nullish-coalescing-operator.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>The Nullish Coalescing Operator is a new logical operator in JavaScript introduced in ES 2020. In this article, we'll understand how this operator works.</p>
<p>There are over four logical operators in JavaScript: the AND <code>&amp;&amp;</code>, OR <code>||</code>, NOT <code>!</code>, and the Nullish Coalescing Operator <code>??</code>.</p>
<p>Sometimes called the <strong>Nullish Operator</strong>, this operator is used between two operands:</p>
<pre><code class="lang-js">operand1 ?? operand2
</code></pre>
<p>To understand this operator, we'll have to understand what "nullish", "coalescing" and <strong>short-circuiting</strong> mean.</p>
<p>I have a <a target="_blank" href="https://youtu.be/CX3VWymirxw">video on this topic</a> that you can check out also.</p>
<h2 id="heading-what-are-nullish-values">What are "nullish" values?</h2>
<p>Nullish values in JavaScript are <code>null</code> and <code>undefined</code>. These values fall under <strong>falsy values</strong> but are more specifically referred to as <strong>null values</strong>. All nullish values are falsy, but not all falsy values (for example, <code>0</code>) are nullish.</p>
<p>So, the nullish operator is related to <code>null</code> and <code>undefined</code> values while other logical operators are related to <code>truthy</code> and <code>falsy</code> values in general.</p>
<h2 id="heading-what-does-coalescing-mean">What does "coalescing" mean?</h2>
<p>Coalescing, according to the dictionary means "coming together to form one whole". How does this apply to programming? It means you bring multiple values together, to make one value out of it.</p>
<p>Coalescing in programming does not specifically mean "joining the values together", but more about "deciding what value is made out of the provided values".</p>
<p>We'll see how this works with examples later in this article.</p>
<h2 id="heading-short-circuiting">Short-Circuiting</h2>
<p>The concept of short-circuiting applies to many programming languages. It occurs when interpreters execute a boolean-related expression and skips the irrelevant part of the expression.</p>
<p>For example, a boolean expression like "I am 40 years old, and I am in tech". This expression would only be <code>true</code> if I am 40 years old, and not just that, I am in tech.</p>
<p>After the interpreter executes "I am 40 years old", it cannot yet conclude that the whole expression is true, because in the case that "I am <strong>NOT</strong> in tech", the expression will be false. The second part of the expression is relevant because it can change the result.</p>
<p>But, in the case that "I am <strong>NOT</strong> 40 years old", short-circuiting will happen. Since the first part of the expression returns <code>false</code>, the interpreter knows that there is no point evaluating the second expression. The second part is irrelevant, as the value from this expression does not change the result. So the interpreter skips the second part (thereby saving resources--time, power).</p>
<p>This also applies to the nullish operator.</p>
<p>You can learn more about short-circuiting <a target="_blank" href="https://dillionmegida.com/p/short-circuit-in-programming-simplified/">in this article</a></p>
<h2 id="heading-the-nullish-coalescing-operator">The Nullish Coalescing Operator</h2>
<p>Now that we've looked at the fundamentals of this operator, let's understand what this operator does.</p>
<p>When used in an expression, the Nullish Operator checks the first operand (on the left) to see if its value is <code>null</code> or <code>undefined</code>. If it isn't, the operator returns it from the expression. But if the first operand is any of those values, the operator returns the second operand from the expression.</p>
<p>Let's see a quick example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">expression1</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
}

<span class="hljs-keyword">const</span> expression2 = <span class="hljs-number">4</span> * <span class="hljs-number">5</span>

<span class="hljs-keyword">const</span> result = expression1() ?? expression2

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// 20</span>
</code></pre>
<p>Here, we have a function called <code>expression1</code> which when called returns <code>null</code>. And we also have <code>expression2</code> which holds the value from the expression <strong>4 * 5</strong>.</p>
<p>For the <code>result</code> variable, we use the nullish operator and pass <code>expression1()</code> and <code>expression2</code> as the operands.</p>
<p>The first operand (the function call expression) returns <code>null</code>. The operator confirms that the first operand is <code>null</code>, so it returns the value from the second expression: <code>expression2</code>.</p>
<p>Let's see another example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">expression1</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"expression1"</span>)
  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">expression2</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"expression2"</span>)
  <span class="hljs-keyword">return</span> <span class="hljs-string">"Dillion"</span>
}

<span class="hljs-keyword">const</span> result = expression1() ?? expression2()

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// expression1</span>
<span class="hljs-comment">// false</span>
</code></pre>
<p>Here, we have <code>expression1</code>, a function which when called executes <code>console.log("expression1")</code>, then returns <code>false</code>. And we have <code>expression2</code>, which is a function that when called, executes <code>console.log("expression2")</code>, and returns "Dillion".</p>
<p>Using the nullish operator, we have the first operand as <code>expression1()</code>, and the second operand as <code>expression2()</code> and assign the value from the expression to <code>result</code>.</p>
<p>When we run this code, you see that we have "expression1" logged, which calls from the execution of <code>expression1</code>. And you see that <code>result</code> is logged as <code>false</code>. This means, <code>expression1()</code> is the returned expression from the nullish operator.</p>
<p>The operator checks if the first expression returns <code>null</code> or <code>undefined</code>, for which it would return the second expression. But in this case, the first expression returns <code>false</code>, therefore, the operator would return the first expression.</p>
<p>Another thing you notice is that "expression2" is not logged. This means that <code>expression2()</code> is not executed at all. <strong>Short-circuiting</strong> happens here.</p>
<p>Since the operator has already confirmed that the first operand is NOT <code>null</code> or <code>undefined</code>, it doesn't bother about the second expression, because the value of the second expression does not change what the operator would return.</p>
<h2 id="heading-nullish-vs-or-operator">Nullish vs OR Operator</h2>
<p>The Nullish and OR operators have some similarities, but they work a bit differently.</p>
<p>The OR operator <strong>checks if the first operand is a truthy value</strong>. If the first operand is one, it returns it, else, it returns the second operand.</p>
<p>But, the Nullish operator <strong>checks if the first operand is a nullish value</strong>. If the first operand isn't one, it returns it, else, it returns the second operand</p>
<p>Here's an OR example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> expression1 = <span class="hljs-string">""</span>
<span class="hljs-keyword">const</span> expression2 = <span class="hljs-string">"Dillion"</span>

<span class="hljs-keyword">const</span> result = expression1 || expression2

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// "Dillion"</span>
</code></pre>
<p>Since the first operand, <code>expression1</code>, is a falsy value (empty string), the operator returns the second operand. If <code>expression1</code> was 20, for example (which is a truthy value), it would have been returned, and short-circuiting would have happened.</p>
<p>Here's a Nullish example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> expression1 = <span class="hljs-literal">undefined</span>
<span class="hljs-keyword">const</span> expression2 = <span class="hljs-string">"Dillion"</span>

<span class="hljs-keyword">const</span> result = expression1 ?? expression2

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// "Dillion"</span>
</code></pre>
<p>Using the nullish operator here, the first operand is <code>undefined</code>, a nullish value, so the operator returns the second operand. If <code>expression1</code> was <code>false</code>, 20, or some other non-nullish value, it would have been returned, and short-circuiting would have happened.</p>
<h2 id="heading-using-the-nullish-operator-directly-with-andor">Using the nullish operator directly with AND/OR</h2>
<p>You can directly mix the AND and OR operators in expressions but you cannot do that for the nullish operator. Here's what I mean:</p>
<pre><code class="lang-js">exp1 &amp;&amp; exp2 || exp3 &amp;&amp; exp4
</code></pre>
<p>Here, we combine AND and OR. The order in this expression is:</p>
<ol>
<li>"exp1 AND exp2"</li>
<li>"the result of that OR exp3"</li>
<li>"the result of that AND exp4"</li>
</ol>
<blockquote>
<p>Don't forget that due to short-circuiting, step 2 or step 3 may never be reached.</p>
</blockquote>
<p>But you cannot do these combinations directly with the nullish operator. For example:</p>
<pre><code class="lang-js">exp1 &amp;&amp; exp2 ?? exp3 || exp4
</code></pre>
<p>We're mixing AND, Nullish, and OR here: this will throw a syntax error. Let's see an actual example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">expression1</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
}

<span class="hljs-keyword">const</span> expression2 = <span class="hljs-number">20</span> &lt; <span class="hljs-number">10</span>

<span class="hljs-keyword">const</span> expression3 =<span class="hljs-string">"Dillion"</span>

<span class="hljs-keyword">const</span> result = expression1() ?? expression2 || expression3
<span class="hljs-comment">// SyntaxError: Unexpected token '||'</span>
</code></pre>
<p>We have <code>expression1</code> a function which when called returns <code>null</code>, <code>expression2</code> which holds the returned value from <strong>20 &lt; 10</strong>, and <code>expression3</code> which holds the string value "Dillion".</p>
<p>Use the nullish and OR operators with these three expressions, what I would expect is that:</p>
<ol>
<li><code>expression1()</code> returns <code>null</code>, so the nullish operator returns the right side of the expression which is <code>expression2 || expression3</code></li>
<li>on the right side, the OR operator is used, which checks if the left side, <code>expression2</code> is truthy; since it is a falsy value, the operator returns the right side</li>
</ol>
<p>But, by executing this, we get an error: <strong>SyntaxError: Unexpected token '||'</strong>. This means you cannot use these operators directly. The only way to combine them is to add parenthesis like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> result = (expression1() ?? expression2) || expression3

<span class="hljs-built_in">console</span>.log(result)
<span class="hljs-comment">// Dillion</span>
</code></pre>
<p>By surrounding <strong>expression1() ?? expression2</strong> with parentheses, we can then use the returned result as the first operand for the OR operator, and add <code>expression3</code> as the second operand.</p>
<h2 id="heading-wrap-up">Wrap up</h2>
<p>The nullish operator is very useful in declaring default values for potential <code>null</code> or <code>undefined</code> values. Say, you're expecting an object from an API. If that object does not contain an expected property, that property may either hold <code>null</code> or be <code>undefined</code> like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {}

<span class="hljs-built_in">console</span>.log(obj.type)
<span class="hljs-comment">// undefined</span>
</code></pre>
<p>Using the nullish operator, we can provide a default value:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {}

<span class="hljs-built_in">console</span>.log(obj.type ?? <span class="hljs-string">"default"</span>)
<span class="hljs-comment">// "default"</span>
</code></pre>
<p>There are many other ways you can use this operator for default values or safe checks.</p>
<p>If you enjoyed this article, please share :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Hoisting in JavaScript | Hoisting Functions, Variables and Classes ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida Hoisting is a concept or behavior in JavaScript where the declaration of a function, variable, or class goes to the top of the scope they were defined in. What does this mean? Hoisting is a concept you may find in some programming l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-hoisting-in-javascript-3/</link>
                <guid isPermaLink="false">66d84f6bf6f7ca5a604624f5</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 28 Apr 2023 14:54:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/27-hoisting.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>Hoisting is a concept or behavior in JavaScript where the declaration of a function, variable, or class goes to the top of the scope they were defined in. What does this mean?</p>
<p>Hoisting is a concept you may find in some programming languages (such as JavaScript) and not in others. It's a special behavior of the JavaScript interpreter. We'll learn about how it works in this article.</p>
<p>Let's start with functions.</p>
<p>I have a <a target="_blank" href="https://youtu.be/o8kXXjZdpqg">video version of this topic</a> which you can check out.</p>
<h2 id="heading-function-hoisting">Function Hoisting</h2>
<p>Take a look at this code example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHello</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}

printHello()
<span class="hljs-comment">// hello</span>
</code></pre>
<p>Here, we declare <code>printHello</code>, and we execute the function just after the line it was declared. No errors; everything works!</p>
<p>Now look at this example:</p>
<pre><code class="lang-js">printHello()
<span class="hljs-comment">// hello</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHello</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}
</code></pre>
<p>Here, we execute <code>printHello</code> before the line the function was declared. And everything still works without errors. What happened here? <strong>Hoisting</strong>.</p>
<p>Before the interpreter executes the whole code, it first hoists (raises, or lifts) the declared function to the top of the scope it is defined in. In this case, <code>printHello</code> is defined in the global scope, so the function is hoisted to the top of the global scope. Through hoisting, the function (including the logic) becomes accessible even before the line it was declared in the code.</p>
<p>Let's see another example:</p>
<pre><code class="lang-js">printHello()
<span class="hljs-comment">// hello</span>

printDillion()
<span class="hljs-comment">// ReferenceError: printDillion is not defined</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHello</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'hello'</span>)

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printDillion</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"dillion"</span>)
  }
}
</code></pre>
<p>As you see here, we declare <code>printHello</code>. In this function, we first execute <code>console.log('hello')</code> then we declare another function called <code>printDillion</code> which executes <code>console.log('dillion')</code> when called.</p>
<p>Before <code>printHello</code> is declared in the code, we try to access it by executing <code>printHello()</code>. It's accessible (since it is hoisted to the top of the global scope), so we have "hello" printed on the console.</p>
<p>But then we try to access <code>printDillion</code>, and we get a reference error: <strong>printDillion is not defined</strong>. Does hoisting not occur on <code>printDillion</code>?</p>
<p><code>printDillion</code> is hoisted, but it is only lifted to the top of the scope it was declared in. In this case, it is declared in a local scope--in <code>printHello</code>. Therefore, it would only be accessible in the function. Let's update our code:</p>
<pre><code class="lang-js">printHello()
<span class="hljs-comment">// hello</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHello</span>(<span class="hljs-params"></span>) </span>{
  printDillion()
  <span class="hljs-comment">// dillion</span>

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'hello'</span>)

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printDillion</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"dillion"</span>)
  }
}
</code></pre>
<p>Now, we execute <code>printDillion</code> in <code>printHello</code> before the line where <code>printDillion</code> was actually declared. Since the function is hoisted to the top of the local scope, we're able to access it before the line where it was actually declared.</p>
<p>Hoisting makes all these possible for function declarations. But, it's also worth noting that <strong>hoisting does not occur on function expressions</strong>. I explained the reason for this here: <a target="_blank" href="https://www.freecodecamp.org/news/function-declaration-vs-function-expression/">Function Declarations vs Function Expressions</a></p>
<p>Now let's look at hoisting for variables.</p>
<h2 id="heading-variable-hoisting">Variable Hoisting</h2>
<p>You can declare variables in JavaScript with the <code>var</code>, <code>let</code>, and <code>const</code> variables. And these variable declarations would be hoisted, but behave differently. Let's start with <code>var</code>.</p>
<h3 id="heading-hoisting-var-variables">Hoisting <code>var</code> variables</h3>
<p>Take a look at this example:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// undefined</span>

<span class="hljs-keyword">var</span> name = <span class="hljs-string">"Dillion"</span>
</code></pre>
<p>Here, we declare a variable called <code>name</code> with a string value of "Dillion". But, we try to access the variable before the line it was declared. But we don't get any errors. <strong>Hoisting happened</strong>. The <code>name</code> declaration is hoisted to the top, so the interpreter "knows" that there is a variable called <code>name</code>. If the interpreter did not know, you would get <strong>name is not defined</strong>. Let's try it out:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// ReferenceError: name is not defined</span>

<span class="hljs-keyword">var</span> myName = <span class="hljs-string">"Dillion"</span>
</code></pre>
<p>We have a variable called <code>myName</code> but no <code>name</code>. We get the <strong>name is not defined</strong> error when we try to access <code>name</code>. The interpreter "does not know" about this variable.</p>
<p>Coming back to our example above:</p>
<pre><code><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// undefined</span>

<span class="hljs-keyword">var</span> name = <span class="hljs-string">"Dillion"</span>
</code></pre><p>Although hoisting happened here, the value of <code>name</code> is undefined when we access it before the line of declaration. With variables declared <code>var</code>, the variable declaration is hoisted but with a default value of <code>undefined</code>. The actual value is initialized when the declaration line is executed.</p>
<p>By accessing the variable after that line, we get the actual value:</p>
<pre><code><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// undefined</span>

<span class="hljs-keyword">var</span> name = <span class="hljs-string">"Dillion"</span>

<span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// Dillion</span>
</code></pre><p>Let's say we declared <code>name</code> in a function:</p>
<pre><code class="lang-js">print()

<span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// ReferenceError: name is not defined</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Dillion"</span>
}
</code></pre>
<p>Here, we get a reference error: <strong>name is not defined</strong>. Remember, variables are hoisted but <strong>only to the top of the scope they were declared in</strong>. In this case, <code>name</code> is declared in <code>print</code>, so it will be hoisted to the top of that local scope. Let's try to access it in the function:</p>
<pre><code class="lang-js">print()

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(name)
  <span class="hljs-comment">// undefined</span>

  <span class="hljs-keyword">var</span> name = <span class="hljs-string">"Dillion"</span>
}
</code></pre>
<p>By trying to access <code>name</code> in the function, even though it's above the line of declaration, we do not get an error. That's because <code>name</code> is hoisted, but don't forget, <strong>with a default value of <code>undefined</code></strong>.</p>
<h3 id="heading-hoisting-let-variables">Hoisting <code>let</code> variables</h3>
<p>Although variables declared with <code>let</code> are also hoisted, they have a different behavior. Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// ReferenceError: Cannot access 'name' before initialization</span>

<span class="hljs-keyword">let</span> name = <span class="hljs-string">"Dillion"</span>
</code></pre>
<p>Here, we get a reference error: <strong>Cannot access 'name' before initialization</strong>. Do you notice that the error does not say <strong>name is not defined</strong>? That's because the interpreter is "aware" of a <code>name</code> variable because the variable is hoisted.</p>
<p>"Cannot access 'name' before initialization" occurs because variables declared with <code>let</code> do not have a default value when hoisted. As we saw in <code>var</code>, the variables have a default value of <code>undefined</code> until the line where the declaration/initialization is executed. But with <code>let</code>, the variables are uninitialized.</p>
<p>The variables are hoisted to the top of the scope they are declared in (local, global, or block), but are not accessible because they have not been initialized. This concept is also referred to as the <a target="_blank" href="https://dillionmegida.com/p/temporal-dead-zone-in-javascript">Temporal Dead Zone</a>.</p>
<p>They can only be accessible after the initialization line has been executed:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Dillion"</span>

<span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// Dillion</span>
</code></pre>
<p>By accessing <code>name</code> after the line it was declared and initialized, we get no errors.</p>
<h3 id="heading-hoisting-const-variables">Hoisting <code>const</code> variables</h3>
<p>Just like <code>let</code>, variables declared with <code>const</code> are hoisted, but not accessible. For example:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// ReferenceError: Cannot access 'name' before initialization</span>

<span class="hljs-keyword">const</span> name = <span class="hljs-string">"Dillion"</span>
</code></pre>
<p>The same concept of a <strong>temporal dead zone</strong> applies to <code>const</code> variables. Such variables are hoisted to the top of the scope they are defined in (local, global, or block), but they remain inaccessible until the variables are initialized with a value.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> name = <span class="hljs-string">"Dillion"</span>

<span class="hljs-built_in">console</span>.log(name)
<span class="hljs-comment">// Dillion</span>
</code></pre>
<p>By accessing the variable after it has been initialized with a value (as you see above), everything works fine.</p>
<p>Moving onto hoisting for classes.</p>
<h2 id="heading-class-hoisting">Class Hoisting</h2>
<p>Classes in JavaScript are also hoisted. Let's see an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Dog = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">"Bingo"</span>)
<span class="hljs-comment">// ReferenceError: Cannot access 'Animal' before initialization</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name
  }
}
</code></pre>
<p>Here, we declare a class called <code>Animal</code>. We try to access this class (instantiate a <code>Dog</code> object) before it was declared. We get a reference error: <strong>Cannot access 'Animal' before initialization</strong>. What does this error remind you of?</p>
<p>Just like <code>let</code> and <code>const</code> variables, classes are hoisted to the top of the scope they are defined in, but inaccessible until they are initialized. We do not get "Animal is not defined", which shows that the interpreter "knows" that there is an <code>Animal</code> class (due to hoisting). But we cannot access that class until the line of initialization is executed.</p>
<p>Let's update the code:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name
  }
}

<span class="hljs-keyword">const</span> Dog = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">"Bingo"</span>)

<span class="hljs-built_in">console</span>.log(Dog)
<span class="hljs-comment">// { name: 'Bingo' }</span>
</code></pre>
<p>After <code>Animal</code> has been initialized, it becomes accessible, so we can instantiate the <code>Dog</code> object from the class without errors.</p>
<h2 id="heading-wrap-up">Wrap Up</h2>
<p>In some codebases, you may find a code similar to this:</p>
<pre><code class="lang-js">function1()
function2()
function3()

<span class="hljs-comment">// lines of code</span>
<span class="hljs-comment">// lines of code</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">function1</span>(<span class="hljs-params"></span>) </span>{...}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">function2</span>(<span class="hljs-params"></span>) </span>{...}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">function3</span>(<span class="hljs-params"></span>) </span>{...}
</code></pre>
<p>The three functions here are called at the top but actually declared in the code at the bottom. This is possible, due to hoisting. The functions are hoisted to the top of the global scope (which is where they were defined) together with their logic, so they become accessible/executable even before the line they were defined.</p>
<p>It's different for the others. <code>var</code> variables are hoisted but with a default value of <code>undefined</code>. <code>let</code> and <code>const</code> variables, and classes are hoisted but inaccessible as they do not have a default initialization.</p>
<p>If you enjoyed this piece, please share it with others 🙏🏾</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Function Declaration vs Function Expression ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida When creating functions, you can use two approaches: declaration and expression. What's the difference? When talking about functions in JavaScript, you would often hear function declarations and function expressions. Though these ap... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/function-declaration-vs-function-expression/</link>
                <guid isPermaLink="false">66d84ef37211ea6be29e1b4f</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 26 Apr 2023 12:11:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/26-function-declaration-vs-expression.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>When creating functions, you can use two approaches: <strong>declaration</strong> and <strong>expression</strong>. What's the difference?</p>
<p>When talking about functions in JavaScript, you would often hear function declarations and function expressions. Though these approaches are almost similar, they have notable differences.</p>
<p>We'll look at the differences in this article.</p>
<p>I have <a target="_blank" href="https://www.youtube.com/watch?v=cozcCZjkjto">a video version of this topic</a> you can also check out.</p>
<h2 id="heading-function-declaration">Function Declaration</h2>
<p>To declare a function, you use the <code>function</code> keyword and specify a name for the function. For example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateIntro</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hi, my name is <span class="hljs-subst">${name}</span>`</span>
}

<span class="hljs-keyword">const</span> dillion = generateIntro(<span class="hljs-string">"Dillion"</span>)
<span class="hljs-built_in">console</span>.log(dillion)

<span class="hljs-comment">// Hi, my name is Dillion</span>
</code></pre>
<p>Here, we have "declared" a function called <code>generateIntro</code>. You see we use the <code>function</code> keyword followed by the name of the function: "generateIntro"</p>
<p>Now let's look at function expression.</p>
<h2 id="heading-function-expression">Function Expression</h2>
<p>Here, you create a function expression and assign it to a variable that can be called. You can do this in two ways.</p>
<h3 id="heading-function-expressions-with-the-function-keyword">Function Expressions with the <code>function</code> keyword</h3>
<p>One way to do this is to use the function keyword without a name, which makes it an anonymous function. Here's how:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> generateIntro = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hi, my name is <span class="hljs-subst">${name}</span>`</span>
}

<span class="hljs-keyword">const</span> dillion = generateIntro(<span class="hljs-string">"Dillion"</span>)
<span class="hljs-built_in">console</span>.log(dillion)

<span class="hljs-comment">// Hi, my name is Dillion</span>
</code></pre>
<p>As you see here, we have the <code>function</code> keyword without a name for the function. This makes it an expression, which you have to assign to a variable (as we have done to <code>generateIntro</code> here).</p>
<p><strong>Note:</strong> you can use <code>const</code>, <code>let</code> or <code>var</code> to declare the variable. You can learn more about the differences between these keywords <a target="_blank" href="https://www.freecodecamp.org/news/differences-between-var-let-const-javascript/">in this article</a></p>
<p>If we use the <code>function</code> keyword without a name, we create a function expression, which we have to assign to a variable, else we get an error. Here's what I mean:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hi, my name is <span class="hljs-subst">${name}</span>`</span>
}

<span class="hljs-comment">// SyntaxError: Function statements require a function name</span>
</code></pre>
<p>We get an error: <strong>SyntaxError: Function statements require a function name</strong>. Without assigning it to a variable, JavaScript assumes it is a statement, and as the error says, you must provide a function name.</p>
<p>But when you assign it to a variable, you assign the expression, and when you call the variable (<code>variable()</code>), it will execute the logic of the function expression assigned to it.</p>
<h3 id="heading-arrow-function-expressions">Arrow function expressions</h3>
<p>You can also create function expressions with arrow functions. Arrow functions, introduced in ES6 allow you to write functions in a short manner. But <strong>arrow functions cannot be declared; they can only be expressed</strong>. Here's an example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> generateIntro = <span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hi, my name is <span class="hljs-subst">${name}</span>`</span>
}

<span class="hljs-keyword">const</span> dillion = generateIntro(<span class="hljs-string">"Dillion"</span>)
<span class="hljs-built_in">console</span>.log(dillion)

<span class="hljs-comment">// Hi, my name is Dillion</span>
</code></pre>
<p>The arrow function here is <code>(args) =&gt; {...}</code>. This is a function expression that we have assigned to <code>generateIntro</code>.</p>
<p>For the rest of this article, I'll focus on function expressions created with the <code>function</code> keyword but know that it also applies to arrow functions.</p>
<h2 id="heading-function-declarations-vs-function-expressions">Function Declarations vs Function Expressions</h2>
<p>So what's the difference between these ways of creating functions and why does it matter?</p>
<p>It matters because these functions have different behaviors. And depending on what you want to achieve, one may be preferred over the other.</p>
<h3 id="heading-1-expressed-functions-cannot-be-used-before-initialization">1. Expressed functions cannot be used before initialization</h3>
<p>You can use a declared function before the line it was initialized. Here's what I mean:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> result = sum(<span class="hljs-number">20</span>, <span class="hljs-number">50</span>)
<span class="hljs-built_in">console</span>.log(result)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">num1, num2</span>) </span>{
  <span class="hljs-keyword">return</span> num1 + num2
}

<span class="hljs-comment">// 70</span>
<span class="hljs-comment">// "hello"</span>
</code></pre>
<p>As you see here, we used <code>sum</code> on line 1, which is actually before the line was declared. What happens here is <strong>hoisting</strong>. <code>sum</code> is hoisted to the top of the code before the whole code is executed. This makes <code>sum</code> accessible before the line where it was actually created in the code.</p>
<p>When it comes to hoisting, <strong>all functions and variables are hoisted</strong>. But, functions created with function expressions cannot be "used" before their initialization.</p>
<p>Let's see an example using a function expression created with the <code>function</code> keyword:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> result = sum(<span class="hljs-number">20</span>, <span class="hljs-number">50</span>)
<span class="hljs-built_in">console</span>.log(result)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-keyword">const</span> sum = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">num1, num2</span>) </span>{
  <span class="hljs-keyword">return</span> num1 + num2
}

<span class="hljs-comment">// ReferenceError: Cannot access 'sum' before initialization</span>
</code></pre>
<p>We get an error: <strong>ReferenceError: Cannot access 'sum' before initialization</strong>. We get this error because when you declare variables with <code>let</code> or <code>const</code> (like we did for <code>sum</code> here), they are hoisted, but without a default initialization. You can learn more about what happens here in this article: <a target="_blank" href="https://www.freecodecamp.org/news/javascript-let-and-const-hoisting/">the hoisting behavior in let and const</a></p>
<p>Let's say we create the variable with <code>var</code> instead:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> result = sum(<span class="hljs-number">20</span>, <span class="hljs-number">50</span>)
<span class="hljs-built_in">console</span>.log(result)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-keyword">var</span> sum = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">num1, num2</span>) </span>{
  <span class="hljs-keyword">return</span> num1 + num2
}

<span class="hljs-comment">// TypeError: sum is not a function</span>
</code></pre>
<p>Now we get a new error: <strong>TypeError: sum is not a function</strong>. Although <code>var</code> variables are hoisted, they are hoisted with a default initialization of <code>undefined</code>. So attempting to call it like a function, that is <code>undefined()</code>, throws the error that "sum is not a function".</p>
<p>The same error would occur if it were an arrow function.</p>
<p>Therefore, <strong>only declared functions can be used before initialization</strong>.</p>
<h3 id="heading-2-expressed-functions-need-to-be-assigned-to-be-used-later">2. Expressed functions need to be assigned to be used later</h3>
<p>With declared functions, you already have the name: <code>function name...</code>. So you can use the function later: <code>name()</code>. But with function expressions, there's no name as we saw. It would be impossible to use such a function later unless we assigned it to a variable:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> printName = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">firstname, lastname</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${firstname}</span> <span class="hljs-subst">${lastname}</span>`</span>)
}
</code></pre>
<p>Here, we assigned the function expression to <code>printName</code>. Now we can use that function logic later by calling <code>printName()</code>.</p>
<h3 id="heading-3-anonymous-functions-are-useful-for-anonymous-operations">3. Anonymous functions are useful for anonymous operations</h3>
<p>There are cases where you do not need to use a function later. You can execute the function instantly. In such cases, you do not need a name, so you can use a function expression instead of a declaration.</p>
<p>Let's see some examples.</p>
<h4 id="heading-immediately-invoked-function-expressions-iifes">Immediately Invoked Function Expressions (IIFEs)</h4>
<p>IIFEs are functions that are immediately invoked after creation. Here's an example:</p>
<pre><code class="lang-js">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'deeecode'</span>)
})()

<span class="hljs-comment">// deeecode</span>
</code></pre>
<p>Or the arrow function equivalent:</p>
<pre><code class="lang-js">
(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'deeecode'</span>)
})()

<span class="hljs-comment">// deeecode</span>
</code></pre>
<p>This is an IIFE where we create a function that executes <code>console.log('deeecode')</code>. Immediately after creating the function, we execute it as you see at the end (<code>()</code>). Here, we do not intend to use the function later, so a function expression works fine.</p>
<p>Using a function declaration here will not throw an error, but the name of the function will be inaccessible:</p>
<pre><code class="lang-js">(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'deeecode'</span>)
})()

print()

<span class="hljs-comment">// deeecode</span>
<span class="hljs-comment">// ReferenceError: print is not defined</span>
</code></pre>
<p>Using a function declaration, the IIFE is executed, but you cannot access the name of the function outside the parenthesis.</p>
<h4 id="heading-callback-functions">Callback Functions</h4>
<p>When using callback functions, you can also pass anonymous functions (function expressions). For example, using the <code>forEach</code> method of arrays which expects a callback function, we can use an anonymous function.</p>
<p>The syntax of the <code>forEach</code> method is:</p>
<pre><code class="lang-js">array.forEach(callbackFn)
</code></pre>
<p><code>forEach</code> loops through each item in an array and executes the callback function on them. Let's see how we use a function expression for this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]

array.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-built_in">console</span>.log(value)
})

<span class="hljs-comment">// 1</span>
<span class="hljs-comment">// 2</span>
<span class="hljs-comment">// 3</span>
</code></pre>
<p>As you see here, we passed a function expression (anonymous function) as an argument to <code>forEach</code>.</p>
<p>You can pass a function declaration instead, and the callback function will work. But, as we saw earlier, you won't be able to access the function later:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]

array.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-built_in">console</span>.log(value)
})

<span class="hljs-comment">// 1</span>
<span class="hljs-comment">// 2</span>
<span class="hljs-comment">// 3</span>

<span class="hljs-comment">// ReferenceError: print is not defined</span>
</code></pre>
<p>As you see here, <code>print</code> is declared and used as the callback function, but you cannot access <code>print</code> afterward.</p>
<h2 id="heading-wrap-up">Wrap up</h2>
<p>Function declarations and function expressions are terms you would hear a lot around functions in JavaScript You can use function expressions to perform similar logic with function declarations, but it is worth noting the differences.</p>
<p>In this article, we've seen how function expressions and different from function declarations.</p>
<p>If you enjoyed this article, please give it a share :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Arrow Functions vs Regular Functions in JavaScript – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida In JavaScript, there are two types of functions. You have normal functions and arrow functions. Let's explore the difference between them in this article. Arrow functions was introduced in ES6. And it introduced a simple and shorter... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-difference-between-arrow-functions-and-normal-functions/</link>
                <guid isPermaLink="false">66d84f624c5150361c4fdb28</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 13 Apr 2023 21:04:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/25-arrow-normal-functions.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>In JavaScript, there are two types of functions. You have normal functions and arrow functions. Let's explore the difference between them in this article.</p>
<p>Arrow functions was introduced in ES6. And it introduced a simple and shorter way to create functions.</p>
<p>Here's how to create a normal function, with arguments, which returns something:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">num1, num2</span>) </span>{
  <span class="hljs-keyword">const</span> result = num1 * num2
  <span class="hljs-keyword">return</span> result
}
</code></pre>
<p>If you want to transform this into an arrow function, here's what you'll have:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> multiply = <span class="hljs-function">(<span class="hljs-params">num1, num2</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> result = num1 * num2
  <span class="hljs-keyword">return</span> result
}
</code></pre>
<p>If the <code>return</code> statement is the only statement in the function, you can even have a shorter function expression. For example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> multiply = <span class="hljs-function">(<span class="hljs-params">num1, num2</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> num1 * num2
}
</code></pre>
<p>This function only contains the <code>return</code> statement. With arrow functions, we can have something shorter like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> multiply = <span class="hljs-function">(<span class="hljs-params">num1, num2</span>) =&gt;</span> num1 * num2
</code></pre>
<p>We skip the curly braces and the <code>return</code> keyword. Shorter; one-liner.</p>
<p>But the syntax of writing both types of functions is not the only difference. There's more, so let's look at them.</p>
<p>I have a <a target="_blank" href="https://youtu.be/M10gzHpIUDw">video version of this topic</a> which you can also check out :)</p>
<h2 id="heading-1-no-arguments-object-in-arrow-functions">1. No <code>arguments</code> object in arrow functions</h2>
<p>A normal function has an <code>arguments</code> object which you can access in the function:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">arguments</span>)
}
</code></pre>
<p>The <code>arguments</code> object is a local variable that contains the arguments passed to the function when called. Let's try it out:</p>
<pre><code class="lang-js">print(<span class="hljs-string">"hello"</span>, <span class="hljs-number">400</span>, <span class="hljs-literal">false</span>)

<span class="hljs-comment">// {</span>
<span class="hljs-comment">//   '0': 'hello',</span>
<span class="hljs-comment">//   '1': 400,</span>
<span class="hljs-comment">//   '2': false</span>
<span class="hljs-comment">// }</span>
</code></pre>
<p>As you can see here, the three arguments passed when calling <code>print()</code> are contained in the <code>arguments</code> object which we log to the console. We can access the first argument with <code>arguments[0]</code>, the second with <code>arguments[1]</code> and the third with <code>arguments[2]</code></p>
<p>But this object does not exist in arrow functions. Let's try it out. Say we have <code>print</code> using an arrow function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> print = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">arguments</span>)
}

print(<span class="hljs-string">"hello"</span>, <span class="hljs-number">400</span>, <span class="hljs-literal">false</span>)
<span class="hljs-comment">// Uncaught ReferenceError: arguments is not defined</span>
</code></pre>
<p>Now we have a reference error: <strong>arguments is not defined</strong>. That's because the <code>arguments</code> variable does not exist in arrow functions.</p>
<h2 id="heading-2-arrow-functions-do-not-create-their-own-this-binding">2. Arrow functions do not create their own <code>this</code> binding</h2>
<p>In normal functions, a <code>this</code> variable is created which references the objects that call them. For example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'deeecode'</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">print</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>)
  }
}

obj.print()
<span class="hljs-comment">// {</span>
<span class="hljs-comment">//   name: 'deeecode',</span>
<span class="hljs-comment">//   age: 200,</span>
<span class="hljs-comment">//   print: [Function: print]</span>
<span class="hljs-comment">// }</span>
</code></pre>
<p>As you can see here, the <code>this</code> in the <code>print</code> method points to <code>obj</code>, which is the object that calls the method.</p>
<p>Here's another example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'deeecode'</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">print</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print2</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>)
    }

    print2()
  }
}

obj.print()
<span class="hljs-comment">// Window</span>
</code></pre>
<p>Here, we have two functions. The first one is <code>print</code> which is a method of the <code>obj</code> object. The second is <code>print2</code> which is a function declared inside <code>print</code>. <code>print2()</code> is also called directly.</p>
<p>In this case, <code>print</code> is called by <code>obj</code> (<code>obj.print()</code>) but no object calls <code>print2</code> (<code>print2()</code>). So the <code>this</code> in <code>print2</code> would reference the window object by default.</p>
<p>Now let's see what happens with an arrow function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'deeecode'</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">print</span>: <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>)
  }
}

obj.print()
<span class="hljs-comment">// Window</span>
</code></pre>
<p>By using an arrow function for <code>print</code>, this function does not automatically create a <code>this</code> variable. As a result, any reference to <code>this</code> would point to what <code>this</code> was before the function was created.</p>
<p>As you see in the result, <code>this</code> was pointing to the <code>Window</code> object before <code>print</code> was created.</p>
<p>Let's see another example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'deeecode'</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">print</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> print2 = <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>)
    }

    print2()
  }
}

obj.print()
<span class="hljs-comment">// {</span>
<span class="hljs-comment">//   name: 'deeecode',</span>
<span class="hljs-comment">//   age: 200,</span>
<span class="hljs-comment">//   print: [Function: print]</span>
<span class="hljs-comment">// }</span>
</code></pre>
<p>Here, we have <code>print</code> as a normal function which means a <code>this</code> variable is automatically created in it. Then we have <code>print2</code> which is an arrow function.</p>
<p>Because <code>obj</code> is calling <code>print</code> (as in <code>obj.print()</code>), the <code>this</code> in <code>print</code> would point to <code>obj</code>.</p>
<p>Since <code>print2</code> is an arrow function, it doesn't create its own <code>this</code> variable. Therefore, any reference to <code>this</code> would point to what the value of <code>this</code> was before the function was created. In this case where <code>obj</code> calls <code>print</code>, <code>this</code> was pointing to <code>obj</code> before <code>print2</code> was created. As you can see in the results, by logging <code>this</code> from <code>print2</code>, <code>obj</code> is the result. </p>
<p>You can learn more about <a target="_blank" href="https://dillionmegida.com/p/this-demystified/"><code>this</code> in my article here</a></p>
<h2 id="heading-3-arrow-functions-cannot-be-used-as-constructors">3. Arrow functions cannot be used as constructors</h2>
<p>With normal functions, you can create constructors which serve as a special function for instantiating an object from a class.</p>
<p>Here is an example of an <code>Animal</code> class which we instantiate two objects from:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, numOfLegs) {
    <span class="hljs-built_in">this</span>.name = name
    <span class="hljs-built_in">this</span>.numOfLegs = numOfLegs
  }

  sayName() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`My name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>)
  }
}

<span class="hljs-keyword">const</span> Dog = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">"Bingo"</span>, <span class="hljs-number">4</span>)
<span class="hljs-keyword">const</span> Bird = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">"Steer"</span>, <span class="hljs-number">2</span>)

Dog.sayName()
<span class="hljs-comment">// My name is Bingo</span>

Bird.sayName()
<span class="hljs-comment">// My name is Steer</span>
</code></pre>
<p>Here, we have the <code>Animal</code> constructor which can be instantiated with different parameters. In the constructor, two arguments are required: <code>name</code> and <code>noOfLegs</code>.</p>
<p>In the case of <code>Dog</code>, we create a new instance of <code>Animal</code> using "Bingo" as the <code>name</code> and <strong>4</strong> as the <code>noOfLegs</code>.</p>
<p>In the case of <code>Bird</code>, we create a new instance of <code>Animal</code> using "Steer" as the <code>name</code> and <strong>2</strong> as the <code>noOfLegs</code>.</p>
<p>By calling <code>sayName</code> on <code>Dog</code> and <code>Bird</code>, you can see how the method works currently with each object. The <code>this</code> variable points to the objects and the <code>name</code> field is gotten from each of them.</p>
<p>The <code>this</code> variable is very important for classes and constructors. In point 2, we saw that arrow functions cannot create their own <code>this</code>. For this reason, arrow functions also cannot be used as constructors.</p>
<p>Let's attempt it and see what happens:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span> = (name, numOfLegs) =&gt; {
    <span class="hljs-built_in">this</span>.name = name
    <span class="hljs-built_in">this</span>.numOfLegs = numOfLegs
  }

  sayName() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`My name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>)
  }
}

<span class="hljs-comment">// Uncaught SyntaxError: Classes may not have a field named 'constructor'</span>
</code></pre>
<p>Here, we have an arrow function used for the <code>constructor</code>. But, we get a SyntaxError: <strong>Classes may not have a field named 'constructor'</strong>.</p>
<p>Because arrow functions involve expressions that are assigned variables, JavaScript now sees <code>constructor</code> as a field. And in classes, you cannot have a field named <code>constructor</code> as that is a reserved name.</p>
<p>But, we can use arrow functions for the methods in the class without getting errors. For example:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span> (name, numOfLegs){
    <span class="hljs-built_in">this</span>.name = name
    <span class="hljs-built_in">this</span>.numOfLegs = numOfLegs
  }

  sayName = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`My name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>)
  }
}

<span class="hljs-keyword">const</span> Dog = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">"Bingo"</span>, <span class="hljs-number">4</span>)

Dog.sayName()
<span class="hljs-comment">// My name is Bingo</span>
</code></pre>
<p>Here, we have a normal function for the <code>constructor</code>, and an arrow function for the <code>sayName</code> method. <code>sayName</code> is a field. And we do not get errors.</p>
<p>By calling <code>sayName()</code> on <code>Dog</code>, we still get "My name is Bingo". Though <code>sayName</code> as an arrow function does not create its own <code>this</code>, remember that any reference to <code>this</code> would point to the value of it before the arrow function was created. In this case, the value of <code>this</code> pointed to <code>Dog</code> before <code>sayName</code> was created.</p>
<h2 id="heading-4-arrow-functions-cannot-be-declared">4. Arrow functions cannot be declared</h2>
<p>When it comes to functions, you need to understand <strong>function declaration</strong> and <strong>function expression</strong>.</p>
<p>Function declarations involve the <code>function</code> keyword and a name for the function. For example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHello</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}
</code></pre>
<p><code>printHello</code> is a <strong>declared function</strong>. But, check out this example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> printHello = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}
</code></pre>
<p>In this case, <code>printHello</code> is not a declared function. We have an anonymous function (not named) on the right side of the assignment operator. This function is a <strong>function expression</strong>, which is assigned to the <code>printHello</code> variable.</p>
<p>Though the <code>function</code> keyword is used, there is no name assigned, which makes it an expression and not a declaration. To prove that it is not a declaration, try the following:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}
</code></pre>
<p>Because this expression is not assigned to a variable, you get an error: <strong>SyntaxError: Function statements require a function name</strong></p>
<p>Back to arrow functions. Normal functions can be declared when you use the function keyword and a name, but arrow functions cannot be declared. They can only be expressed because they are anonymous:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> printHello = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)
}
</code></pre>
<p>As you see here, we have an anonymous function (starting from <code>() =&gt; ...</code>) which is assigned to the <code>printHello</code> variable. <code>printHello</code> is not a declared function here. It is a variable that holds the evaluated value from the function expression.</p>
<h2 id="heading-5-arrow-functions-cannot-be-accessed-before-initialization">5 Arrow functions cannot be accessed before initialization</h2>
<p>Hoisting is a concept where a variable or function is lifted to the top of its global or local scope before the whole code is executed. This makes it possible for such a variable/function to be accessed before initialization. Here's a function example:</p>
<pre><code class="lang-js">printName()

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printName</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"i am dillion"</span>)
}

<span class="hljs-comment">// i am dillion</span>
<span class="hljs-comment">// hello</span>
</code></pre>
<p>As you can see here, we called <code>printName</code> before it was actually declared in the code. But we don't get any errors. <code>printName()</code> is executed (logging "i am dillion" to the console) before <code>console.log("hello")</code>.</p>
<p>What happens here is hoisting.</p>
<p>The <code>printName</code> function is raised to the top of the global scope (the scope it is declared in) before the whole code is executed, thereby making it possible to execute the function earlier.</p>
<p>But not all kinds of functions can be accessed before initialization. All functions and variables in JavaScript are hoisted, but <strong>only declared functions can be accessed before initialization</strong>.</p>
<p>Here's an example with an arrow function:</p>
<pre><code class="lang-js">printName()

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-keyword">const</span> printName = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"i am dillion"</span>)
}

<span class="hljs-comment">// ReferenceError: Cannot access 'printName' before initialization</span>
</code></pre>
<p>Running this code, you get an error: <strong>ReferenceError: Cannot access 'printName' before initialization</strong>. </p>
<p>As we saw in point 4, <code>printName</code> is not a declared function. It is a variable, declared with <code>const</code> which is assigned a function expression. Variables declared with <code>let</code> and <code>const</code> are hoisted, but they cannot be accessed before the line they are initialized.</p>
<p>Let's say we use <code>var</code> for our arrow function:</p>
<pre><code class="lang-js">printName()

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>)

<span class="hljs-keyword">var</span> printName = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"i am dillion"</span>)
}

<span class="hljs-comment">// TypeError: printName is not a function</span>
</code></pre>
<p>Here, we have declared the <code>printName</code> variable with <code>var</code>. The error we get now is <strong>TypeError: printName is not a function</strong>. The reason for this is that variables declared with <code>var</code> are hoisted and accessible, but they have a default value of <code>undefined</code>. So attempting to access <code>printName</code> before the line it was initialized with the function expression is interpreted as <code>undefined()</code>, and as you know, "undefined is not a function".</p>
<p>You can learn more about <a target="_blank" href="https://www.freecodecamp.org/news/javascript-let-and-const-hoisting/">the hoisting differences between var, let, and const here</a></p>
<h2 id="heading-wrap-up">Wrap up</h2>
<p>Although arrow functions allow you to write functions more concisely, they also have limitations. As we have seen in this article, some of the behaviors that occur in normal functions do not happen in arrow functions.</p>
<p>If you want to create constructors, retain the normal behavior of <code>this</code> or have your functions hoisted, then arrow functions are not the right approach.</p>
<p>If you enjoyed this article, please share it with others :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Build a 100 Days of Code Discord Bot with TypeScript, MongoDB, and Discord.js 13 ]]>
                </title>
                <description>
                    <![CDATA[ The 100 Days of Code challenge is very popular among new coders and developers looking to level up their skills. It's so popular that our Discord server has an entire channel dedicated to it. By popular demand, we built a Discord bot that helps peopl... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-100-days-of-code-discord-bot-with-typescript-mongodb-and-discord-js-13/</link>
                <guid isPermaLink="false">66ac7eac11cd6758aec202a8</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ bots ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding challenge ]]>
                    </category>
                
                    <category>
                        <![CDATA[ discord ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Naomi Carrigan ]]>
                </dc:creator>
                <pubDate>Mon, 31 Jan 2022 21:41:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/pexels-kindel-media-8566473.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <a target="_blank" href="https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/">100 Days of Code challenge</a> is very popular among new coders and developers looking to level up their skills. It's so popular that our <a target="_blank" href="https://www.freecodecamp.org/news/freecodecamp-discord-chat-room-server/">Discord server</a> has an entire channel dedicated to it.</p>
<p>By popular demand, we built a Discord bot that helps people track their progress in the challenge.</p>
<p>Today I am going to show you how to build your own 100 Days of Code bot.</p>
<blockquote>
<p>Note that discord.js has released version 14, which includes breaking changes. For compatibility with this tutorial, you will want to ensure you are using discord.js 13 - you can install this with <code>npm install discord.js@13</code>. If you have any questions, feel free to join my <a target="_blank" href="https://chat.nhcarrigan.com">discord server</a>. </p>
</blockquote>
<details>
    <summary>Contents</summary>
    <ul>
        <li>
            <a href="#create-a-discord-bot-application">Create a Discord Bot Application</a>
        </li>
        <li>
            <a href="#set-up-your-project">Set Up Your Project</a>
        </li>
        <li>
            <a href="#create-the-discord-bot">Create the Discord Bot</a>
        </li>
        <li>
            <a href="#gateway-events-in-discord">Gateway Events in Discord</a>
        </li>
        <li>
            <a href="#connect-to-the-database">Connect to the Database</a>
        </li>
        <li>
            <a href="#environment-variable-validation">Environment Variable Validation</a>
        </li>
        <li>
            <a href="#the-interaction-event">The "interaction" Event</a>
        </li>
        <li>
            <a href="#prepare-for-commands">Prepare for Commands</a>
        </li>
        <li>
            <a href="#database-model">Database Model</a>
        </li>
        <li>
            <a href="#write-bot-commands">Write Bot Commands</a>
        </li>
    </ul>
</details>

<h2 id="heading-create-a-discord-bot-application">Create a Discord Bot Application</h2>
<p>Your first step is to set up a Discord bot application. Head over to the <a target="_blank" href="https://discord.dev">Discord Developer Portal</a>, sign in if needed, and select "Applications" from the sidebar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-76.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the Developer Portal. If this is your first bot, you will not have any applications here.</em></p>
<p>Click the "New Application" button. Give it a name, and set it as a "Personal" application. You will now be taken to the application's settings. Here you can change the name, or give it an avatar.</p>
<p>Select "Bot" from the side bar, then click the "Add Bot" button. This will create a Discord Bot account for your application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-77.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the Bot settings page. If you did not set an avatar, you will see a default based on your bot's name.</em></p>
<p>This is the screen where you will get the bot token. It is <em>very</em> important to keep this token secret, as the token allows your code to connect to your bot. Keep it safe and do not share it with anyone.</p>
<p>Now you need to add the bot to a server to interact with it. Click the "OAuth2" option on the sidebar, then select "URL Generator".</p>
<p>Under "Scopes", select <code>bot</code> and <code>application.commands</code>. The <code>bot</code> scope allows your bot account to join the server, and the <code>application.commands</code> scope allows you to update the slash commands (more on this later).</p>
<p>When you select <code>bot</code>, a new section for "Bot Permissions" will appear. Select the following permissions:</p>
<ul>
<li>Send Messages</li>
<li>Embed Links</li>
<li>Read Messages/View Channels</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-78.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the OAuth screen with the required settings.</em></p>
<p>Copy the generated URL, and paste it into your browser. This will take you through Discord's process to add your new bot to a server. </p>
<p>Note that you must have the Manage Server permission in the server you want to add the bot to. If you do not have this permission, you can create a server to test your bot in.</p>
<p>Now you are ready to write some code!</p>
<h2 id="heading-set-up-your-project">Set Up Your Project</h2>
<p>You will first need to set up the infrastructure and tooling for your project.</p>
<p>Ensure that you have Node.js <strong>version 16</strong> and <code>npm</code> installed. Note that the packages you will use do not support earlier versions of Node.</p>
<h3 id="heading-prepare-the-packagejson">Prepare the <code>package.json</code></h3>
<p>Create a directory, or folder, for your project. Open your terminal pointing to that new folder. Run the command <code>npm init</code> to set up your <code>package.json</code> file. For this tutorial, the default values are sufficient, but feel free to edit them as you wish.</p>
<p>You should end up with a <code>package.json</code> similar to this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"100doc-tutorial"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>
}
</code></pre>
<p>Now you need to make a couple of changes to get ready for the TypeScript implementation.</p>
<p>First, replace the <code>main</code> value of <code>index.js</code> with <code>./prod/index.js</code> – you will be setting your TypeScript to compile to a <code>prod</code> directory.</p>
<p>Then remove the <code>test</code> script and add the following two scripts:</p>
<pre><code class="lang-json"><span class="hljs-string">"build"</span>: <span class="hljs-string">"tsc"</span>,
<span class="hljs-string">"start"</span>: <span class="hljs-string">"node -r dotenv/config ./prod/index.js"</span>
</code></pre>
<p>The <code>build</code> script will compile your TypeScript into JavaScript so Node can run it, and the <code>start</code> script will run the <code>index.js</code> entrypoint file.</p>
<p>Adding the <code>-r dotenv/config</code> here will dynamically import and run the <code>config</code> method in the <code>dotenv</code> package, which loads your environment variables from the <code>.env</code> file.</p>
<p>Speaking of packages, your next step is to install dependencies. Using <code>npm install</code>, install these dependencies:</p>
<ul>
<li><code>discord.js</code> – this is the library that will handle connecting to the gateway and managing the Discord API calls.</li>
<li><code>@discordjs/builders</code> – the discord.js package for constructing application commands</li>
<li><code>@discordjs/rest</code> – a custom API client for interacting with the Discord REST API.</li>
<li><code>discord-api-types</code> – Type definitions and handlers for the Discord REST API.</li>
<li><code>dotenv</code> – a package that loads <code>.env</code> values into the Node process.</li>
<li><code>mongoose</code> – A wrapper for the MongoDB connection which offers tools for structuring your data.</li>
</ul>
<p>Finally, install the development dependencies with <code>npm install --save-dev</code>. Development dependencies are packages that are required for working on your project in a development environment, but not required for running the codebase in production.</p>
<ul>
<li><code>typescript</code> – This is the package for the TypeScript language, which includes everything needed to write code in TypeScript and compile it into JavaScript.</li>
<li><code>@types/node</code> – TypeScript relies on type definitions to understand the code you write. This package defines the types for the Node.js runtime environment, such as the <code>process.env</code> object.</li>
</ul>
<p>With these packages installed, you should now have a <code>package.json</code> similar to this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"100doc-tutorial"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"./prod/index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"tsc"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node -r dotenv/config ./prod/index.js"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"@discordjs/builders"</span>: <span class="hljs-string">"^0.11.0"</span>,
    <span class="hljs-attr">"@discordjs/rest"</span>: <span class="hljs-string">"^0.2.0-canary.0"</span>,
    <span class="hljs-attr">"discord.js"</span>: <span class="hljs-string">"^13.6.0"</span>,
    <span class="hljs-attr">"dotenv"</span>: <span class="hljs-string">"^14.2.0"</span>,
    <span class="hljs-attr">"mongoose"</span>: <span class="hljs-string">"^6.1.7"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"@types/node"</span>: <span class="hljs-string">"^17.0.10"</span>,
    <span class="hljs-attr">"typescript"</span>: <span class="hljs-string">"^4.5.4"</span>
  }
}
</code></pre>
<h3 id="heading-prepare-typescript">Prepare TypeScript</h3>
<p>TypeScript's compiler offers a number of different settings to maximise your control over the resulting JavaScript.</p>
<p>You can typically modify the compiler settings through a <code>tsconfig.json</code> file at the root of your project. You can generate the default boilerplate for this file with <code>npx tsc --init</code>, use an existing one if you set one up in another project, or even write one from scratch.</p>
<p>Because the compiler settings can significantly change the behaviour of TypeScript, it is best to use the same settings when following this tutorial. Here are the settings you should use:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"ES6"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"CommonJS"</span>,
    <span class="hljs-attr">"rootDir"</span>: <span class="hljs-string">"./src"</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./prod"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"skipLibCheck"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"forceConsistentCasingInFileNames"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"resolveJsonModule"</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>The most important settings here are the <code>rootDir</code> and <code>outDir</code> settings. These tell the compiler that all of your code will be in the <code>src</code> directory, and the resulting JavaScript should go in the <code>prod</code> directory.</p>
<p>If you would like to test your settings, create a <code>src</code> directory and place an <code>index.ts</code> file inside. Write some code (such as a <code>console.log</code> statement) and run <code>npm run build</code> in your terminal. You should see a <code>prod</code> directory get created, with an <code>index.js</code> containing your compiled code.</p>
<h3 id="heading-additional-setup-notes">Additional Setup Notes</h3>
<p>If you are using <code>git</code> as a version control, you want to avoid pushing secrets and unnecessary code to your repository. Create a <code>.gitignore</code> file in your root project directory, and add the following content:</p>
<pre><code class="lang-txt">/node_modules/
/prod/
.env
</code></pre>
<p>The <code>.gitignore</code> file tells <code>git</code> not to track files/folders that match the patterns you enter. Ignoring the <code>node_modules</code> folder keeps your repository from becoming bloated.</p>
<p>Pushing the compiled JavaScript is also unnecessary, as your project is typically compiled in production before runtime. <code>.env</code> files contain secret values, such as API keys and tokens, so they should not be committed to a repository.</p>
<h2 id="heading-create-the-discord-bot">Create the Discord Bot</h2>
<p>Your next step is to prepare the initial bot connection. If you did not do so earlier, create a <code>src</code> directory and an <code>index.ts</code> file within.</p>
<p>Start with an anonymous immediately-invoked function expression (IIFE) to allow for top-level <code>await</code> use:</p>
<pre><code class="lang-ts">(<span class="hljs-keyword">async</span> () =&gt; {

})();
</code></pre>
<p>Within this function you are going to instantiate your Discord bot. At the top of the file, import the <code>Client</code> class with <code>import { Client } from "discord.js";</code>. The <code>Client</code> class represents your Discord bot's session.</p>
<p>Inside your function, construct a new <code>Client</code> instance and assign it to a <code>BOT</code> variable with <code>const BOT = new Client();</code>. Now the <code>BOT</code> variable will represent your bot.</p>
<p>To connect your bot to the Discord gateway and begin receiving events, you will need to use the <code>.login()</code> method on your bot instance. The <code>.login()</code> method takes a single argument, which is the token for the bot application you created earlier.</p>
<p>Many of the methods in <code>discord.js</code> are asynchronous, so you will need to use <code>await</code> here. Add the line <code>await BOT.login(process.env.BOT_TOKEN);</code> to your IIFE.</p>
<p>Your <code>index.ts</code> file should now look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> BOT = <span class="hljs-keyword">new</span> Client();

  <span class="hljs-keyword">await</span> BOT.login(process.env.BOT_TOKEN);
})();
</code></pre>
<p>If you try to run <code>npm run build</code>, you will see an error: <code>An argument for 'options' was not provided.</code></p>
<p>In discord.js 13, you are required to specify Gateway Intents when you instantiate your bot. Gateway Intents tell Discord what events your bot should receive.</p>
<p>In your <code>src</code> folder, create a <code>config</code> folder - then in <code>config</code>, create an <code>IntentOptions.ts</code> file.</p>
<p>Within that new file, add the line <code>export const IntentOptions = ["GUILDS"]</code>. This will tell Discord your bot should receive the Guild events.</p>
<p>Then, back in your <code>index.ts</code> file, add an argument to your <code>new Client()</code> call: <code>new Client({intents: IntentOptions})</code>. You'll need to import it at the top of your file with <code>import { IntentOptions } from "./config/IntentOptions;</code>. </p>
<p>It seems you still have an error: <code>Type 'string' is not assignable to type 'number |</code>${bigint}<code>| IntentsString | Readonly&lt;BitField&lt;IntentsString, number&gt;&gt; | RecursiveReadonlyArray&lt;number |</code>${bigint}<code>| IntentsString | Readonly&lt;...&gt;&gt;'.</code></p>
<p>TypeScript is inferring your <code>IntentOptions</code> array as a string, but the <code>Client</code> constructor is expecting more specific types. </p>
<p>Head back to your <code>config/IntentOptions.ts</code> file and add another import: <code>import { IntentsString } from "discord.js"</code>. Then update your variable with the new type definition: <code>export const IntentOptions: IntentsString[] = ["GUILDS"];</code>.</p>
<p>Now <code>npm run build</code> should be successful. If you have added your new bot to a Discord server, running <code>npm start</code> will show your bot come online in that server. However, the bot is not going to respond to anything yet, because you have not started listening to events.</p>
<h2 id="heading-gateway-events-in-discord">Gateway Events in Discord</h2>
<p>Gateway "events" are generated when an action happens on Discord, and are typically sent to clients (including your bot) as JSON payloads. You can listen to those events with the <code>.on()</code> method, allowing you to write logic for your bot to follow when specific events occur.</p>
<p>The first event to listen to is the "ready" event. This event fires when your bot has connected to the gateway and is <em>ready</em> to process events. Above your <code>.login()</code> call, add <code>BOT.on("ready", () =&gt; console.log("Connected to Discord!"));</code>. </p>
<p>For your changes to take effect, use <code>npm run build</code> again to compile the new code. Now if you try <code>npm run start</code>, you should see "Connected to Discord!" print in your terminal.</p>
<h2 id="heading-connect-to-the-database">Connect to the Database</h2>
<p>You'll be using the <code>mongoose</code> package to connect to a MongoDB instance. If you prefer, you can run MongoDB locally, or you can use the MongoDB Atlas free tier for a cloud-based solution. </p>
<p>If you do not have a MongoDB Atlas account, freeCodeCamp has a <a target="_blank" href="https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/">great tutorial on setting one up</a>.</p>
<p>Grab your connection string for your database and add it to your <code>.env</code> file as <code>MONGO_URI=""</code>, with the connection string going between the quotes. For the database name, use <code>oneHundredDays</code>.</p>
<p>Create a directory called <code>database</code> to hold the files that contain your database logic. Within that directory, create a file called <code>connectDatabase.ts</code>. You will be writing your logic to initiate the database connection here.</p>
<p>Start with an exported function declaration:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> connectDatabase = <span class="hljs-keyword">async</span> () =&gt; {

}
</code></pre>
<p><code>mongoose</code> offers a <code>connect</code> method for connecting to the database. Import it with <code>import { connect } from "mongoose";</code> at the top of your file.</p>
<p>Then use the method inside your function with <code>await connect(process.env.MONGO_URI);</code>. Add a <code>console.log</code> statement after that so you can identify that your bot has connected to the database. </p>
<p>Your <code>connectDatabase.ts</code> file should now look something like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { connect } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> connectDatabase = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> connect(process.env.MONGO_URI);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Database Connected!"</span>)
}
</code></pre>
<p>Now, within your <code>index.ts</code> file, import this function with <code>import { connectDatabase } from "./database/connectDatabase"</code> and add <code>await connectDatabase()</code> to your IIFE, just before the <code>.login()</code> method. Go ahead and run <code>npm run build</code> again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-157.png" alt="Image" width="600" height="400" loading="lazy">
<em>A compiler error, indicating that: Argument of type string or undefined is not assignable to parameter of type string.</em></p>
<p>Oh no – an error!</p>
<h2 id="heading-environment-variable-validation">Environment Variable Validation</h2>
<p>The problem with environment variables is that they can all be <code>undefined</code>. This often happens if you make a typo in your environment variable name, or mix the name up with another name (a mistake I made when writing this tutorial, using <code>TOKEN</code> instead of <code>BOT_TOKEN</code> in some places).</p>
<p>TypeScript is warning you that the <code>connect</code> method takes a string, and that an <code>undefined</code> value will break things. You can fix this, but first you will want to write a function to handle validating your environment variables.</p>
<p>Within your <code>src</code> directory, create a <code>utils</code> directory to contain your utility functions. Add a <code>validateEnv.ts</code> file there.</p>
<p>Create a function in the file called <code>validateEnv</code>. This function will be synchronous and does not need the <code>async</code> keyword. Within that function, add conditions to check for your two environment variables. If either one is missing, return <code>false</code>. Otherwise, return <code>true</code>.</p>
<p>Your code might look something like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> validateEnv = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (!process.env.BOT_TOKEN) {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Missing Discord bot token."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }

  <span class="hljs-keyword">if</span> (!process.env.MONGO_URI) {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Missing MongoDB connection."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
</code></pre>
<p>Head back to your <code>index.ts</code> file and import this validation function with <code>import { validateEnv } from "./utils/validateEnv"</code>. Then at the beginning of your IIFE, use an if statement to return early if the function returns false. Your <code>index.ts</code> should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { connectDatabase } <span class="hljs-keyword">from</span> <span class="hljs-string">"./database/connectDatabase"</span>;
<span class="hljs-keyword">import</span> { validateEnv } <span class="hljs-keyword">from</span> <span class="hljs-string">"./utils/validateEnv"</span>;

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">if</span> (!validateEnv()) <span class="hljs-keyword">return</span>;

  <span class="hljs-keyword">const</span> BOT = <span class="hljs-keyword">new</span> Client();

  BOT.on(<span class="hljs-string">"ready"</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected to Discord!"</span>));

  <span class="hljs-keyword">await</span> connectDatabase();

  <span class="hljs-keyword">await</span> BOT.login(process.env.BOT_TOKEN);
})();
</code></pre>
<p>If you try <code>npm run build</code> again, you will see the same error message as before. This is because while we know the environment variable exists, TypeScript still cannot infer it. The validation function is set up to exit the process if the environment variable is missing, so we are going to tell TypeScript that it is definitely a string.</p>
<p>Back in your <code>connectDatabase.ts</code> file, within the <code>connect</code> function use <code>process.env.MONGO_URI as string</code> to coerce the type into <code>string</code>. The error should go away, and you can now run <code>npm run build</code> and <code>npm start</code>. </p>
<p>You should see the messages you wrote for both the Discord and MongoDB connections print in your terminal.</p>
<h2 id="heading-the-interaction-event">The "interaction" Event</h2>
<p>While you are making great progress on your bot, it still does not <em>do</em> anything. In order to receive commands, you will need to create another event listener.</p>
<p>Discord rolled out slash commands, featuring a new UI and a new gateway event. The <code>interactionCreate</code> event is triggered when someone uses a slash command with your bot. This is the event you will want to listen to. Because the logic is a bit more complicated than the <code>ready</code> event, you will want to create a separate file.</p>
<p>Within your <code>src</code> directory, create an <code>events</code> directory, and an <code>onInteraction.ts</code> file in there. Start by defining an exported function <code>onInteraction</code>. This should be an asynchronous function, with a single parameter called <code>interaction</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onInteraction = <span class="hljs-keyword">async</span> (interaction) =&gt; {

};
</code></pre>
<p>To provide a type definition for your parameter, import the <code>Interaction</code> type from <code>discord.js</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Interaction } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onInteraction = <span class="hljs-keyword">async</span> (interaction: Interaction) =&gt; {

};
</code></pre>
<p>The <code>interaction</code> event actually triggers on any command interaction, which includes things like button clicks and select menus, as well as the slash commands we want. </p>
<p>Because you will only be writing slash commands for this bot, you can filter out any other interaction type and help TypeScript understand the data you are working with.</p>
<p>In your new function, add a condition to check <code>interaction.isCommand()</code>. You will be writing logic within this block later.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Interaction } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onInteraction = <span class="hljs-keyword">async</span> (interaction: Interaction) =&gt; {
  <span class="hljs-keyword">if</span> (interaction.isCommand()) {
  }
};
</code></pre>
<p>Now, back in your <code>index.ts</code> file, you can mount another listener. Next to your <code>.on("ready")</code> listener, add a <code>BOT.on("interactionCreate")</code> listener. For this event, the callback takes an <code>interaction</code> argument which you can pass to your new <code>onInteraction</code> function.</p>
<pre><code class="lang-ts">  BOT.on(
    <span class="hljs-string">"interactionCreate"</span>,
    <span class="hljs-keyword">async</span> (interaction) =&gt; <span class="hljs-keyword">await</span> onInteraction(interaction)
  );
</code></pre>
<p>Great! You can run <code>npm run build</code> to confirm that TypeScript doesn't throw any errors, but without actual commands to use you can't quite test this code yet.</p>
<h2 id="heading-prepare-for-commands">Prepare for Commands</h2>
<p>I maintain a few Discord bots, and one thing I've discovered that helps keep code maintainable and readable is making the components modular.</p>
<h3 id="heading-define-an-interface">Define an Interface</h3>
<p>You will first need to define a common structure for your commands. Create an <code>interfaces</code> folder in <code>src</code>. Then inside <code>interfaces</code> create a file called <code>Command.ts</code>.</p>
<p>Now you are going to create an interface. In TypeScript, an interface is often used to define the structure of an object, and is one of many tools available for declaring a variable's type.</p>
<p>In your <code>Command.ts</code> file, create an exported interface called <code>Command</code>:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Command {

}
</code></pre>
<p>Your interface will have two properties – <code>data</code>, which will hold the command data to send to Discord, and <code>run</code>, which will hold the callback function and command logic.</p>
<p>For the <code>data</code> property, import <code>SlashCommandBuilder</code> and <code>SlashCommandSubcommandsOnlyBuilder</code> from <code>@discordjs/builders</code>. Define the <code>data</code> property as either one of those two types.</p>
<p>For the <code>run</code> property, import the <code>CommandInteraction</code> type from <code>discord.js</code>. Define <code>run</code> as a function which takes a <code>CommandInteraction</code> typed parameter and returns a <code>void</code> Promise.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> {
  SlashCommandBuilder,
  SlashCommandSubcommandsOnlyBuilder,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { CommandInteraction } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CommandInt {
  data: SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder;
  run: <span class="hljs-function">(<span class="hljs-params">interaction: CommandInteraction</span>) =&gt;</span> <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">void</span>&gt;;
}
</code></pre>
<h3 id="heading-create-a-command-list">Create a Command List</h3>
<p>Next you need a place to store all of your commands. Create a folder called <code>commands</code> in the <code>src</code> directory, and add a file called <code>_CommandList.ts</code>. The underscore here will keep this file at the top of the list.</p>
<p>The <code>_CommandList.ts</code> file will need two lines. First, import your <code>Command</code> interface, then declare a <code>CommandList</code> array. The array will be empty for now, but give it a <code>Command[]</code> type so TypeScript knows it will eventually hold your command objects. The file should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CommandList: Command[] = [];
</code></pre>
<p>The purpose of this file is to create an array of your bot's commands which you will iterate over in the interaction event listener. <a target="_blank" href="https://github.com/BeccaLyria/discord-bot/blob/main/src/utils/readDirectory.ts">There are ways to automate this</a>, but they tend to be unnecessarily complex for smaller bots.</p>
<h3 id="heading-check-for-commands">Check for Commands</h3>
<p>Back in your <code>onInteraction.ts</code> file, you should start working on the logic for finding and running a command.</p>
<p>In your <code>interaction.isCommand()</code> condition block, loop through the <code>CommandList</code> array (remember to import it!) with a <code>for...of</code> loop. </p>
<pre><code class="lang-ts"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> Command <span class="hljs-keyword">of</span> CommandList) {

}
</code></pre>
<p>The interaction payload received from Discord includes a <code>commandName</code> property, which you can use to find the command that a user has selected. To check this, compare <code>interaction.commandName</code> with the <code>Command.data.name</code> property.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">if</span> (interaction.commandName === Command.data.name) {

}
</code></pre>
<p>Now, if you have found the command the user has chosen, you need to run the logic for that command. This is achieved with a <code>Command.run(interaction)</code> call – passing the interaction payload into the command.</p>
<p>Your final file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Interaction } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { CommandList } <span class="hljs-keyword">from</span> <span class="hljs-string">"../commands/_CommandList"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onInteraction = <span class="hljs-keyword">async</span> (interaction: Interaction) =&gt; {
  <span class="hljs-keyword">if</span> (interaction.isCommand()) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> Command <span class="hljs-keyword">of</span> CommandList) {
      <span class="hljs-keyword">if</span> (interaction.commandName === Command.data.name) {
        <span class="hljs-keyword">await</span> Command.run(interaction);
        <span class="hljs-keyword">break</span>;
      }
    }
  }
};
</code></pre>
<h2 id="heading-database-model">Database Model</h2>
<p>There's one more step before you are ready to start writing commands. This bot will track your community members' 100 Days of Code progress. And you need to store that progress in the database.</p>
<p><code>mongoose</code> helps structure your MongoDB records to prevent you from passing malformed or incomplete data into your database.</p>
<p>Start by creating a <code>models</code> folder in your <code>database</code> directory. In that <code>models</code> folder, create a <code>CamperModel.ts</code> file. This will be your structure for the user objects.</p>
<p>You first need to import the necessary values from the <code>mongoose</code> library. Add <code>import { Document, model, Schema } from "mongoose";</code> at the top of the file.</p>
<p>Because you are using TypeScript, you need to create a type definition for your database objects. Create another interface, like you did for your commands, named <code>CamperInt</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CamperInt <span class="hljs-keyword">extends</span> Document {

}
</code></pre>
<p>Your database model will have four properties. Add these to your interface:</p>
<ul>
<li><code>discordId: string;</code> – Every user object in Discord has a unique identifier, called a Snowflake, which is used to distinguish them from other users. Unlike a username or discriminator (the four digit number after the username), the <code>id</code> value cannot be changed. This makes it the ideal value for linking your stored data to a Discord user.</li>
<li><code>round: number;</code> – This will represent the "round" the user is on in the challenge. When someone completes 100 days of the challenge, they may choose to undertake the challenge again. When they do, they often refer to it as "round 2", for example. </li>
<li><code>day: number;</code> – This represents the day the user is on in the challenge.</li>
<li><code>timestamp: number;</code> – You will use this value to track when the user last submitted a 100 Days of Code post.</li>
</ul>
<p>Great! Now you need to define the Schema for your database entries. <code>mongoose</code> uses a Schema object to define the shape of the documents that go in to your database collection. The <code>Schema</code> import has a constructor, which you will assign to a variable.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema();
</code></pre>
<p>This constructor takes an object as its argument, and that object defines the database keys and types. Go ahead and pass in an object similar to what your interface looks like.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema({
    discordId: <span class="hljs-built_in">String</span>,
    round: <span class="hljs-built_in">Number</span>,
    day: <span class="hljs-built_in">Number</span>,
    timestamp: <span class="hljs-built_in">Number</span>,
})
</code></pre>
<p>Next you need to create the <code>model</code>. In <code>mongoose</code>, the <code>model</code> object serves to create, read, and update your documents in the MongoDB database. Add <code>export default model();</code> at the bottom of your file.</p>
<p>The <code>model</code> function takes a few parameters. The first is a string, and is the name to use for the documents in your database. For this collection, use <code>"camper"</code>. The second argument is the schema to use for the data – use your <code>Camper</code> schema there.</p>
<p>By default, <code>mongoose</code> will use the plural version of your <code>model</code> name for the collection. In our case, that would be "campers". If you want to change that, you can pass in a third argument of <code>{ collection: "name" }</code> to set the collection to <code>name</code>.</p>
<p>If you were using JavaScript, this would be enough to get your database model set up. However, because you are using TypeScript, you should take advantage of the type safety. <code>model()</code> by default returns a <code>Document</code> type of <code>any</code>. </p>
<p>To resolve this, you can pass a generic type into the <code>model</code> function. Generic types serve as variables for type definitions, in a sense. You need to set the generic type for your <code>model</code> to use your interface. Add the generic type by changing <code>model</code> to <code>model&lt;CamperInt&gt;</code>.</p>
<p>Just one more step here. Your <code>CamperInt</code> interface only defines the properties you set in the MongoDB document, but doesn't include the standard properties. </p>
<p>Change your <code>export interface CamperInt</code> to <code>export interface CamperInt extends Document</code>. This tells TypeScript that your type definition is an extension of the existing <code>Document</code> type definition – you are essentially adding properties to that structure.</p>
<p>Your final file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Document, model, Schema } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CamperInt {
  discordId: <span class="hljs-built_in">string</span>;
  round: <span class="hljs-built_in">number</span>;
  day: <span class="hljs-built_in">number</span>;
  timestamp: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema({
  discordId: <span class="hljs-built_in">String</span>,
  round: <span class="hljs-built_in">Number</span>,
  day: <span class="hljs-built_in">Number</span>,
  timestamp: <span class="hljs-built_in">Number</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> model&lt;CamperInt&gt;(<span class="hljs-string">"camper"</span>, Camper);
</code></pre>
<p>As a safety check, use <code>npm run build</code> again. You should not see any errors in the terminal.</p>
<h2 id="heading-write-bot-commands">Write Bot Commands</h2>
<p>You are finally ready to start writing some commands! As this is a 100 Days of Code bot, you should start with the command for creating a 100 Days of Code update.</p>
<h3 id="heading-100-command">100 Command</h3>
<p>Within your <code>commands</code> folder, create a <code>oneHundred.ts</code> file. This will hold your 100 Days of Code command. Import your command interface with <code>import { Command } from "../interfaces/Command;</code>.</p>
<p>Now declare an exported variable <code>oneHundred</code> and give it the <code>Command</code> type:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {

};
</code></pre>
<p>First, create the <code>data</code> property. You will be using the <code>@discordjs/builders</code> package to build a slash command.</p>
<p>Start by importing the <code>SlashCommandBuilder()</code> from the <code>@discordjs/builders</code> package. Then, construct a new instance in the <code>data</code> property with <code>new SlashCommandBuilder()</code>. You're going to chain some methods here to pass the information you want into the builder.</p>
<p>The <code>.setName()</code> method allows you to set the name of your slash command. Set the name to <code>"100"</code>. The <code>setDescription()</code> option allows you to display a description of the command in Discord's UI. Set the description to <code>"Check in for the 100 Days of Code challenge."</code>.</p>
<p>Slash commands can also accept <code>option</code> values. These are used to take arguments from the user, and come in various types. For this command, you'll want a string option with the <code>addStringOption()</code> method. Option methods take a callback function, with an <code>option</code> parameter.</p>
<p>You can then chain methods on the <code>option</code> parameter to configure the information for the argument. Use the <code>.setName()</code> method to give the option a name of <code>"message"</code>, and the <code>.setDescription()</code> method to give it a description of <code>"The message to go in your 100 Days of Code update."</code>. Finally, use the <code>.setRequired()</code> method to set the option to be required.</p>
<p>Here's what you should have now:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"100"</span>)
    .setDescription(<span class="hljs-string">"Check in for the 100 Days of Code challenge."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
};
</code></pre>
<p>If you are coding in an IDE with Intellisense enabled, you may have noticed that this will throw a type error on the <code>data</code> property. This is because the <code>SlashCommandBuilder</code> actually returns an <code>Omit</code> type! An <code>Omit</code> type is used to tell TypeScript that the type is <em>almost</em> the same as another type, but with specific properties removed.</p>
<p>Head over to your <code>interfaces/Command.ts</code> file to update the type. Replace the <code>SlashCommandBuilder</code> type with <code>Omit&lt;SlashCommandBuilder, "addSubcommandGroup" | "addSubcommand"&gt;</code>. This will tell TypeScript that <code>data</code> should be a <code>SlashCommandBuilder</code>, but without those two specific properties.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> {
  SlashCommandBuilder,
  SlashCommandSubcommandsOnlyBuilder,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { CommandInteraction } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Command {
  data:
    | Omit&lt;SlashCommandBuilder, <span class="hljs-string">"addSubcommandGroup"</span> | <span class="hljs-string">"addSubcommand"</span>&gt;
    | SlashCommandSubcommandsOnlyBuilder;
  run: <span class="hljs-function">(<span class="hljs-params">interaction: CommandInteraction</span>) =&gt;</span> <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">void</span>&gt;;
}
</code></pre>
<p>Great! Now that your type error is resolved, head back over to your <code>oneHundred.ts</code> command file – it is time to write the command logic.</p>
<p>All of your bot's logic for responding to the command will go in the <code>run</code> property. As you did in your interface, start by creating an async function which takes an <code>interaction</code> argument. Then, let the first line of your function be <code>await interaction.deferReply();</code>.</p>
<p>Discord expects a bot to respond to a command within three seconds. Because this command may take longer to process, using the <code>.deferReply()</code> method sends an acknowledgement response that gives you a full 15 minutes to send the actual response.</p>
<p>Next, you need to extract some data from the command. First, destructure the <code>user</code> object out of the interaction payload with <code>const { user } = interaction;</code>. The <code>user</code> object represents the Discord user that called the command. </p>
<p>Then get the <code>message</code> option you sent with <code>const text = interaction.options.getString("message", true);</code>. With this line, you are accessing the <code>options</code> property of the interaction. The <code>.getString()</code> method specifically grabs a string option (remember that you created the option in <code>data</code>), and <code>"message"</code> is the <strong>name</strong> of the option. The <code>true</code> argument indicates that this is a required option, so TypeScript won't consider it nullable.</p>
<p>Your file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"100"</span>)
    .setDescription(<span class="hljs-string">"Check in for the 100 Days of Code challenge."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { user } = interaction;
    <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);
  },
};
</code></pre>
<p>The next step in this command would be to fetch data from your database. Because many of your commands will need to do this, you should create a module for it.</p>
<h3 id="heading-handling-the-database-logic">Handling the Database Logic</h3>
<p>Create a <code>src/modules</code> directory, and add a <code>getCamperData.ts</code> file within. Create an exported async function named <code>getCamperData</code>, and give it a string parameter named <code>id</code>. Then, within the function, you can query the database.</p>
<p>Import your <code>CamperModel</code> from the <code>database</code> directory, and use the <code>findOne()</code> method to query by the camper's <code>id</code>: <code>const camperData = await CamperModel.findOne({ discordId: id });</code>. </p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> CamperModel <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getCamperData = <span class="hljs-keyword">async</span> (id: <span class="hljs-built_in">string</span>) =&gt; {
  <span class="hljs-keyword">const</span> camperData = <span class="hljs-keyword">await</span> CamperModel.findOne({ id });
};
</code></pre>
<p>We still have one more step here. If the camper has not used the bot before, they won't have an existing database record. <code>findOne()</code> would return <code>null</code> in this case – so you can add a fallback value.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> CamperModel <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getCamperData = <span class="hljs-keyword">async</span> (id: <span class="hljs-built_in">string</span>) =&gt; {
  <span class="hljs-keyword">const</span> camperData =
    (<span class="hljs-keyword">await</span> CamperModel.findOne({ discordId: id })) ||
    (<span class="hljs-keyword">await</span> CamperModel.create({
      discordId: id,
      round: <span class="hljs-number">1</span>,
      day: <span class="hljs-number">0</span>,
      date: <span class="hljs-built_in">Date</span>.now(),
    }));
};
</code></pre>
<p>Finally, you need to <code>return</code> your data. Add <code>return camperData</code> at the end of the function. For extra type safety, define the return type of your function as <code>Promise&lt;CamperData&gt;</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> CamperModel, { CamperInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getCamperData = <span class="hljs-keyword">async</span> (id: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">Promise</span>&lt;CamperInt&gt; =&gt; {
  <span class="hljs-keyword">const</span> camperData =
    (<span class="hljs-keyword">await</span> CamperModel.findOne({ discordId: id })) ||
    (<span class="hljs-keyword">await</span> CamperModel.create({
      discordId: id,
      round: <span class="hljs-number">1</span>,
      day: <span class="hljs-number">0</span>,
      date: <span class="hljs-built_in">Date</span>.now(),
    }));
  <span class="hljs-keyword">return</span> camperData;
};
</code></pre>
<p>You now have a way to get camper data from the database, but you need a way to update it as well. Create another file in your <code>/src/modules</code> directory called <code>updateCamperData.ts</code>. This will handle the logic to increment a camper's progress.</p>
<p>Start with an exported async function called <code>updateCamperData</code>. It should take a <code>Camper</code> parameter, which would be the data you fetch from MongoDB.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CamperInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateCamperData = <span class="hljs-keyword">async</span> (Camper: CamperInt) =&gt; {

};
</code></pre>
<p>The only time you will update data is within the <code>/100</code> command – where you'll want to increment the camper's day count, check if they have started a new round, and update the timestamp.</p>
<p>First, increment the day count with <code>Camper.day++;</code>. With the way the 100 Days of Code challenge works, if a camper has passed day 100 then they have started a new "round". You'll need a condition to check if <code>Camper.day &gt; 100</code>, and if so, reset the day to 1 and increment the round. </p>
<p>After that condition, update the timestamp with <code>Camper.timestamp = Date.now();</code> and save the data with <code>await Camper.save();</code>. Finally, return the modified data object so you can use it in the command.</p>
<p>Your final file should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CamperInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateCamperData = <span class="hljs-keyword">async</span> (Camper: CamperInt) =&gt; {
  Camper.day++;
  <span class="hljs-keyword">if</span> (Camper.day &gt; <span class="hljs-number">100</span>) {
    Camper.day = <span class="hljs-number">1</span>;
    Camper.round++;
  }
  Camper.timestamp = <span class="hljs-built_in">Date</span>.now();
  <span class="hljs-keyword">await</span> Camper.save();
  <span class="hljs-keyword">return</span> Camper;
};
</code></pre>
<h3 id="heading-100-command-continued">100 Command Continued</h3>
<p>Now that your database logic is ready, return to your <code>oneHundred.ts</code> file. As a reminder, that file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"100"</span>)
    .setDescription(<span class="hljs-string">"Check in for the 100 Days of Code challenge."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { user } = interaction;
    <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);
  },
};
</code></pre>
<p>Import your two new modules at the top of the file. Then, after your logic that extracts the values from the interaction object, fetch the camper's data from the database with <code>const targetCamper = await getCamperData(user.id);</code>. Update the data with <code>const updatedCamper = await updateCamperData(targetCamper);</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;
<span class="hljs-keyword">import</span> { getCamperData } <span class="hljs-keyword">from</span> <span class="hljs-string">"../modules/getCamperData"</span>;
<span class="hljs-keyword">import</span> { updateCamperData } <span class="hljs-keyword">from</span> <span class="hljs-string">"../modules/updateCamperData"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"100"</span>)
    .setDescription(<span class="hljs-string">"Check in for the 100 Days of Code challenge."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { user } = interaction;
    <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);

    <span class="hljs-keyword">const</span> targetCamper = <span class="hljs-keyword">await</span> getCamperData(user.id);
    <span class="hljs-keyword">const</span> updatedCamper = <span class="hljs-keyword">await</span> updateCamperData(targetCamper);
  },
};
</code></pre>
<p>Now you need to construct the response to send back to the camper when they use the command. </p>
<p>For this, you'll be using Discord's message embed feature. Start by importing the <code>MessageEmbed</code> constructor from discord.js, and creating a new embed with <code>const oneHundredEmbed = new MessageEmbed();</code>. The <code>MessageEmbed</code> class has a few methods to use for building the content of the embed.</p>
<p>Use the <code>.setTitle()</code> method to set the title of the embed to <code>"100 Days of Code"</code>. </p>
<p>Use the <code>.setDescription()</code> method to set the description of the embed to the message the camper provided in the command (remember that you extracted this to the <code>text</code> variable earlier). The author of the embed can be set, and will display at the top of the embed. </p>
<p>Use the <code>.setAuthor()</code> method to pass an object with a <code>name</code> property set to <code>user.tag</code> (which will display the camper's username and discriminator, like <code>nhcarrigan#0001</code>), and an <code>iconURL</code> property set to <code>user.displayAvatarUrl()</code> (which will attach the camper's avatar to the embed).</p>
<p>Embeds also accept fields, which are smaller blocks of text that have their own title and description. The <code>.addField()</code> method takes two or three arguments, the first being the field title, the second being the field description, and the third being an optional boolean to set the field as inline. </p>
<p>Use the <code>.addField()</code> method to add two fields. The first should have the title set to <code>"Round"</code> and the description set to <code>updatedCamper.round.toString()</code>. The second should have the title set to <code>"Day"</code> and the description set to <code>updatedCamper.day.toString()</code>. Both fields should be inline.</p>
<p>For the last part of your embed, use the <code>.setFooter()</code> method to add small footer text. Pass an object with a <code>text</code> property set to <code>"Day completed: " + new Date(updatedCamer.timestamp).toLocaleDateString()</code> to show the time the camper reported their progress.</p>
<p>Finally, you need to send this new embed back to the camper. Because you have already sent a response with the <code>interaction.deferReply()</code> call, you cannot send another response. Instead, you need to edit the one you sent.</p>
<p>Use <code>await interaction.editReply()</code> to edit the response. The <code>.editReply()</code> method takes an object with various properties – in this case, you are sending an embed. Pass an object with an <code>embeds</code> property set to <code>[oneHundredEmbed]</code>. </p>
<p>Note that this is an array containing your embed. Discord messages can contain up to 10 embeds, and the API expects an array of embed objects to match.</p>
<p>Your final command file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;
<span class="hljs-keyword">import</span> { getCamperData } <span class="hljs-keyword">from</span> <span class="hljs-string">"../modules/getCamperData"</span>;
<span class="hljs-keyword">import</span> { updateCamperData } <span class="hljs-keyword">from</span> <span class="hljs-string">"../modules/updateCamperData"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"100"</span>)
    .setDescription(<span class="hljs-string">"Check in for the 100 Days of Code challenge."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { user } = interaction;
    <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);

    <span class="hljs-keyword">const</span> targetCamper = <span class="hljs-keyword">await</span> getCamperData(user.id);
    <span class="hljs-keyword">const</span> updatedCamper = <span class="hljs-keyword">await</span> updateCamperData(targetCamper);

    <span class="hljs-keyword">const</span> oneHundredEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    oneHundredEmbed.setTitle(<span class="hljs-string">"100 Days of Code"</span>);
    oneHundredEmbed.setDescription(text);
    oneHundredEmbed.setAuthor({
      name: user.tag,
      iconURL: user.displayAvatarURL(),
    });
    oneHundredEmbed.addField(<span class="hljs-string">"Round"</span>, updatedCamper.round.toString(), <span class="hljs-literal">true</span>);
    oneHundredEmbed.addField(<span class="hljs-string">"Day"</span>, updatedCamper.day.toString(), <span class="hljs-literal">true</span>);
    oneHundredEmbed.setFooter({
      text:
        <span class="hljs-string">"Day completed: "</span> +
        <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(updatedCamper.timestamp).toLocaleDateString(),
    });

    <span class="hljs-keyword">await</span> interaction.editReply({ embeds: [oneHundredEmbed] });
  },
};
</code></pre>
<h3 id="heading-registering-commands">Registering Commands</h3>
<p>If you run <code>npm run build</code> and <code>npm start</code>, everything starts up – but you have no way to actually use your new command. This is because Discord requires that commands be registered so they are made available in the application UI. There are a few steps we'll need to take to do this.</p>
<p>First, head over to your <code>_CommandList.ts</code> file and import your <code>oneHundred</code> command. Add this to your <code>CommandList</code> array so it's available elsewhere. </p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;
<span class="hljs-keyword">import</span> { oneHundred } <span class="hljs-keyword">from</span> <span class="hljs-string">"./oneHundred"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CommandList: Command[] = [oneHundred];
</code></pre>
<p>Now it is time to add the logic to send the command information to Discord. In your <code>src/events</code> directory, add an <code>onReady.ts</code> file. We'll be using this with the <code>"ready"</code> event.</p>
<p>Create an exported async function named <code>onReady</code>, and give it a single parameter called <code>BOT</code>. Import the <code>Client</code> type from discord.js and set the <code>BOT</code> typedef to <code>Client</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onReady = <span class="hljs-keyword">async</span> (BOT: Client) =&gt; {};
</code></pre>
<p>Now import the <code>REST</code> module from <code>@discordjs/rest</code>. This will allow you to instantiate an API client, which you'll use to send the commands. Construct a new instance with <code>const rest = new REST();</code>. </p>
<p>There are a couple of things you'll need to configure with your REST client. First, pass an object into the <code>REST()</code> constructor with a <code>version</code> property set to <code>"9"</code>. This tells the client to use version 9 of Discord's API, which is currently the latest version. </p>
<p>Then, chain a <code>.setToken()</code> call on the constructor to set the API token to <code>process.env.BOT_TOKEN</code> – you'll have to coerce this to a <code>string</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { REST } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/rest"</span>;
<span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onReady = <span class="hljs-keyword">async</span> (BOT: Client) =&gt; {
  <span class="hljs-keyword">const</span> rest = <span class="hljs-keyword">new</span> REST({ version: <span class="hljs-string">"9"</span> }).setToken(
    process.env.BOT_TOKEN <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>
  );
};
</code></pre>
<p>The API expects command data to be sent in a specific JSON format, but thankfully the slash command builder we are using has a method just for that. Import your <code>CommandList</code>, then create a new array and map your command data.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> commandData = CommandList.map(<span class="hljs-function">(<span class="hljs-params">command</span>) =&gt;</span> command.data.toJSON());
</code></pre>
<p>Before you send the commands to Discord, it's important to note that there are two types of commands. "Global Commands" are available everywhere your bot is used, but take about an hour to update. "Guild Commands" are available only in a single server, but update immediately. Because this bot is designed to run in a single server, we're going to use guild commands.</p>
<p>You'll need to get the ID of the server you are using the bot in. To do this, make sure you have enabled developer mode in your Discord application, then right click on your server icon and select "Copy ID". In your <code>.env</code> file, add a <code>GUILD_ID</code> variable and assign it the ID you copied. It should look something like <code>GUILD_ID="778130114772598785"</code>.</p>
<p>Back in your <code>onReady.ts</code> file, start your API call with <code>await rest.put()</code>. Sending a <code>PUT</code> request will update any existing commands, where a <code>POST</code> will attempt to create new commands and error if commands share a name. Import <code>Routes</code> from <code>discord-api-types/v9</code>, and within the <code>rest.put()</code> call pass a <code>Routes.applicationGuildCommands()</code> call. This will be used to construct the API endpoint to send the commands to.</p>
<p>The <code>applicationGuildCommands()</code> call will take two arguments. </p>
<p>The first is the application ID to associate the commands with. You can get this from the <code>BOT.user.id</code> value – but <code>user</code> is potentially undefined, so you'll need to optionally chain it. Use <code>BOT.user?.id || "missing id"</code> to add a fallback value that will error out – this will allow us to know if the bot's ID is missing. </p>
<p>The second argument is the server ID, which you set up as <code>process.env.GUILD_ID</code> (remember to coerce the type!).</p>
<p>The <code>.put()</code> call needs a second argument as well, which is the data you want to send. Pass this as <code>{ body: commandData }</code> to match the expected format. </p>
<p>Finally, add a <code>console.log("Discord ready!")</code> at the end of the file to indicate your bot is online.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { REST } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/rest"</span>;
<span class="hljs-keyword">import</span> { Routes } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord-api-types/v9"</span>;
<span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { CommandList } <span class="hljs-keyword">from</span> <span class="hljs-string">"../commands/_CommandList"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onReady = <span class="hljs-keyword">async</span> (BOT: Client) =&gt; {
  <span class="hljs-keyword">const</span> rest = <span class="hljs-keyword">new</span> REST({ version: <span class="hljs-string">"9"</span> }).setToken(
    process.env.BOT_TOKEN <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>
  );

  <span class="hljs-keyword">const</span> commandData = CommandList.map(<span class="hljs-function">(<span class="hljs-params">command</span>) =&gt;</span> command.data.toJSON());

  <span class="hljs-keyword">await</span> rest.put(
    Routes.applicationGuildCommands(
      BOT.user?.id || <span class="hljs-string">"missing id"</span>,
      process.env.GUILD_ID <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>
    ),
    { body: commandData }
  );

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Discord ready!"</span>);
};
</code></pre>
<p>Switch to your <code>index.ts</code> file and locate your <code>"ready"</code> event listener. Replace the <code>console.log</code> call with your new <code>onReady</code> function – remember to import it, and make the callback asynchronous.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { IntentOptions } <span class="hljs-keyword">from</span> <span class="hljs-string">"./config/IntentOptions"</span>;
<span class="hljs-keyword">import</span> { connectDatabase } <span class="hljs-keyword">from</span> <span class="hljs-string">"./database/connectDatabase"</span>;
<span class="hljs-keyword">import</span> { onInteraction } <span class="hljs-keyword">from</span> <span class="hljs-string">"./events/onInteraction"</span>;
<span class="hljs-keyword">import</span> { onReady } <span class="hljs-keyword">from</span> <span class="hljs-string">"./events/onReady"</span>;
<span class="hljs-keyword">import</span> { validateEnv } <span class="hljs-keyword">from</span> <span class="hljs-string">"./utils/validateEnv"</span>;

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">if</span> (!validateEnv()) <span class="hljs-keyword">return</span>;
  <span class="hljs-keyword">const</span> BOT = <span class="hljs-keyword">new</span> Client({ intents: IntentOptions });

  BOT.on(<span class="hljs-string">"ready"</span>, <span class="hljs-keyword">async</span> () =&gt; <span class="hljs-keyword">await</span> onReady(BOT));

  BOT.on(
    <span class="hljs-string">"interactionCreate"</span>,
    <span class="hljs-keyword">async</span> (interaction) =&gt; <span class="hljs-keyword">await</span> onInteraction(interaction)
  );

  <span class="hljs-keyword">await</span> connectDatabase();

  <span class="hljs-keyword">await</span> BOT.login(process.env.BOT_TOKEN);
})();
</code></pre>
<p>Now run <code>npm run build</code> and <code>npm start</code>, and head to your server in Discord. If you type <code>/</code> you should see your new <code>/100</code> command show up. Try using the command and checking the response.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-122.png" alt="Image" width="600" height="400" loading="lazy">
<em>If you see this response, then you've successfully created your first command!</em></p>
<p>Congratulations! You have your first successful command. With all of the infrastructure you've built, adding additional commands will be much smoother. Let's go ahead and do that now.</p>
<h3 id="heading-edit-command">Edit Command</h3>
<p>What happens if a camper makes a typo in their <code>/100</code> message? Because the bot sends the response, the camper cannot edit it (Discord does not allow you to edit messages you did not send). You should create a command that will allow a camper to do this.</p>
<p>Create an <code>edit.ts</code> file in your <code>src/commands</code> directory. Like you did with the <code>/100</code> command, import your <code>SlashCommandBuilder</code> and <code>Command</code> interface, and export an <code>edit</code> object with the <code>Command</code> type.</p>
<p>Use the <code>SlashCommandBuilder</code> to prepare the <code>data</code> property. Give the command the name <code>edit</code> and the description <code>Edit a previous 100 days of code post.</code>, then add two string options. The first string option should have a name <code>embed-id</code> and a description of <code>ID of the message to edit.</code>, and the second should have a name of <code>message</code> and a description of <code>The message to go in your 100 Days of Code update.</code>. Both options should be required.</p>
<p>Your code should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> edit: Command = {
    data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"edit"</span>)
    .setDescription(<span class="hljs-string">"Edit a previous 100 days of code post."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"embed-id"</span>)
        .setDescription(<span class="hljs-string">"ID of the message to edit."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    )
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
}
</code></pre>
<p>Create your <code>run</code> property with an async function and an <code>interaction</code> parameter. Destructure the <code>channel</code> and <code>user</code> from the interaction, and grab the <code>embed-id</code> and <code>message</code> options. Don't forget to defer the response!</p>
<pre><code class="lang-js">    run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
        <span class="hljs-keyword">await</span> interaction.deferReply();
        <span class="hljs-keyword">const</span> { channel, user } = interaction;
        <span class="hljs-keyword">const</span> targetId = interaction.options.getString(<span class="hljs-string">"embed-id"</span>, <span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);
    }
</code></pre>
<p>The <code>channel</code> property is nullable (in cases where an interaction is sent via a DM, for example), so you'll want to check that it exists. If it does not, respond with a message that the command is missing parameters.</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">if</span> (!channel) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content: <span class="hljs-string">"Missing channel parameter."</span>,
      });
      <span class="hljs-keyword">return</span>;
    }
</code></pre>
<p>Now that you know the channel exists, you can fetch the message that the camper wants to edit based on the ID they provided. Use <code>channel.messages.fetch()</code> to do this, passing in the <code>targetId</code> as the argument.</p>
<p>Because it is possible that the target message does not exist, you need to account for that in your code. Add a condition that checks for this, and if the message is not found respond with an explanation.</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">const</span> targetMessage = <span class="hljs-keyword">await</span> channel.messages.fetch(targetId);

    <span class="hljs-keyword">if</span> (!targetMessage) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content:
          <span class="hljs-string">"That does not appear to be a valid message ID. Be sure that you are using this command in the same channel as the message."</span>,
      });
      <span class="hljs-keyword">return</span>;
    }
</code></pre>
<p>The last thing you need to check is that the message the camper is editing actually belongs to them. You can access the embed with the <code>.embeds</code> property – much like how you sent it, the property is returned as an array of embed objects.</p>
<p>Grab the first embed from the array, and then check that the embed author matches the user's tag. If not, let them know they cannot edit this post.</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">const</span> targetEmbed = targetMessage.embeds[<span class="hljs-number">0</span>];

    <span class="hljs-keyword">if</span> (targetEmbed.author?.name !== user.tag) {
        <span class="hljs-keyword">await</span> interaction.editReply({
            content: <span class="hljs-string">"This does not appear to be your 100 Days of Code post. You cannot edit it."</span>
        })
    }
</code></pre>
<p>Now that you have confirmed everything is correct, you can use <code>.setDescription()</code> on the embed to update the text. Then, edit the message with the new embed, and respond to the interaction with a confirmation.</p>
<p>Your full code should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> edit: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"edit"</span>)
    .setDescription(<span class="hljs-string">"Edit a previous 100 days of code post."</span>)
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"embed-id"</span>)
        .setDescription(<span class="hljs-string">"ID of the message to edit."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    )
    .addStringOption(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span>
      option
        .setName(<span class="hljs-string">"message"</span>)
        .setDescription(<span class="hljs-string">"The message to go in your 100 Days of Code update."</span>)
        .setRequired(<span class="hljs-literal">true</span>)
    ),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { channel, user } = interaction;
    <span class="hljs-keyword">const</span> targetId = interaction.options.getString(<span class="hljs-string">"embed-id"</span>, <span class="hljs-literal">true</span>);
    <span class="hljs-keyword">const</span> text = interaction.options.getString(<span class="hljs-string">"message"</span>, <span class="hljs-literal">true</span>);

    <span class="hljs-keyword">if</span> (!channel) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content: <span class="hljs-string">"Missing channel parameter."</span>,
      });
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> targetMessage = <span class="hljs-keyword">await</span> channel.messages.fetch(targetId);

    <span class="hljs-keyword">if</span> (!targetMessage) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content:
          <span class="hljs-string">"That does not appear to be a valid message ID. Be sure that you are using this command in the same channel as the message."</span>,
      });
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> targetEmbed = targetMessage.embeds[<span class="hljs-number">0</span>];

    <span class="hljs-keyword">if</span> (targetEmbed.author?.name !== user.tag) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content:
          <span class="hljs-string">"This does not appear to be your 100 Days of Code post. You cannot edit it."</span>,
      });
    }

    targetEmbed.setDescription(text);
    <span class="hljs-keyword">await</span> targetMessage.edit({ embeds: [targetEmbed] });
    <span class="hljs-keyword">await</span> interaction.editReply({ content: <span class="hljs-string">"Updated!"</span> });
  },
};
</code></pre>
<p>Add your new <code>edit</code> command to your <code>CommandList</code> array, then build and run your bot and you should see the new command. Try editing the embed you sent earlier.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-123.png" alt="Image" width="600" height="400" loading="lazy">
<em>You should see your embed update, and a confirmation from the bot!</em></p>
<h3 id="heading-view-command">View Command</h3>
<p>Campers should have a way to view their current progress, so we'll need to create a command to do so. By now, you should be comfortable with the command structure – we encourage you to follow these instructions but attempt to write the code without looking at the final result.</p>
<p>Create a <code>view.ts</code> file in your commands directory, and set up your command variable. Create the <code>data</code> property with a command that has the name <code>view</code> and the description <code>Shows your latest 100 days of code check in.</code> This command does not need any options.</p>
<p>Set up your async function in the <code>run</code> property, and defer the interaction response. Extract the <code>user</code> object from the interaction. Use your <code>getCamperData</code> module to fetch the camper's data from the database. Then, check if the data's <code>day</code> property has a non-zero value. If it does not, let the camper know that they have not started the 100 Days of Code challenge, and can do so with the <code>/100</code> command.</p>
<p>Create an embed with a title set to <code>My 100DoC Progress</code>. Set the description to <code>Here is my 100 Days of Code progress. I last reported an update on:</code> and add the camper's timestamp. Add a <code>Round</code> and <code>Day</code> field, and set the author for the embed. Then send the embed in the interaction response.</p>
<p>Remember to add your new command to the <code>CommandList</code>, then try building and starting your bot. You should see the command available, and be able to get a response from it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-125.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you did not get the response, here is what your code should look like.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;
<span class="hljs-keyword">import</span> { getCamperData } <span class="hljs-keyword">from</span> <span class="hljs-string">"../modules/getCamperData"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> view: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"view"</span>)
    .setDescription(<span class="hljs-string">"Shows your latest 100 Days of Code check in."</span>),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> { user } = interaction;
    <span class="hljs-keyword">const</span> targetCamper = <span class="hljs-keyword">await</span> getCamperData(user.id);

    <span class="hljs-keyword">if</span> (!targetCamper.day) {
      <span class="hljs-keyword">await</span> interaction.editReply({
        content:
          <span class="hljs-string">"It looks like you have not started the 100 Days of Code challenge yet. Use `/100` and add your message to report your first day!"</span>,
      });
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> camperEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    camperEmbed.setTitle(<span class="hljs-string">"My 100DoC Progress"</span>);
    camperEmbed.setDescription(
      <span class="hljs-string">`Here is my 100 Days of Code progress. I last reported an update on <span class="hljs-subst">${<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
        targetCamper.timestamp
      ).toLocaleDateString()}</span>.`</span>
    );
    camperEmbed.addField(<span class="hljs-string">"Round"</span>, targetCamper.round.toString(), <span class="hljs-literal">true</span>);
    camperEmbed.addField(<span class="hljs-string">"Day"</span>, targetCamper.day.toString(), <span class="hljs-literal">true</span>);
    camperEmbed.setAuthor({
      name: user.tag,
      iconURL: user.displayAvatarURL(),
    });

    <span class="hljs-keyword">await</span> interaction.editReply({ embeds: [camperEmbed] });
  },
};
</code></pre>
<h3 id="heading-help-command">Help Command</h3>
<p>The last thing you need to build is a help command, which will explain how campers can interact with the bot. </p>
<p>Create your <code>help.ts</code> file in the command directory, and create your <code>data</code> property. Give the command the name <code>help</code> and the description <code>Provides information on using this bot.</code></p>
<p>Set up your <code>run</code> property with the async function, and remember to defer the reply. Create an embed, and use the description and fields to provide the information you would like to share with your campers. Send the embed in the interaction response. </p>
<p>Load your new help command into the <code>CommandList</code>, and build + start your bot to test it. You should see a response with the embed you created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/image-126.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Your embed might look different, depending on what information you chose to share. Here's the code that we used for the above embed:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SlashCommandBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">"@discordjs/builders"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { Command } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/Command"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> help: Command = {
  data: <span class="hljs-keyword">new</span> SlashCommandBuilder()
    .setName(<span class="hljs-string">"help"</span>)
    .setDescription(<span class="hljs-string">"Provides information on using this bot."</span>),
  run: <span class="hljs-keyword">async</span> (interaction) =&gt; {
    <span class="hljs-keyword">await</span> interaction.deferReply();
    <span class="hljs-keyword">const</span> helpEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    helpEmbed.setTitle(<span class="hljs-string">"100 Days of Code Bot!"</span>);
    helpEmbed.setDescription(
      <span class="hljs-string">"This discord bot is designed to help you track and share your 100 Days of Code progress."</span>
    );
    helpEmbed.addField(
      <span class="hljs-string">"Create today's update"</span>,
      <span class="hljs-string">"Use the `/100` command to create your update for today. The `message` will be displayed in your embed."</span>
    );
    helpEmbed.addField(
      <span class="hljs-string">"Edit today's update"</span>,
      <span class="hljs-string">"Do you see a typo in your embed? Right click it and copy the ID (you may need developer mode on for this), and use the `/edit` command to update that embed with a new message."</span>
    );
    helpEmbed.addField(
      <span class="hljs-string">"Show your progress"</span>,
      <span class="hljs-string">"To see your current progress in the challenge, and the day you last checked in, use `/view`."</span>
    );
    helpEmbed.setFooter({ text: <span class="hljs-string">`Version <span class="hljs-subst">${process.env.npm_package_version}</span>`</span> });
    <span class="hljs-keyword">await</span> interaction.editReply({ embeds: [helpEmbed] });
    <span class="hljs-keyword">return</span>;
  },
};
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You have successfully built a Discord bot for the 100 Days of Code challenge.</p>
<p>If you are interested in exploring further, you can view <a target="_blank" href="https://github.com/nhcarrigan/100-days-of-code-bot">the source code</a> for the live bot that inspired this tutorial, which includes custom error logging, external error reporting, and a documentation site.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Take the 2022 Become-a-Dev New Year's Resolution Challenge ]]>
                </title>
                <description>
                    <![CDATA[ Every year, millions of people create New Year's Resolutions. A vast majority of these will fail. But I've created one for you that I'm optimistic you can succeed with. This is all free and you'll learn a ton. There will be a lot of other people doin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/2022-become-a-dev-new-years-resolution-challenge/</link>
                <guid isPermaLink="false">66b8d1d080f2fbfc1b20bbcc</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ community ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Thu, 30 Dec 2021 15:54:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Take-the-2022-Become-a-Dev-New-Year-s-Resolution-Challenge.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every year, millions of people create New Year's Resolutions. A vast majority of these will fail. But I've created one for you that I'm optimistic you can succeed with. This is all free and you'll learn a ton.</p>
<p>There will be a lot of other people doing this challenge alongside you, ready to cheer you on. And you may be able to complete all of this before summer.</p>
<p>Here is what you will need:</p>
<ol>
<li>A Mac, Windows, or Linux computer</li>
<li>A twitter account (you can create one in about 5 minutes)</li>
<li>VS Code (you can install it in about 5 minutes)</li>
<li>A Hashnode developer blog (I'll show you how to create one.)</li>
<li>At least 30 minutes per day to do the <a target="_blank" href="https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/">#100DaysOfCode</a> challenge</li>
</ol>
<p>I've structured this challenge to be manageable, but gradually increase in involvement. By accepting this challenge, you agree to at least give the first step a try. After that, if you're not feeling it, it's perfectly fine to abandon this New Year's Resolution challenge.</p>
<p>Here are the 4 steps to the challenge.</p>
<h3 id="heading-step-1-max-out-your-stats-in-learn-tocode-rpg-takes-about-3-hours">Step #1: Max out your stats in Learn ToCode RPG (takes about 3 hours)</h3>
<p>A lot of people aren't sure whether they want to become developers. It's a lot of work. So we created this video game that simulates the process of learning to code and applying for developer jobs.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vLK4fOeiIEk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>One cool aspect of the game: you learn and apply real programming and computer science concepts.</p>
<p>The game currently has 6 different endings and 55 Easter eggs, and I encourage you to catch 'em all. But for the purpose of this challenge, you just need to max-out your skills.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Learn_to_Code_RPG_-_Press_Kit_--.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of Learn to Code RPG's stats view. Max these out by playing the game and answering quiz questions.</em></p>
<p>Here's more information about <a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-rpg/">Learn to Code RPG and how to install it</a>.</p>
<h3 id="heading-step-2-start-100daysofcode-takes-about-30-minutes-each-day-for-100-days">Step #2: Start #100DaysOfCode (takes about 30 minutes each day for 100 days)</h3>
<p>If you enjoyed Learn To Code RPG and are ready to dig deeper into learning coding, you can take the popular #100DaysOfCode challenge.</p>
<p>The rules are simple:</p>
<ol>
<li>Code at least a little bit each day</li>
<li>Tweet your status (what you did) using the #100DaysOfCode hashtag</li>
<li>Encourage at least 2 other people who have also tweeted out their #100DaysOfCode status by commenting on it.</li>
</ol>
<p>This is a popular challenge that thousands of people have done over the past 6 years. I wrote an entire <a target="_blank" href="https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/">history of the #100DaysOfCode challenge</a> if you're curious.</p>
<p>While you are doing #100DaysOfCode, you can proceed to steps 3 and 4.</p>
<h3 id="heading-step-3-complete-the-freecodecamp-relational-database-certification">Step #3: Complete the freeCodeCamp Relational Database Certification</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/freeCodeCamp-Relational-Database-Certification.png" alt="Image" width="600" height="400" loading="lazy">
<em>The freeCodeCamp Relational Database Certification running inside VS Code</em></p>
<p>This is a new 300-hour curriculum we published in 2021 (though it may take you less than that if you have some Linux / SQL experience).</p>
<p>It will teach you:</p>
<ul>
<li>Linux</li>
<li>Bash</li>
<li>SQL</li>
<li>Git</li>
<li>... and a lot of other command line tools</li>
</ul>
<p>Along the way, you'll build a dozen different projects – all interactively, inside the popular VS Code editor.</p>
<p>Here is more information about <a target="_blank" href="https://www.freecodecamp.org/news/how-to-run-freecodecamps-relational-databases-curriculum-using-docker-vscode-and-coderoad/">how to install the freeCodeCamp Relational Database Curriculum</a> on your Mac, Windows PC, or Linux computer.</p>
<h3 id="heading-step-4-publish-3-tutorials-on-your-hashnode-blog">Step #4: Publish 3 tutorials on your Hashnode blog</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Quincy_Larson_s_Blog_--.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot from my own Hashnode blog</em></p>
<p>Hashnode is a powerful blogging tool where you can publish articles on your own personal domain, but still get some discovery within their community. They make it easy to set up a blog.</p>
<p>As you learn about programming and technology, I encourage you to turn around and write about it. This will not only help other people who are learning alongside you – it will help you reinforce your own learning. As the saying goes, "To teach is to learn twice."</p>
<p>Here's <a target="_blank" href="https://www.freecodecamp.org/news/devblog-launch-your-developer-blog-own-domain/">how to set up your Hashnode developer blog</a>.</p>
<p>So for the final step in this challenge, you should write 3 short tutorials about programming concepts you've learned along the way.</p>
<p>And if you decide you want to reach an even wider audience, you can consider applying to become an author on freeCodeCamp's publication, which gets about a quarter-million readers each day. Here's <a target="_blank" href="https://www.freecodecamp.org/news/developer-news-style-guide/">the freeCodeCamp publication style guide</a> if you decide to apply.</p>
<h2 id="heading-thats-it-one-video-game-one-certification-and-3-blog-posts">That's it. One video game, one certification, and 3 blog posts.</h2>
<p>If this sounds like a reasonable challenge for your 2022 New Year's Resolution, I encourage you to go for it. Here's how you can accept the challenge: create a Twitter account if you don't have one yet and quote-retweet this tweet with the words "I'm in."</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/ossia/status/1476581551873925123"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>I will add you to <a target="_blank" href="https://twitter.com/i/lists/1476412934440067079">this Twitter List</a> and you'll be able to follow it and see what everyone else is doing, and how they're progressing.</p>
<p>And if you make it all the way through, let me know. I will add you to the 2022 Become-a-Dev Challenge Hall of Fame below. ☺️ Good luck!</p>
<h2 id="heading-the-2022-become-a-dev-challenge-hall-of-fame">The 2022 Become-a-Dev Challenge Hall of Fame</h2>
<ul>
<li>Nobody yet ☺️</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use TypeScript and MongoDB to Build a 100 Days of Code Discord Bot ]]>
                </title>
                <description>
                    <![CDATA[ The 100 Days of Code challenge is very popular among new coders and developers looking to level up their skills. It's so popular that our Discord server has an entire channel dedicated to it.  By popular demand, we recently built a Discord bot that h... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-100-days-of-code-bot-for-discord-using-typescript-and-mongodb/</link>
                <guid isPermaLink="false">66ac7f0d297ff4b6f39a55f1</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #chatbots ]]>
                    </category>
                
                    <category>
                        <![CDATA[ discord ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Naomi Carrigan ]]>
                </dc:creator>
                <pubDate>Tue, 22 Jun 2021 16:20:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/06/news-header.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <a target="_blank" href="https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/">100 Days of Code challenge</a> is very popular among new coders and developers looking to level up their skills. It's so popular that our <a target="_blank" href="https://www.freecodecamp.org/news/freecodecamp-discord-chat-room-server/">Discord server</a> has an entire channel dedicated to it. </p>
<p>By popular demand, we recently built a Discord bot that helps people track their progress in the challenge.</p>
<p>Today I am going to show you how to build your own 100 Days of Code bot.</p>
<h2 id="heading-how-to-create-a-discord-bot-application">How to Create a Discord Bot Application</h2>
<p>Your first step is to set up a Discord bot application. Head over to the <a target="_blank" href="https://discord.com/developers">Discord Developer Portal</a>, sign in if needed, and select "Applications" from the sidebar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-158.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the Developer Portal. If this is your first bot, you will not have any applications here.</em></p>
<p>Click the "New Application" button. Give it a name, and set it as a "Personal" application. You will now be taken to the application's settings. Here you can change the name, or give it an avatar.</p>
<p>Select "Bot" from the side bar, then click the "Add Bot" button. This will create a Discord Bot account for your application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-99.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the Bot settings page. If you did not set an avatar, you will see a default based on your bot's name.</em></p>
<p>This is the screen where you will get the bot token. It is <em>very</em> important to keep this token secret, as the token allows your code to connect to your bot. Keep it safe and do not share it with anyone.</p>
<p>Now you need to add the bot to a server to interact with it. Click the "OAuth2" option on the side bar. You should see a form under the "OAuth2 URL Generator" section. Leave the "Select Redirect URL" dropdown blank, and check the box for the "bot" scope.</p>
<p>An option to select permissions will appear. Check the boxes for the following permissions:</p>
<ul>
<li>Send Messages</li>
<li>Manage Messages</li>
<li>Embed Links</li>
<li>Read Message History</li>
<li>View Channels</li>
</ul>
<p>Above that section, you should see a URL generated. Click the "Copy" button to copy it, then paste it into your browser and go. </p>
<p>This will take you through Discord's process to add your new bot to a server. Note that you must have the Manage Server permission in the server you want to add the bot to. If you do not have this permission in any servers, you can create a server to test your bot in.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-156.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of the OAuth screen with the correct settings marked.</em></p>
<p>Now you are ready to write some code!</p>
<h2 id="heading-how-to-set-up-your-project">How to Set Up Your Project</h2>
<p>You need to set up the infrastructure and tooling for your project.</p>
<h3 id="heading-prepare-the-packagejson">Prepare the <code>package.json</code></h3>
<p>Create a directory, or folder, for your project. Open your terminal pointing to that new folder. Run the command <code>npm init</code> to set up your <code>package.json</code> file. For this tutorial, the default values are sufficient, but feel free to edit them as you wish.</p>
<p>You should end up with a <code>package.json</code> similar to this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"tutorial"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>
}
</code></pre>
<p>Now you need to make a couple of changes to get ready for the TypeScript implementation.</p>
<p>First, replace the <code>main</code> value of <code>index.js</code> with <code>./prod/index.js</code> – you will be setting your TypeScript to compile to a <code>prod</code> directory.</p>
<p>Then, remove the <code>test</code> script and add the following two scripts:</p>
<pre><code class="lang-json"><span class="hljs-string">"build"</span>: <span class="hljs-string">"tsc"</span>,
<span class="hljs-string">"start"</span>: <span class="hljs-string">"node -r dotenv/config ./prod/index.js"</span>
</code></pre>
<p>The <code>build</code> script will compile your TypeScript into JavaScript so <code>node</code> can run it, and the <code>start</code> script will run the <code>index.js</code> entrypoint file.</p>
<p>Adding the <code>-r dotenv/config</code> here will dynamically import and run the <code>config</code> method in the <code>dotenv</code> package, which loads your environment variables from the <code>.env</code> file.</p>
<p>Speaking of packages, your next step is to install dependencies. Using <code>npm install</code>, install these dependencies:</p>
<ul>
<li><code>discord.js</code> – this is the library that will handle connecting to the gateway and managing the Discord API calls.</li>
<li><code>dotenv</code> – a package that loads <code>.env</code> values into the node process.</li>
<li><code>mongoose</code> – A wrapper for the MongoDB connection which offers tools for structuring your data.</li>
</ul>
<p>Finally, install the development dependencies with <code>npm install --save-dev</code>. Development dependencies are packages that are required for working on your project in a development environment, but not required for running the codebase in production.</p>
<ul>
<li><code>typescript</code> – This is the package for the TypeScript language, which includes everything needed to write code in TypeScript and compile it into JavaScript.</li>
<li><code>@types/node</code> – TypeScript relies on type definitions to help understand the code you write. This package defines the types for the Node.js runtime environment, such as the <code>process.env</code> object.</li>
</ul>
<p>With these packages installed, you should now have a <code>package.json</code> similar to this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"tutorial"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"tsc"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node -r dotenv/config ./prod/index.js"</span>
  },
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"discord.js"</span>: <span class="hljs-string">"^12.5.3"</span>,
    <span class="hljs-attr">"dotenv"</span>: <span class="hljs-string">"^10.0.0"</span>,
    <span class="hljs-attr">"mongoose"</span>: <span class="hljs-string">"^5.12.14"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"@types/node"</span>: <span class="hljs-string">"^15.12.2"</span>,
    <span class="hljs-attr">"typescript"</span>: <span class="hljs-string">"^4.3.4"</span>
  }
}
</code></pre>
<h3 id="heading-prepare-typescript">Prepare TypeScript</h3>
<p>TypeScript's compiler offers a number of different settings to maximize your control over the resulting JavaScript. </p>
<p>You can typically modify compiler settings through a <code>tsconfig.json</code> file at the root of your project. You can generate the default boilerplate for this file with <code>npx tsc --init</code>, use an existing one if you set one up in another project, or even write one from scratch.</p>
<p>Because the compiler settings can significantly change the behaviour of TypeScript, it is best to use the same settings when following this tutorial. Here are settings you should use:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"ES6"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"CommonJS"</span>,
    <span class="hljs-attr">"rootDir"</span>: <span class="hljs-string">"./src"</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./prod"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"skipLibCheck"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"forceConsistentCasingInFileNames"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"resolveJsonModule"</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>The most important settings here are the <code>rootDir</code> and <code>outDir</code> settings. These tell the compiler that all of your code will be in the <code>src</code> directory, and the resulting JavaScript should go in the <code>prod</code> directory.</p>
<p>If you would like to test your settings, create a <code>src</code> directory and place an <code>index.ts</code> file inside. Write some code (such as a <code>console.log</code> statement) and run <code>npm run build</code> in your terminal. You should see a <code>prod</code> directory get created, with an <code>index.js</code> containing your compiled code.</p>
<h3 id="heading-additional-setup-notes">Additional Setup Notes</h3>
<p>If you are using <code>git</code> as a version control, you want to avoid pushing secrets and unnecessary code to your repository. Create a <code>.gitignore</code> file in your root project directory, and add the following content:</p>
<pre><code class="lang-txt">/node_modules/
/prod/
.env
</code></pre>
<p>The <code>.gitignore</code> file tells <code>git</code> not to track files/folders that match the patterns you enter. Ignoring the node modules folder keeps your repository from becoming bloated. </p>
<p>Pushing the compiled JavaScript is also unnecessary, as your project is typically compiled in production before runtime. <code>.env</code> files typically contain your secret values, such as API keys and tokens, so they should not be committed to a repository.</p>
<p>If you are using a UNIX based environment (such as Linux, or Git Bash on Windows), you can also add a <code>prebuild</code> script to your <code>package.json</code>. The <code>prebuild</code> script will automatically run before the <code>build</code> script when you use <code>npm run build</code>. I set mine to clean up the existing <code>prod</code> directory with <code>rm -r ./prod</code>.</p>
<h2 id="heading-how-to-create-the-discord-bot">How to Create the Discord Bot</h2>
<p>Your next step is to prepare the initial bot connection. If you did not do so earlier, create a <code>src</code> directory and an <code>index.ts</code> file within.</p>
<p>Start with an anonymous immediately-invoked function expression (IIFE) to allow for top-level <code>await</code> use:</p>
<pre><code class="lang-ts">(<span class="hljs-keyword">async</span> () =&gt; {

})();
</code></pre>
<p>Within this function you are going to instantiate your Discord bot. At the top of the file, import the <code>Client</code> class with <code>import { Client } from "discord.js;"</code>. The <code>Client</code> class represents your Discord bot's session.</p>
<p>Inside your function, construct a new <code>Client</code> instance and assign it to a <code>BOT</code> variable with <code>const BOT = new Client();</code>. Now the <code>BOT</code> variable will represent your bot.</p>
<p>To connect your bot to Discord's gateway and begin receiving events, you will need to use the <code>.login()</code> method on your bot instance. The <code>.login()</code> method takes a single argument, which is the token for the bot application you created earlier. </p>
<p>Many of the methods in <code>discord.js</code> are asynchronous, so you will need to use <code>await</code> here. Add the line <code>await BOT.login(process.env.BOT_TOKEN);</code> to your IIFE.</p>
<p>The <code>process.env</code> object will contain the environment variables for your Node.js runtime environment. With the <code>dotenv</code> package, this will also include any variables you set in your <code>.env</code> secrets file. </p>
<p>Create that <code>.env</code> file in the root of your project, and add <code>BOT_TOKEN=""</code> as the first line. Between the quotes, paste the bot token from the bot page on the Discord Developer Portal.</p>
<p>Your <code>index.ts</code> file should now look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> BOT = <span class="hljs-keyword">new</span> Client();

  <span class="hljs-keyword">await</span> BOT.login(process.env.BOT_TOKEN);
})();
</code></pre>
<p>Assuming you added your new bot to a server, if you run <code>npm run build</code> and <code>npm start</code> you should see your bot come online in the server. However, the bot will not respond to anything yet, because we have not started listening to events.</p>
<h2 id="heading-gateway-events-in-discord">Gateway Events in Discord</h2>
<p>Gateway "events" are generated when an action happens on Discord, and are typically sent to clients (including your bot) as JSON payloads. You can listen to those events with the <code>.on()</code> method, allowing you to write logic for your bot to follow when specific events occur.</p>
<p>The first event to listen to is the "ready" event. This event fires when your bot has connected to the gateway and is <em>ready</em> to process events. Above your <code>.login()</code> call, add <code>BOT.on("ready", () =&gt; console.log("Connected to Discord!"));</code>. </p>
<p>For your changes to take effect, use <code>npm run build</code> again to compile the new code. Now if you try <code>npm run start</code>, you should see "Connected to Discord!" print in your terminal.</p>
<h2 id="heading-how-to-connect-to-the-database">How to Connect to the Database</h2>
<p>You'll be using the <code>mongoose</code> package to connect to a MongoDB instance. If you prefer, you can run MongoDB locally, or you can use the MongoDB Atlas free tier for a cloud-based solution. </p>
<p>If you do not have a MongoDB Atlas account, freeCodeCamp has a <a target="_blank" href="https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/">great tutorial on setting one up</a>.</p>
<p>Grab your connection string for your database and add it to your <code>.env</code> file as <code>MONGO_URI=""</code>, with the connection string going between the quotes. For the database name, use <code>oneHundredDays</code>.</p>
<p>Create a directory called <code>database</code> to hold the files that contain your database logic. Within that directory, create a file called <code>connectDatabase.ts</code>. You will be writing your logic to initiate the database connection here.</p>
<p>Start with an exported function declaration:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> connectDatabase = <span class="hljs-keyword">async</span> () =&gt; {

}
</code></pre>
<p><code>mongoose</code> offers a <code>connect</code> method for connecting to the database. Import it with <code>import { connect } from "mongoose";</code> at the top of your file.</p>
<p>Then use the method inside your function with <code>await connect(process.env.MONGO_URI);</code>. Add a <code>console.log</code> statement after that so you can identify that your bot has connected to the database. </p>
<p>Your <code>connectDatabase.ts</code> file should now look something like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { connect } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> connectDatabase = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> connect(process.env.MONGO_URI);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Database Connected!"</span>)
}
</code></pre>
<p>Now, within your <code>index.ts</code> file, import this function with <code>import { connectDatabase } from "./database/connectDatabase"</code> and add <code>await connectDatabase()</code> to your IIFE, just before the <code>.login()</code> method. Go ahead and run <code>npm run build</code> again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-157.png" alt="Image" width="600" height="400" loading="lazy">
<em>A compiler error, indicating that: Argument of type string or undefined is not assignable to parameter of type string.</em></p>
<p>Oh no – an error!</p>
<h2 id="heading-environment-variable-validation">Environment Variable Validation</h2>
<p>The problem with environment variables is that they can all be <code>undefined</code>. This often happens if you make a typo in your environment variable name, or mix the name up with another name (a mistake I made when writing this tutorial, using <code>TOKEN</code> instead of <code>BOT_TOKEN</code> in some places).</p>
<p>TypeScript is warning you that the <code>connect</code> method takes a string, and that an <code>undefined</code> value will break things. You can fix this, but first you will want to write a function to handle validating your environment variables.</p>
<p>Within your <code>src</code> directory, create a <code>utils</code> directory to contain your utility functions. Add a <code>validateEnv.ts</code> file there.</p>
<p>Create a function in the file called <code>validateEnv</code>. This function will be synchronous and does not need the <code>async</code> keyword. Within that function, add conditions to check for your two environment variables. If either one is missing, return <code>false</code>. Otherwise, return <code>true</code>.</p>
<p>Your code might look something like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> validateEnv = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (!process.env.BOT_TOKEN) {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Missing Discord bot token."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }

  <span class="hljs-keyword">if</span> (!process.env.MONGO_URI) {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Missing MongoDB connection."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
</code></pre>
<p>Head back to your <code>index.ts</code> file and import this validation function with <code>import { validateEnv } from "./utils/validateEnv"</code>. Then at the beginning of your IIFE, use an if statement to return early if the function returns false. Your <code>index.ts</code> should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { connectDatabase } <span class="hljs-keyword">from</span> <span class="hljs-string">"./database/connectDatabase"</span>;
<span class="hljs-keyword">import</span> { validateEnv } <span class="hljs-keyword">from</span> <span class="hljs-string">"./utils/validateEnv"</span>;

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">if</span> (!validateEnv()) <span class="hljs-keyword">return</span>;

  <span class="hljs-keyword">const</span> BOT = <span class="hljs-keyword">new</span> Client();

  BOT.on(<span class="hljs-string">"ready"</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected to Discord!"</span>));

  <span class="hljs-keyword">await</span> connectDatabase();

  <span class="hljs-keyword">await</span> BOT.login(process.env.BOT_TOKEN);
})();
</code></pre>
<p>If you try <code>npm run build</code> again, you will see the same error message as before. This is because while we know the environment variable exists, TypeScript still cannot infer it. The validation function is set up to exit the process if the environment variable is missing, so we are going to tell TypeScript that it is definitely a string.</p>
<p>Back in your <code>connectDatabase.ts</code> file, within the <code>connect</code> function use <code>process.env.MONGO_URI as string</code> to coerce the type into <code>string</code>. The error should go away, and you can now run <code>npm run build</code> and <code>npm start</code>. </p>
<p>You should see the messages you wrote for both the Discord and MongoDB connections print in your terminal.</p>
<h2 id="heading-the-message-event">The "message" Event</h2>
<p>While you are making great progress on your bot, it still does not <em>do</em> anything. In order for the bot to respond to messages, you will need another event handler. </p>
<p>The logic in this one will be a bit more complicated, so you should create a separate module for it. Create an <code>events</code> folder in the <code>src</code> directory.</p>
<p>Within your <code>events</code> folder, create an <code>onMessage.ts</code> file. At the top, import the <code>Message</code> class from discord.js with <code>import { Message } from "discord.js";</code>. This class will serve as your type definition.</p>
<p>Then create an exported function called <code>onMessage</code>. The function should be asynchronous and take a <code>message</code> parameter with the <code>Message</code> type. Your function will look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Message } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> onMessage = <span class="hljs-keyword">async</span> (message: Message) =&gt; {

};
</code></pre>
<p>Before diving in to the logic for this function, you should attach it to the event listener. Back in your <code>index.ts</code> file, import your new function with <code>import { onMessage } from "./events/onMessage";</code>.</p>
<p>Next to your existing <code>.on("ready")</code> listener, add a <code>BOT.on("message")</code> listener. For the "message" event, the callback takes a <code>message</code> argument which you can pass to your new <code>onMessage</code> function:</p>
<pre><code class="lang-ts">BOT.on(<span class="hljs-string">"message"</span>, <span class="hljs-keyword">async</span> (message) =&gt; <span class="hljs-keyword">await</span> onMessage(message));
</code></pre>
<p>We should test that this works. Head back to your <code>onMessage.ts</code> file. Inside your <code>onMessage</code> function, add <code>console.log(message.content)</code>. The <code>.content</code> property on the <code>Message</code> class contains the text content sent in the message.</p>
<p>Use <code>npm run build</code> and <code>npm start</code> to get your bot running again, and then send "Hello" in a Discord channel the bot can see. You should see "Hello" print to your terminal.</p>
<h2 id="heading-how-to-prepare-for-commands">How to Prepare for Commands</h2>
<p>I maintain a few Discord bots, and one thing I've discovered that helps keep code maintainable and readable is making the components modular.</p>
<h3 id="heading-define-an-interface">Define an Interface</h3>
<p>You will first need to define a common structure for your commands. Create an <code>interfaces</code> folder in <code>src</code>. Then inside <code>interfaces</code> create a file <code>CommandInt.ts</code>.</p>
<p>Now you are going to create an interface. In TypeScript, an interface is often used to define the structure of an object, and is one of many tools available for declaring a variable's type.</p>
<p>In your <code>CommandInt.ts</code> file, import the Message class from Discord, then declare an interface called <code>CommandInt</code> with this syntax:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Message } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CommandInt {

}
</code></pre>
<p>Inside this interface, you are going to add three properties:</p>
<ul>
<li><code>name: string;</code> – the <code>name</code> value will be your command's name. You will use this to trigger the command in the Discord server.</li>
<li><code>description: string;</code> – the <code>description</code> value explains what the command does. You will used this in one of the commands.</li>
<li><code>run: (message: Message) =&gt; Promise&lt;void&gt;</code> – this is the property that will hold the command's logic.</li>
</ul>
<p>The <code>run</code> type definition is a bit tricky, so let's break it down. You have typed it as a function which takes one argument, <code>message</code>. That argument should be the <code>Message</code> type. You then set the function's <code>return</code> type to <code>Promise&lt;void&gt;</code>. This means your function will be asynchronous (this is important later) and does not return a value.</p>
<h3 id="heading-create-a-command-list">Create a Command List</h3>
<p>Next you need a place to store all of your commands. Create a folder called <code>commands</code> in the <code>src</code> directory, and add a file called <code>_CommandList.ts</code>. The underscore here will keep this file at the top of the list.</p>
<p>The <code>_CommandList.ts</code> file will need two lines. First, import your <code>CommandInt</code> interface, then declare a <code>CommandList</code> array. The array will be empty for now, but give it a <code>CommandInt[]</code> type so TypeScript knows it will eventually hold your command objects. The file should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CommandList: CommandInt[] = [];
</code></pre>
<p>The purpose of this file is to create an array of your bot's commands which you will iterate over in the message event listener. <a target="_blank" href="https://github.com/BeccaLyria/discord-bot/blob/main/src/utils/readDirectory.ts">There are ways to automate this</a>, but they tend to be unnecessarily complex for smaller bots.</p>
<h3 id="heading-check-for-commands">Check for Commands</h3>
<p>Back in your <code>onMessage.ts</code> file, you should start working on the logic to check messages for commands.</p>
<p>The first step is to ensure that your bot ignores its own messages, as well as the messages of other bots. This helps prevent endless cycles where the bot is responding to itself. </p>
<p>The <code>message</code> object has an <code>author</code> property, which represents the Discord user that sent the message. The <code>author</code> property has a <code>bot</code> property, which is a Boolean that indicates the author is a bot account. Add a step to check if this property is true:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">if</span> (message.author.bot) {
  <span class="hljs-keyword">return</span>;
}
</code></pre>
<p>You also want to prevent people from accidentally calling your bot's commands. For example, if you have a <code>help</code> command, you would not want the bot to respond when someone says "help me please".</p>
<p>This can be avoided by setting a prefix for the bot to detect. Most bots use <code>!</code>, but you are welcome to choose whichever prefix you would like. </p>
<p>Declare a variable <code>prefix</code> and assign it your chosen prefix, such as <code>const prefix = "!";</code>. Then add a condition to check if the <code>message.content</code> does not start with that prefix, and if so <code>return</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> prefix = <span class="hljs-string">"!"</span>;

<span class="hljs-keyword">if</span> (!message.content.startsWith(prefix)) {
  <span class="hljs-keyword">return</span>;
}
</code></pre>
<p>Now that you have verified that the message came from a user and is intentionally triggering your bot, you can check to see if the command is valid. </p>
<p>Using the (currently empty) <code>CommandList</code> array will facilitate this process, so import it at the top of your file with <code>import { CommandList } from "../commands/_CommandList";</code>.</p>
<p>There are a few ways to iterate through an array – for the live bot, I used a <code>for..of</code> loop. Regardless of the loop approach, you will want to check each command in the array against the message content. Here is a loop example:</p>
<pre><code class="lang-ts">  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> Command <span class="hljs-keyword">of</span> CommandList) {
    <span class="hljs-keyword">if</span> (message.content.startsWith(prefix + Command.name)) {
      <span class="hljs-keyword">await</span> Command.run(message);
      <span class="hljs-keyword">break</span>;
    }
  }
</code></pre>
<p>This loop iterates through the list of commands, and if the message content starts with the prefix and command name, the bot will call the command's <code>run</code> method. </p>
<p>Remember that you declared the <code>run</code> property to be an async function that took the message as an argument. Then, to save on compute time, the loop breaks when it finds a matching command.</p>
<h2 id="heading-database-model">Database Model</h2>
<p>There's one more step before you are ready to start writing commands. This bot will track your community members' 100 Days of Code progress. And you need to store that progress in the database.</p>
<p><code>mongoose</code> helps structure your MongoDB records to prevent you from passing malformed or incomplete data into your database.</p>
<p>Start by creating a <code>models</code> folder in your <code>database</code> directory. In that <code>models</code> folder, create a <code>CamperModel.ts</code> file. This will be your structure for the user objects.</p>
<p>You first need to import the necessary values from the <code>mongoose</code> library. Add <code>import { Document, model, Schema } from "mongoose";</code> at the top of the file.</p>
<p>Because you are using TypeScript, you need to create a type definition for your database objects. Create another interface, like you did for your commands, named <code>CamperInt</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CamperInt {

}
</code></pre>
<p>Your database model will have four properties. Add these to your interface:</p>
<ul>
<li><code>discordId: string;</code> – Every user object in Discord has a unique identifier, called a Snowflake, which is used to distinguish them from other users. Unlike a username or discriminator (the four digit number after the username), the <code>id</code> value cannot be changed. This makes it the ideal value for linking your stored data to a Discord user.</li>
<li><code>round: number;</code> – This will represent the "round" the user is on in the challenge. When someone completes 100 days of the challenge, they may choose to undertake the challenge again. When they do, they often refer to it as "round 2", for example. </li>
<li><code>day: number;</code> – This represents the day the user is on in the challenge.</li>
<li><code>timestamp: number;</code> – You will use this value to track when the user last submitted a 100 Days of Code post.</li>
</ul>
<p>Great! Now you need to define the Schema for your database entries. <code>mongoose</code> uses a Schema object to define the shape of the documents that go in to your database collection. The <code>Schema</code> import has a constructor, which you will assign to a variable.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema();
</code></pre>
<p>This constructor takes an object as its argument, and that object defines the database keys and types. Go ahead and pass in an object similar to what your interface looks like.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema({
    discordId: <span class="hljs-built_in">String</span>,
    round: <span class="hljs-built_in">Number</span>,
    day: <span class="hljs-built_in">Number</span>,
    timestamp: <span class="hljs-built_in">Number</span>,
})
</code></pre>
<p>Next you need to create the <code>model</code>. In <code>mongoose</code>, the <code>model</code> object serves to create, read, and update your documents in the MongoDB database. Add <code>export default model();</code> at the bottom of your file.</p>
<p>The <code>model</code> function takes a few parameters. The first is a string, and is the name to use for the documents in your database. For this collection, use <code>"camper"</code>. The second argument is the schema to use for the data – use your <code>Camper</code> schema there.</p>
<p>By default, <code>mongoose</code> will use the plural version of your <code>model</code> name for the collection. In our case, that would be "campers". If you want to change that, you can pass in a third argument of <code>{ collection: "name" }</code> to set the collection to <code>name</code>.</p>
<p>If you were using JavaScript, this would be enough to get your database model set up. However, because you are using TypeScript, you should take advantage of the type safety. <code>model()</code> by default returns a <code>Document</code> type of <code>any</code>. </p>
<p>To resolve this, you can pass a generic type into the <code>model</code> function. Generic types serve as variables for type definitions, in a sense. You need to set the generic type for your <code>model</code> to use your interface. Add the generic type by changing <code>model</code> to <code>model&lt;CamperInt&gt;</code>.</p>
<p>Just one more step here. Your <code>CamperInt</code> interface only defines the properties you set in the MongoDB document, but doesn't include the standard properties. </p>
<p>Change your <code>export interface CamperInt</code> to <code>export interface CamperInt extends Document</code>. This tells TypeScript that your type definition is an extension of the existing <code>Document</code> type definition – you are essentially adding properties to that structure.</p>
<p>Your final file should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Document, model, Schema } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CamperInt {
  discordId: <span class="hljs-built_in">string</span>;
  round: <span class="hljs-built_in">number</span>;
  day: <span class="hljs-built_in">number</span>;
  timestamp: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Camper = <span class="hljs-keyword">new</span> Schema({
  discordId: <span class="hljs-built_in">String</span>,
  round: <span class="hljs-built_in">Number</span>,
  day: <span class="hljs-built_in">Number</span>,
  timestamp: <span class="hljs-built_in">Number</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> model&lt;CamperInt&gt;(<span class="hljs-string">"camper"</span>, Camper);
</code></pre>
<p>As a safety check, use <code>npm run build</code> again. You should not see any errors in the terminal.</p>
<h2 id="heading-how-to-write-bot-commands">How to Write Bot Commands</h2>
<p>You are finally ready to start writing some commands! As this is a 100 Days of Code bot, you should start with the command for creating a 100 Days of Code update.</p>
<h3 id="heading-100-command">100 command</h3>
<p>Within your <code>commands</code> folder, create a <code>oneHundred.ts</code> file. This will hold your 100 Days of Code command. Import your command interface with <code>import { CommandInt } from "../interfaces/CommandInt";</code>.</p>
<p>Now declare an exported variable <code>oneHundred</code> and give it the <code>CommandInt</code> type:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: CommandInt = {

}
</code></pre>
<p>Set the <code>name</code> property to <code>"100"</code>, give it a <code>description</code> property similar to <code>"Creates a 100 Days of Code update"</code>, and set up the <code>run</code> function as <code>async (message) =&gt; {}</code>.</p>
<p>Now for the logic within the function. Your logic will need a few properties from the <code>message</code> object to work, so go ahead and destructure those out: <code>const{ author, channel, content } = message;</code>.</p>
<p>When a user calls this command, it should look something like this:</p>
<blockquote>
<p>!100 Here is my 100 Days of Code update.</p>
</blockquote>
<p>You will want to extract that text without the <code>!100</code> part. There are a few was to do this – we are going to slice it out with <code>const text = content.split(" ").slice(1).join(" ")</code>.  Using the previous example, <code>text</code> would now hold the string <code>"Here is my 100 Days of Code update."</code>.</p>
<p>Time for some database work. Import your <code>CamperModel</code> with <code>import CamperModel from "../database/models/CamperModel"</code>. Note that you are importing the default export, instead of a module.</p>
<p>Now you need to see if the user has a record in your database. Use <code>let targetCamperData = await CamperModel.findOne()</code> to prepare for this. </p>
<p>The <code>.findOne()</code> method is used to query the collection for a single record, and takes an object to filter the query. These queries support MongoDB's syntax for advanced searching, but in this case you only need to find the record by the user's <code>discordId</code>. Add <code>{discordId: author.id}</code> as the parameter for the <code>findOne()</code>.</p>
<p>What happens if the user's record does not exist yet? If this is their first time using the command, they will not have a document in the database. Add an <code>if</code> condition to check if <code>targetCamperData</code> does not exist:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">if</span> (!targetCamperData) {

}
</code></pre>
<p>In this block, you are going to reassign <code>targetCamperData</code> to a new document with <code>targetCamperData = await CamperModel.create()</code>. You use the <code>.create()</code> method to generate and save a new document. The method takes an object as the first argument – that object is the document to create. Pass the following object to the method:</p>
<pre><code class="lang-ts">targetCamperData = <span class="hljs-keyword">await</span> CamperModel.create({
  discordId: author.id,
  round: <span class="hljs-number">1</span>,
  day: <span class="hljs-number">0</span>,
  timestamp: <span class="hljs-built_in">Date</span>.now()
});
</code></pre>
<p>Whether the record exists already or has just been created, your next step is to update it. After your <code>if</code> block, add a line to increment the <code>day</code> value: <code>targetCamperData.day++</code>.</p>
<p>What happens if the user is on day 100? They should not be able to go to day 101, as the challenge is only a hundred days long. You will need to add logic for that. If the user is above day 100, you want to set their day to 1 and increase their round:</p>
<pre><code class="lang-ts">targetCamperData.day++;
<span class="hljs-keyword">if</span> (targetCamperData &gt; <span class="hljs-number">100</span>) {
  targetCamperData.day = <span class="hljs-number">1</span>;
  targetCamperData.round++;
}
</code></pre>
<p>Now update the timestamp with <code>targetCamperData.timestamp = Date.now();</code>. This may seem redundant, since you did this step in the <code>create</code> method, but this ensures that the timestamp is updated if the data already existed.</p>
<p>You need to save the changes you made to the document. Add <code>await targetCamperData.save();</code> to do this – <code>mongoose</code> will then save your changes to the document in MongoDB.</p>
<p>Now you will construct the message the bot should send. To do this, you are going to use a message embed. Message embeds are special message formats that are available to Discord bots, which offer additional formatting options and styling.</p>
<p>Start by adding the <code>MessageEmbed</code> class to your imports with <code>import { MessageEmbed } from "discord.js";</code>. Then, after your database logic, create a new message embed with <code>const oneHundredEmbed = new MessageEmbed();</code>. Time to start setting the values of the embed.</p>
<p>The embed title appears as large text at the top of the embed. Set the title to "100 Days of Code" with <code>oneHundredEmbed.setTitle("100 Days of Code");</code>.</p>
<p>The embed description appears as standard text below the title. Set this to the user-provided text with <code>oneHundredEmbed.setDescription(text);</code>.</p>
<p>The embed author appears above the title, and is used to indicate who generated the embed. You will set this with <code>oneHundredEmbed.setAuthor()</code>. </p>
<p>This method takes a few arguments, and you will use the first two. The first argument is the author's name. Set this to <code>author.username + "#" + author.discriminator</code>.  This will display in the same way that you see a user in Discord: <code>nhcarrigan#0001</code>.  </p>
<p>Set the second argument to <code>author.displayAvatarUrl()</code>. This is a method provided by discord.js to fetch the URL for the author's avatar image.</p>
<p>Embed fields are additional title-description pairs that can be nested within the embed, and optionally inlined. These can be created with the <code>.addField()</code> method, which takes up to three arguments. The first argument is the field title, the second argument is the field description, and the third argument is an optional Boolean to set the field as inline. </p>
<p>Add two fields to your embed. The first is <code>oneHundredEmbed.addField("Round", targetCamperData.round, true);</code>, and the second is <code>oneHundredEmbed.addField("Day", targetCamperData.day, true);</code>.</p>
<p>You can add a footer to an embed and appears at the bottom in small text. Set the footer to the data's timestamp with <code>oneHundredEmbed.setFooter("Day completed: " + new Date(targetCamperData.timestamp).toLocaleDateString();</code>.  The <code>toLocaleDateString()</code> method will take a <code>Date</code> object and convert it to a locale-specific string based on the location of your bot's server.</p>
<p>Now you need to send that message embed. The <code>channel</code> property you extracted from the <code>message</code> value earlier represents the Discord channel in which the message was sent. This object has a <code>.send()</code> method, which you can use to have the bot send a message back to that channel. Use <code>await channel.send(oneHundredEmbed)</code> to send your new embed to that channel.</p>
<p>To keep the channel clean, add an <code>await message.delete()</code> to have the bot delete the message that triggered the command. Your final code should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;
<span class="hljs-keyword">import</span> CamperModel <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> oneHundred: CommandInt = {
  name: <span class="hljs-string">"100"</span>,
  description: <span class="hljs-string">"Creates a 100 Days of Code update"</span>,
  run: <span class="hljs-keyword">async</span> (message) =&gt; {
    <span class="hljs-keyword">const</span> { author, channel, content } = message;
    <span class="hljs-keyword">const</span> text = content.split(<span class="hljs-string">" "</span>).slice(<span class="hljs-number">1</span>).join(<span class="hljs-string">" "</span>);

    <span class="hljs-keyword">let</span> targetCamperData = <span class="hljs-keyword">await</span> CamperModel.findOne({ discordId: author.id });

    <span class="hljs-keyword">if</span> (!targetCamperData) {
      targetCamperData = <span class="hljs-keyword">await</span> CamperModel.create({
        discordId: author.id,
        round: <span class="hljs-number">1</span>,
        day: <span class="hljs-number">0</span>,
        timestamp: <span class="hljs-built_in">Date</span>.now(),
      });
    }

    targetCamperData.day++;
    <span class="hljs-keyword">if</span> (targetCamperData.day &gt; <span class="hljs-number">100</span>) {
      targetCamperData.day = <span class="hljs-number">1</span>;
      targetCamperData.round++;
    }
    targetCamperData.timestamp = <span class="hljs-built_in">Date</span>.now();
    <span class="hljs-keyword">await</span> targetCamperData.save();

    <span class="hljs-keyword">const</span> oneHundredEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    oneHundredEmbed.setTitle(<span class="hljs-string">"100 Days of Code"</span>);
    oneHundredEmbed.setDescription(text);
    oneHundredEmbed.setAuthor(
      author.username + <span class="hljs-string">"#"</span> + author.discriminator,
      author.displayAvatarURL()
    );
    oneHundredEmbed.addField(<span class="hljs-string">"Round"</span>, targetCamperData.round, <span class="hljs-literal">true</span>);
    oneHundredEmbed.addField(<span class="hljs-string">"Day"</span>, targetCamperData.day, <span class="hljs-literal">true</span>);
    oneHundredEmbed.setFooter(
      <span class="hljs-string">"Day completed: "</span> +
        <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(targetCamperData.timestamp).toLocaleDateString()
    );

    <span class="hljs-keyword">await</span> channel.send(oneHundredEmbed);
    <span class="hljs-keyword">await</span> message.delete();
  },
};
</code></pre>
<p>If you remember, you created a list to hold all of your commands. You need to add your new command to that list. Head back to your <code>_CommandList.ts</code> file. Import your new command with <code>import { oneHundred } from "./oneHundred";</code>, then add <code>oneHundred</code> to your empty <code>CommandList</code> array:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;
<span class="hljs-keyword">import</span> { oneHundred } <span class="hljs-keyword">from</span> <span class="hljs-string">"./oneHundred"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CommandList: CommandInt[] = [oneHundred];
</code></pre>
<p>Now you can test it out! Use <code>npm run build</code> and <code>npm start</code> to get the bot started. Try sending <code>!100 This is my first post!</code> in the channel. The bot should respond with an embed and delete your message.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-160.png" alt="Image" width="600" height="400" loading="lazy">
<em>You can see the embed, with the author, title, description, fields, and footer.</em></p>
<h3 id="heading-view-command">View command</h3>
<p>What happens if a user forgets if they submitted or not, or wants to see what day they are on? You should add a command to view current 100 Days of Code progress.</p>
<p>In your <code>commands</code> directory, create a <code>view.ts</code> file. Like before, import your command interface and CamperModel, and create a new command called <code>view</code>. Set the <code>name</code> to <code>"view"</code>, the <code>description</code> to something like "View your current 100 Days of Code progress", and the <code>run</code> command to <code>async (message) =&gt; {}</code>.</p>
<p>You won't need the message content for this command, so extract the <code>author</code> and <code>channel</code> values from the <code>message</code> like you did before: <code>const { author, channel } = message;</code>.</p>
<p>Just like the 100 command, you need to fetch the user's data from the database. This time, however, if the data does not exist you will not be creating it – so you can use <code>const</code> here instead of <code>let</code>: <code>const targetCamperData = await CamperModel.findOne({ discordId: author.id });</code> </p>
<p>Now, if the user doesn't have a data record yet, they haven't started the challenge with the bot. You should send a message to let them know how to do this. </p>
<pre><code class="lang-ts"><span class="hljs-keyword">if</span> (!targetCamperData) {
  <span class="hljs-keyword">await</span> channel.send(<span class="hljs-string">"You have not started the challenge yet."</span>);
  <span class="hljs-keyword">return</span>;
}
</code></pre>
<p>Construct an embed, similar to the one you built for the 100 command. Don't forget to import the <code>MessageEmbed</code> class!</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">const</span> camperEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    camperEmbed.setTitle(<span class="hljs-string">"My 100DoC Progress"</span>);
    camperEmbed.setDescription(
      <span class="hljs-string">`Here is my 100 Days of Code progress. I last reported an update on <span class="hljs-subst">${<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
        targetCamperData.timestamp
      ).toLocaleDateString()}</span>.`</span>
    );
    camperEmbed.addField(<span class="hljs-string">"Round"</span>, targetCamperData.round, <span class="hljs-literal">true</span>);
    camperEmbed.addField(<span class="hljs-string">"Day"</span>, targetCamperData.day, <span class="hljs-literal">true</span>);
    camperEmbed.setAuthor(
      author.username + <span class="hljs-string">"#"</span> + author.discriminator,
      author.displayAvatarURL()
    );
</code></pre>
<p>A couple of key differences here. Instead of taking a text input from the user, you are using a fixed description value to indicate this is a <code>view</code> embed instead of a <code>100</code> embed. Since you use the timestamp in the description, you do not need to add a footer.</p>
<p>Just like before, send the embed to the message channel and delete the original message. Your final file should be:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;
<span class="hljs-keyword">import</span> CamperModel <span class="hljs-keyword">from</span> <span class="hljs-string">"../database/models/CamperModel"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> view: CommandInt = {
  name: <span class="hljs-string">"view"</span>,
  description: <span class="hljs-string">"Views your 100 Days of Code progress."</span>,
  run: <span class="hljs-keyword">async</span> (message) =&gt; {
    <span class="hljs-keyword">const</span> { author, channel } = message;

    <span class="hljs-keyword">const</span> targetCamperData = <span class="hljs-keyword">await</span> CamperModel.findOne({
      discordId: author.id,
    });

    <span class="hljs-keyword">if</span> (!targetCamperData) {
      <span class="hljs-keyword">await</span> channel.send(<span class="hljs-string">"You have not started the challenge yet."</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> camperEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    camperEmbed.setTitle(<span class="hljs-string">"My 100DoC Progress"</span>);
    camperEmbed.setDescription(
      <span class="hljs-string">`Here is my 100 Days of Code progress. I last reported an update on <span class="hljs-subst">${<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
        targetCamperData.timestamp
      ).toLocaleDateString()}</span>.`</span>
    );
    camperEmbed.addField(<span class="hljs-string">"Round"</span>, targetCamperData.round, <span class="hljs-literal">true</span>);
    camperEmbed.addField(<span class="hljs-string">"Day"</span>, targetCamperData.day, <span class="hljs-literal">true</span>);
    camperEmbed.setAuthor(
      author.username + <span class="hljs-string">"#"</span> + author.discriminator,
      author.displayAvatarURL()
    );

    <span class="hljs-keyword">await</span> channel.send(camperEmbed)
    <span class="hljs-keyword">await</span> message.delete();
  },
};
</code></pre>
<p>Add your new <code>view</code> command to your <code>_CommandList.ts</code> file with an import, and put the command in the <code>CommandList</code> array. Then use <code>npm run build</code> and <code>npm start</code> to test your new changes. Send "!view" in your channel and you should see the bot respond:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-161.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-edit-command">Edit command</h3>
<p>Unfortunately, if a user makes a typo in their 100 Days of Code post, they can't edit the message because the bot sent it. But you can add a command that will allow them to do this.</p>
<p>Create an <code>edit.ts</code> file in your <code>commands</code> directory. Import your command interface and declare a new command called <code>edit</code>. Set the <code>name</code> to <code>"edit"</code>, the <code>description</code> to something like "Edits a previous 100 Days of Code post", and prepare the <code>run</code> function as you have before.</p>
<p>Within the function, extract the <code>author</code>, <code>channel</code>, and <code>content</code> properties from the <code>message</code> object.</p>
<p>The <code>edit</code> command will take a Discord message id, followed by the updated text to use. You can destructure those from the message content with <code>const [, targetId, ...text] = content.split(" ");</code>. </p>
<p>The first element in the array would be the <code>!edit</code> command call, which is not needed for this command so you do not need to assign it to a value. The <code>targetId</code> element would be the id of the message to edit. <code>...text</code> that uses the spread operator to assign the remaining message content to the <code>text</code> variable, as an array.</p>
<p>Now you need to use the <code>targetId</code> to get the actual message from Discord. The <code>channel</code> value has a <code>messages</code> property which represents all of the messages sent in that channel. You can use the <code>fetch</code> method on that <code>messages</code> property to get a specific message (or multiple messages). Set this up as <code>const targetMessage = await channel.messages.fetch()</code>. </p>
<p>The <code>.fetch()</code> method can take an object containing the options for the fetch request, or it can take a string as the <code>id</code> of the message to fetch. Because you have the <code>id</code>, and are only fetching one message, you can pass <code>targetId</code> to the <code>.fetch()</code> method as the only parameter.</p>
<p>It is possible that the <code>targetMessage</code> does not exist. For example, if the user provided an invalid id string (or no id string at all). You'll need to add logic to check if the <code>targetMessage</code> is not found:</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">if</span> (!targetMessage) {
        <span class="hljs-keyword">await</span> channel.send(<span class="hljs-string">"That does not appear to be a valid message ID."</span>);
        <span class="hljs-keyword">return</span>;
    }
</code></pre>
<p>Now that you have asserted that the message exists, you can start working with the properties. Because your bot sends the message as an embed, the <code>content</code> property you are used to working with will be empty. Instead, you can find the embed within the <code>embeds</code> property.</p>
<p>The <code>embeds</code> property is an array of <code>MessageEmbed</code> objects. Since you wrote the bot's code to only send one embed, you can access that embed with <code>const targetEmbed = targetMessage.embeds[0];</code>.</p>
<p>Now that you have the embed, you need to confirm that the embed is from one of that user's 100 Days of Code posts. Thankfully, you set the user as the author of the embed. You can check if the embed's author information does not match the message author's information:</p>
<pre><code class="lang-ts">    <span class="hljs-keyword">if</span> (
      targetEmbed.author?.name !==
      author.username + <span class="hljs-string">"#"</span> + author.discriminator
    ) {
      <span class="hljs-keyword">await</span> channel.send(
        <span class="hljs-string">"This does not appear to be your 100 Days of Code post. You cannot edit it."</span>
      );
      <span class="hljs-keyword">return</span>;
    }
</code></pre>
<p>You have accounted for the message belonging to a different user (or not having the correct embed entirely), so now you can edit the embed. </p>
<p>Like you did before, set the description of the embed with the <code>.setDescription()</code> method. You'll need to use <code>.join(" ")</code> on the <code>text</code> variable this time, since it is currently an array. <code>targetEmbed.setDescription(text.join(" "));</code></p>
<p>Rather than sending a new message, you need to edit the existing message. You have the existing message stored in <code>targetMessage</code>, so you can use the <code>.edit()</code> method to change that message directly. </p>
<p><code>await targetMessage.edit(targetEmbed);</code> will change the message's embed to your modified version. Then delete the message that triggered this command with <code>await message.delete();</code>. Your command should look like this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> edit: CommandInt = {
  name: <span class="hljs-string">"edit"</span>,
  description: <span class="hljs-string">"Edits a previous 100 Days of Code post."</span>,
  run: <span class="hljs-keyword">async</span> (message) =&gt; {
    <span class="hljs-keyword">const</span> { author, channel, content } = message;
    <span class="hljs-keyword">const</span> [, targetId, ...text] = content.split(<span class="hljs-string">" "</span>);

    <span class="hljs-keyword">const</span> targetMessage = <span class="hljs-keyword">await</span> channel.messages.fetch(targetId);

    <span class="hljs-keyword">if</span> (!targetMessage) {
      <span class="hljs-keyword">await</span> channel.send(<span class="hljs-string">"That does not appear to be a valid message ID."</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> targetEmbed = targetMessage.embeds[<span class="hljs-number">0</span>];

    <span class="hljs-keyword">if</span> (
      targetEmbed.author?.name !==
      author.username + <span class="hljs-string">"#"</span> + author.discriminator
    ) {
      <span class="hljs-keyword">await</span> channel.send(
        <span class="hljs-string">"This does not appear to be your 100 Days of Code post. You cannot edit it."</span>
      );
      <span class="hljs-keyword">return</span>;
    }

    targetEmbed.setDescription(text.join(<span class="hljs-string">" "</span>));

    <span class="hljs-keyword">await</span> targetMessage.edit(targetEmbed);
    <span class="hljs-keyword">await</span> message.delete();
  },
};
</code></pre>
<p>Add the command to your <code>_CommandList.ts</code> file, importing it and adding the variable to the array. Then use <code>npm run build</code> and <code>npm start</code> to run the bot again.</p>
<p>To grab a message ID, you should have Developer Mode enabled in your Discord client. If you have not done so, visit your settings and select the "Advanced" section. Toggle "Developer Mode" on:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-162.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Then head back to your channel and right click on your original 100 Days of Code message. You should see an option in the context menu to copy the message ID:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-164.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Select that option and you will get an ID (mine was <code>855559921666621441</code>). Then in the same channel, use <code>!edit 855559921666621441 This is an edited post!</code>, replacing my value with the one you got from the "Copy ID" option. The bot should edit the existing embed with your new content.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-165.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-help-command">Help command</h3>
<p>You are almost there! One more command to go. Many bots have a <code>help</code> command, which returns a list of available commands. You should add one to your bot as well.</p>
<p>One last time, create a <code>help</code> file in your <code>commands</code> directory. Import your <code>CommandInt</code> interface and set up your command as <code>help</code>. Set the <code>name</code> to <code>"help"</code>, and the <code>description</code> to something like <code>"Returns information on the bot's available commands."</code>. Set up your <code>run</code> function. </p>
<p>This time you only need the message's <code>channel</code> property, so no need to destructure anything here. Instead, import the <code>MessageEmbed</code> class from <code>discord.js</code>, and go ahead and import your command list too: <code>import { CommandList } from "./_CommandList";</code>.</p>
<p>Construct a new <code>MessageEmbed</code> and assign it to a <code>helpEmbed</code> variable. Set the <code>title</code> to <code>"Available Commands:"</code> and the description to something similar to <code>"These are the available commands for this bot."</code>.</p>
<p>Now you need to add a field to the embed and dynamically generate the list of commands. Start by adding the field with <code>helpEmbed.addField()</code>. Use the first parameter to set the field name to <code>"Commands:"</code>. For the description (the second parameter), you will use the <code>CommandList</code> array to generate a readable list of commands.</p>
<pre><code class="lang-ts">    helpEmbed.addField(
      <span class="hljs-string">"Commands:"</span>,
      CommandList.map(<span class="hljs-function">(<span class="hljs-params">el</span>) =&gt;</span> <span class="hljs-string">`\`!<span class="hljs-subst">${el.name}</span>\`: <span class="hljs-subst">${el.description}</span>`</span>).join(<span class="hljs-string">"\n"</span>)
    );
</code></pre>
<p>The process here is two-part. First, using the built-in array method <code>.map</code>, you are creating a new array from your array of <code>CommandInt</code> objects. This array contains strings formatted using Markdown so the command name and description are readable. The string for your help command would look like:</p>
<blockquote>
<p><code>!help</code>: Returns information on the bot's available commands.</p>
</blockquote>
<p>You are then joining that array of strings with a new-line separator, which will create a vertical list of commands in a single string (embed fields require strings for the description).</p>
<p>Send the embed to the channel. Because you did not destructure the <code>channel</code> property out of the <code>message</code> object, you will need to use <code>message.channel.send(helpEmbed);</code> directly. </p>
<p>This time, do not delete the original message – you did not add an author to the help embed, so preserving the original message helps moderators see who used the command. Your help command should look like:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;
<span class="hljs-keyword">import</span> { MessageEmbed } <span class="hljs-keyword">from</span> <span class="hljs-string">"discord.js"</span>;
<span class="hljs-keyword">import</span> { CommandList } <span class="hljs-keyword">from</span> <span class="hljs-string">"./_CommandList"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> help: CommandInt = {
  name: <span class="hljs-string">"help"</span>,
  description: <span class="hljs-string">"Returns information on the bot's available commands."</span>,
  run: <span class="hljs-keyword">async</span> (message) =&gt; {
    <span class="hljs-keyword">const</span> helpEmbed = <span class="hljs-keyword">new</span> MessageEmbed();
    helpEmbed.setTitle(<span class="hljs-string">"Available Commands!"</span>);
    helpEmbed.setDescription(
      <span class="hljs-string">"These are the available commands for this bot."</span>
    );
    helpEmbed.addField(
      <span class="hljs-string">"Commands:"</span>,
      CommandList.map(<span class="hljs-function">(<span class="hljs-params">el</span>) =&gt;</span> <span class="hljs-string">`\`!<span class="hljs-subst">${el.name}</span>\`: <span class="hljs-subst">${el.description}</span>`</span>).join(<span class="hljs-string">"\n"</span>)
    );

    <span class="hljs-keyword">await</span> message.channel.send(helpEmbed);
  },
};
</code></pre>
<p>Import your <code>help</code> command into your <code>_CommandList.ts</code> file and add the command to your array. With this final command, your <code>_CommandList.ts</code> file should be:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CommandInt } <span class="hljs-keyword">from</span> <span class="hljs-string">"../interfaces/CommandInt"</span>;
<span class="hljs-keyword">import</span> { oneHundred } <span class="hljs-keyword">from</span> <span class="hljs-string">"./oneHundred"</span>;
<span class="hljs-keyword">import</span> { view } <span class="hljs-keyword">from</span> <span class="hljs-string">"./view"</span>;
<span class="hljs-keyword">import</span> { edit } <span class="hljs-keyword">from</span> <span class="hljs-string">"./edit"</span>;
<span class="hljs-keyword">import</span> { help } <span class="hljs-keyword">from</span> <span class="hljs-string">"./help"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CommandList: CommandInt[] = [oneHundred, view, edit, help];
</code></pre>
<p>Use <code>npm run build</code> and <code>npm start</code> one last time to test this feature. Send <code>!help</code> in your channel and the bot should respond:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-167.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You have successfully built a Discord bot for the 100 Days of Code challenge.</p>
<p>If you are interested in exploring further, you can view <a target="_blank" href="https://github.com/nhcarrigan/100-days-of-code-bot">the source code</a> for the live bot that inspired this tutorial, which includes custom error logging, external error reporting, and a documentation site.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The #100DaysOfCode Challenge, its history, and why you should try it ]]>
                </title>
                <description>
                    <![CDATA[ Way back in June 2016, I got an email from a developer named Alexander Kallaway. I knew of Alex because he’d created the freeCodeCamp Toronto study group. It was one of the most active study groups in Canada, drawing crowds of developers each week. B... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d/</link>
                <guid isPermaLink="false">66b8d5c3b0d93ae3e75d91c2</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Wed, 09 Dec 2020 16:20:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9afc740569d1a4ca2907.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Way back in June 2016, I got an email from a developer named Alexander Kallaway.</p>
<p>I knew of Alex because he’d created the freeCodeCamp Toronto study group. It was one of the most active study groups in Canada, drawing crowds of developers each week.</p>
<p>But Alex wasn’t writing me about the Toronto study group. He was writing me because he wanted to tell me about an endurance challenge he’d dreamed up.</p>
<p>The challenge was this: Alex wanted to code for at least an hour every day — for the next 100 days in a row.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*gxqZjvLgyl_AQNSD17Eu2Q.jpeg" alt="Image" width="800" height="1214" loading="lazy"></p>
<p>_Comic by [Sarah Andersen](https://www.facebook.com/DoodleTimeSarah/" rel="noopener" target="<em>blank" title=").</em></p>
<p>Alex had written an article explaining the rules of his challenge, and publicly committing to the challenge. He hoped that a few other people would read his article and join him on his challenge.</p>
<p>And he came up with a Twitter hashtag to go with it: <a target="_blank" href="https://twitter.com/search?f=tweets&amp;vertical=default&amp;q=%23100daysofcode&amp;src=typd">#100DaysOfCode</a>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*5UFxgU9XPZOUtvudcc0hXQ.jpeg" alt="Image" width="800" height="600" loading="lazy"></p>
<p><em>“Oh! Hi!” One of the freeCodeCamp events in Toronto, the city where the #100DaysOfCode Challenge was born. Photo by Justin Richardson.</em></p>
<p>Little did I know that 18 months later, <strong>thousands of people would be tweeting this hashtag hundreds of times each day.</strong></p>
<p>Today, people who have committed to the #100DaysOfCode challenge use the hashtag to share their progress, projects, and milestones they’ve hit — like landing their first developer job.</p>
<p>So how did Alex transform from a lone developer who wanted to improve his coding skills into the leader of a global movement involving thousands of developers?</p>
<h3 id="heading-and-who-the-heck-is-alexander-kallaway-anyway">And who the heck is Alexander Kallaway, anyway?</h3>
<p>A few years ago, Alex was just another high school student in Russia. He was passionate about foreign languages, and learning both English and Japanese. His passion eventually took him to Japan, where he continued his studies at a Japanese university.</p>
<p>One day while in Japan, Alex spotted an English-language copy of <a target="_blank" href="https://www.amazon.com/gp/product/B000PKG4DM/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000PKG4DM&amp;linkCode=as2&amp;tag=out0b4b-20&amp;linkId=eba22c67cdb42c3e7b22eb7dd4bcb098">The 4 Hour Workweek</a> on a bookshelf. He says this book opened his eyes to entrepreneurship, and the notion that anyone could start a project that makes a big impact — not just traditional “business people.”</p>
<p>He figured out a way to move to Canada so he could attend business school.</p>
<p>And it was there that his future wife, Anna, reached out to him, wanting to learn more about studying abroad and how he’d managed to do it. She now lives in Toronto with Alex.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*mKM0qA9LbPD8Ln-3Splt8Q.png" alt="Image" width="694" height="759" loading="lazy"></p>
<p><em>Alex and his wife Anna at Hong Kong Disneyland.</em></p>
<p>By 2014, Alex had finished business school, and had started a career in digital marketing.</p>
<p>But Alex’s interactions with the developers around him at work made him realize something important. He was missing a core entrepreneurial skill. He needed to learn to code.</p>
<p>Alex had no real programming experience. He couldn’t afford the time or the money necessary to attend a coding bootcamp — let alone to go back to school for a computer science degree.</p>
<p>But he decided to learn to code anyway. Every day after work, Alex would teach himself to code using free online resources.</p>
<p>While using freeCodeCamp, he decided he wanted to code along with other friends to have more social accountability. He tried to join a freeCodeCamp group in Toronto, but there wasn’t one. So he created one.</p>
<p>The freeCodeCamp Toronto study group expanded quickly through his efforts to organize events. The group started out meeting in coffee shops. Soon it was filling up entire office spaces. And it eventually found a permanent venue at a nearby coworking space.</p>
<p>And through freeCodeCamp Toronto, Alex became friends with dozens of like-minded people who wanted to learn to code.</p>
<p>All his hard work paid off. Thanks to his newly acquired skills and large network of developers, Alex got his first developer job.</p>
<p>At that point, it was easy to become complacent. He had arrived.</p>
<p>He had a fun job. He was making good money. He had made so many friends. And he had “made it.” He was a Russian expatriate finding success in Canada’s biggest and most competitive city.</p>
<p>But Alex knew he needed to keep expanding his skills if he wanted to realize his entrepreneurial ambitions. He could sense his skills hitting a plateau. After a long day at work, it was tempting to just relax and watch TV, or hang out with friends.</p>
<p>Alex recalls:</p>
<blockquote>
<p>“The idea of #100DaysOfCode originally came from personal frustration with my inability to consistently learn to code after work. I would find other less-involved activities to spend my time on, like binge-watching TV series.</p>
<p>One of those days, I was sitting in a restaurant with my wife Anna sharing my frustrations with her. I suggested that maybe I should make a public commitment to learning for at least an hour every day, and I thought I would go for 3 months.</p>
<p>Anna said it was a good idea, and asked: ‘But why stop at 3 months? You should make it an even 100 days! It just sounds better!’”</p>
</blockquote>
<h3 id="heading-the-100daysofcode-challenge-is-born">The #100DaysOfCode Challenge is born</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/1_9VTiBSaOZuTDHr0FQUc8Pw.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>I got to hang out with Alexander Kallaway in person in Toronto.</em></p>
<p>#100DaysOfCode would serve as a commitment device, forcing Alex to code each day after work, even when he felt like watching TV instead.</p>
<p>He needed to clearly state what the rules of the challenge were, so he wouldn’t be able to bend them later.</p>
<p>So he created <strong>Rule #1: You commit to coding for minimum 1 hour every day for the next 100 days.</strong></p>
<p>Alex was obsessed with productivity, and developing positive habits. He had read lots of books on habit formation. Some of the books he recommends reading on the topic are:</p>
<ul>
<li><p><a target="_blank" href="https://www.amazon.com/gp/product/B005CFS8R0/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B005CFS8R0&amp;linkCode=as2&amp;tag=out0b4b-20&amp;linkId=570b829f1e6f6ebf8a2fb6a65a8c5500">The War of Art: Winning the Inner Creative Battles</a></p>
</li>
<li><p><a target="_blank" href="https://www.amazon.com/gp/product/B007EJSMC8/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B007EJSMC8&amp;linkCode=as2&amp;tag=out0b4b-20&amp;linkId=b0333d9cb4da4f50f1fe7825fcadc803">The Power of Habit: Why We Do What We Do in Life and Business</a></p>
</li>
<li><p><a target="_blank" href="https://www.amazon.com/gp/product/B00K5JUNSU/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B00K5JUNSU&amp;linkCode=as2&amp;tag=out0b4b-20&amp;linkId=03640190aae8d90e97e04fffa7d39c04">The Obstacle Is the Way: The Timeless Art of Turning Trials into Triumph</a></p>
</li>
</ul>
<p>Alex thought about how so much of our motivation comes from our friends and family. We need social accountability.</p>
<p>And that’s when he realized that this challenge could be social in nature, and that the more people he got involved, the more likely any single participant would succeed and make it through day 100.</p>
<p>So he created <strong>Rule #2: You commit to encouraging at least 2 other people who are taking the challenge each day, using Twitter.</strong></p>
<p>As Alex puts it:</p>
<blockquote>
<p>“This system could help counteract all the excuses I naturally came up with for not doing what I was supposed to do. This is how the challenge was born — a couple of simple rules, social accountability, and nothing more. Accountability is one of the biggest factors in trying to change some aspect of your life.”</p>
</blockquote>
<p>Right from the start, Alex acknowledged that learning to code is hard. But our friends can help us push forward through the setbacks.</p>
<blockquote>
<p>“There will be plenty of times when you feel like you’ve had enough. Or you’ll feel like your progress is way too slow, or you’re hopelessly stuck. These are all serious-enough reasons to quit. Or at least that’s what you might tell yourself.</p>
<p>But if you connect with others on the same path you can share the ups and downs of the journey, and together move past all these roadblocks. Share your frustrations, learning experiences, and victories with the like-minded people who are also on the same path as you. By sharing these, you grow to understand: ‘It’s not just me.’”</p>
</blockquote>
<h3 id="heading-why-100daysofcode-is-a-more-realistic-goal-than-most-of-the-new-years-resolutions-people-commit-to">Why #100DaysOfCode is a more realistic goal than most of the New Years Resolutions people commit to</h3>
<p>The #100DaysOfCode Challenge is only 100 days long — less than a third of a year. And you have a giant community of people cheering you on.</p>
<p>As a result, many people not only finish the challenge — they commit to it a second time!</p>
<p>So Alex came up with the concept of “rounds.” These are signified by tweeting with which day you’re on (Day 1) and how many times you’ve attempted the challenge (Round 1).</p>
<p>He adopted a new format for daily progress tweets: <strong>R1D1</strong> — which means <strong>R</strong>ound <strong>1</strong> <strong>D</strong>ay <strong>1</strong>.</p>
<blockquote>
<p>“There is an inside joke that was born out of this format: On the second day of the second round — R2D2 — people post a picture or a gif of the beloved R2D2 Star Wars robot in their daily progress tweet.”</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Hw7O2KfPe3OOUpt0L9W1Pg.jpeg" alt="Image" width="800" height="600" loading="lazy"></p>
<p>If you scroll through <a target="_blank" href="https://twitter.com/search?f=tweets&amp;vertical=default&amp;q=%23100daysofcode&amp;src=typd">the #100DaysOfCode hashtag on Twitter</a>, you’ll see cases where people have already completed several rounds.</p>
<p>But Alex recommends starting with a single 100-day commitment and going from there. He also recommends keeping things simple at the start.</p>
<blockquote>
<p>“New Years Resolutions don’t work because people over-commit. Make sure this is your only habit that you’re trying to pick up.”</p>
</blockquote>
<p>He also says it’s OK if something unexpected comes up, and you can’t code for a day.</p>
<blockquote>
<p>“If you are traveling for 2–3 days and cannot code, take a book on coding with you and read it instead. If you only can afford 20 minutes a day, do that. Make the challenge your own. The only rule that I want you to keep sacred is that you have to code daily. You can skip a day here and there for unplanned situations, but not more. The goal is to become consistent, no matter what life throws at you.”</p>
</blockquote>
<p>If you’re interested in boosting your motivation, you should take the challenge. It starts with tweeting your commitment to the challenge.</p>
<p><a target="_blank" href="https://twitter.com/intent/tweet?text=I%27m%20publicly%20committing%20to%20the%20%23100DaysOfCode%20Challenge%20starting%20today.%20Join%20me!&amp;url=https://medium.freecodecamp.org/the-crazy-history-of-the-100daysofcode-challenge-and-why-you-should-try-it-for-2018-6c89a76e298d&amp;hashtags=100DaysOfCode">Click here to publicly commit to the #100DaysOfCode Challenge</a> 😇</p>
<p>Then you can fork the <a target="_blank" href="https://github.com/Kallaway/100-days-of-code">#100DaysOfCode GitHub repository</a> to serve as a journal of your daily progress.</p>
<p>One great thing about the challenge is that you don’t need to wait until New Years to take it.</p>
<p>People are starting the challenge every day, so you’ll have people who started before you cheering you on.</p>
<p>Then you can turn around and cheer on the people who are starting after you.</p>
<p>These encouraging tweets and feedback on your projects can be extremely motivating. I’ve talked with tons of people who say the #100DaysOfCode challenge helped them break through barriers that had held back their coding for months. The social accountability aspect works wonders.</p>
<h3 id="heading-where-to-learn-more">Where to learn more</h3>
<p>Alex has done some great podcast interviews where he talks in greater detail about the #100DaysOfCode Challenge:</p>
<ul>
<li><p><a target="_blank" href="https://www.codenewbie.org/podcast/100-days-of-code">Alex on the CodeNewbie Podcast</a></p>
</li>
<li><p><a target="_blank" href="https://learntocodewith.me/podcast/100-days-of-code-with-alexander-kallaway/">Alex on the Learn to Code With Me Podcast</a></p>
</li>
</ul>
<p>You can also check out their official website: <a target="_blank" href="http://www.100daysofcode.com">100daysofcode.com</a></p>
<p>And <a target="_blank" href="https://medium.freecodecamp.org/take-the-100daysofcode-challenge-make-coding-a-habit-4a655d8663fd">read Alex’s article</a> about some of the improvements to the challenge.</p>
<p>Even if you don’t want to take the challenge, you should keep coding as much as you can make time to do.</p>
<p>At the end of the day, it’s all about practice.</p>
<blockquote>
<p>“Every day you code is the day you’ve won.” — Alexander Kallaway</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Advent Calendar – Learn JavaScript Interactively by Christmas Eve 🎅🏻 ]]>
                </title>
                <description>
                    <![CDATA[ By Per Harald Borgen First of all, bookmark this Advent Calendar and come back every day for new JavaScript lessons. Advent Calendar Day 1 Challenge: Advent Calendar Day 2 Challenge: Advent Calendar Day 3 Challenge: Advent Calendar Day... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introducing-24-days-of-javascriptmas/</link>
                <guid isPermaLink="false">66d8522e18dca47577c8da9b</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ advent-calendar ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 01 Dec 2020 08:57:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/11/email-javascirptmas-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Per Harald Borgen</p>
<p>First of all, bookmark this Advent Calendar and come back every day for new JavaScript lessons.</p>
<h2 id="heading-advent-calendar-day-1-challenge">Advent Calendar Day 1 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-candies-introduction-cLkqvpcQ" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-2-challenge">Advent Calendar Day 2 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-deposit-profit-introduction-cPk7yptk" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-3-challenge">Advent Calendar Day 3 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-chunky-monkey-introduction-cLkqvyAR" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-4-challenge">Advent Calendar Day 4 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/javascript-challenge-century-from-year-introduction-cNDr7NUB" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-5-challenge">Advent Calendar Day 5 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-reverse-a-string-introduction-c9rME3fv" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-6-challenge">Advent Calendar Day 6 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-sort-by-length-introduction-cyw87yuK" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-7-challenge">Advent Calendar Day 7 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/javascript-challenge-count-vowel-consonant-introduction-coa5e49d4b957084837f19509" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-8-challenge">Advent Calendar Day 8 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascriptmas-challenge-the-rolling-dice-introduction-c36yeWh7" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-9-challenge">Advent Calendar Day 9 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-sum-odd-fibonacci-numbers-introduction-cmpWaRcW" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-10-challenge">Advent Calendar Day 10 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-adjacent-elements-product-introduction-c8q4NRCE" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-11-challenge">Advent Calendar Day 11 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-avoid-obstacles-introduction-crGrJPTm" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-12-challenge">Advent Calendar Day 12 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-valid-time-introduction-cLkq4bSQ" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-13-challenge">Advent Calendar Day 13 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-extract-each-kth-introduction-ce96GEHP" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-14-challenge">Advent Calendar Day 14 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-maximal-adjacent-difference-introduction-ckRE4Kt9" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-15-challenge">Advent Calendar Day 15 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-carousel-c9r874s3" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-16-challenge">Advent Calendar Day 16 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-insert-dashes-introduction-co2914310ba38bcaab285ccfa" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-17-challenge">Advent Calendar Day 17 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-different-symbols-naive-introduction-cocf74b85b168559bf4e75a1a" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-18-challenge">Advent Calendar Day 18 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-array-previous-less-introduction-co8cd43f5a1ebd5c407f1b3f8" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-19-challenge">Advent Calendar Day 19 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-alphabet-subsequence-introduction-czbJ4Jt9" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-20-challenge">Advent Calendar Day 20 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-domain-type-introduction-czbwRaH8" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-21-challenge">Advent Calendar Day 21 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-sum-of-two-introduction-cE9B9rfE" title="Embedded content" loading="lazy"></iframe></div>




<h2 id="heading-advent-calendar-day-22-challenge">Advent Calendar Day 22 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/co9a8445aab096f48e7e5ecf5" title="Embedded content" loading="lazy"></iframe></div>



<h2 id="heading-advent-calendar-day-23-challenge">Advent Calendar Day 23 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/-javascript-challenge-social-media-input-crqLDVud" title="Embedded content" loading="lazy"></iframe></div>



<h2 id="heading-advent-calendar-day-24-challenge">Advent Calendar Day 24 Challenge:</h2>
<div class="embed-wrapper"><iframe style="width:100%;min-width:1000px;min-height:600px" src="https://scrimba.com/learn/adventcalendar/coc854c8d9bf01f02843f1b5c" title="Embedded content" loading="lazy"></iframe></div>



<h2 id="heading-about-this-advent-calendar">About this Advent Calendar</h2>
<p>Welcome to <a target="_blank" href="https://scrimba.com/learn/adventcalendar?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=javascriptmas_freecodecamp_launch">24 Days of JavaScriptmas</a>, an Advent Calendar that gives you a small JavaScript challenge every day throughout December.</p>
<p>2020 has been a rough one for aspiring software developers. In addition to the health costs that have affected so many of us, junior developers have faced an increasingly difficult job market. </p>
<p>Many experienced developers were laid off this year, and therefore applied for the same jobs junior developers were hoping to get.</p>
<p>I am convinced that this pandemic eventually will result in <em>more</em> demand for developers, as it pushes industries online. But right now, we seem to be in a tricky transition period.</p>
<p>So to help aspiring developers be better prepared for 2021, we have created an advent calendar called <a target="_blank" href="https://scrimba.com/learn/adventcalendar?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=javascriptmas_freecodecamp_launch">24 Days of JavaScriptmas</a> 🎄</p>
<blockquote>
<p>From December 1st and until Christmas Eve, you will get a small coding challenge to help you improve your JavaScript skills a little bit every single day.</p>
</blockquote>
<p>The challenges start off pretty simple, and then ramp up throughout the month. If you stick with it all the way to Christmas Eve, you will definitely increase your chances of landing a junior developer job in 2021. Because training your core JavaScript skills is the best investment you can do towards that.</p>
<h2 id="heading-the-teacher-dylan-claus-israel">The Teacher: Dylan "Claus" Israel</h2>
<p>All the challenges have been created by online coding instructor Dylan Israel. He has appeared both on <a target="_blank" href="https://www.youtube.com/watch?v=ZihKWQXRBmE&amp;ab_channel=freeCodeCamp.org">freeCodeCamp's YouTube channel</a> and <a target="_blank" href="https://www.freecodecamp.org/news/dropout-to-developer-dylan-israel/">podcast</a> previously, so you might already know Dylan.</p>
<p>But what you probably didn't know is that Dylan takes on a completely different job at the end of each year, as proven by the picture below 👇 </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/dylan_claus-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now, let's have a look at what kind of challenges Dylan "Claus" Israel has created for you this year.</p>
<h2 id="heading-the-challenges-core-javascript-skills">The challenges: core JavaScript skills</h2>
<p>The challenges have been created to help you increase your core JavaScript skills. This is something all web developers need to practice, regardless of which framework they use. </p>
<p>So you'll often find yourself manipulating Arrays, changing Strings, comparing Numbers and so on throughout the advent calendar. In general, they're things you'd often do as a professional web developer.</p>
<p>All challenges come in the form of Scrimba screencasts, or <em>scrims.</em> This makes it simple for you to both understand the instructions and code your solutions, as you do both activities inside the <em>scrims.</em></p>
<h3 id="heading-ok-but-whats-a-scrim">Ok, but what's a scrim? 🤔</h3>
<p>A <em>scrim</em> is a mix between a code editor and a video. Think of it as if YouTube and VS Code had a child. This means that you can pause the "video" it at any given time and edit the code directly in the player. It's almost as if you are pair-programming with the teacher.</p>
<p>So you simply "take over" for Dylan at the end if the <em>scrim</em> and start coding your solution inside the <em>scrim</em>. </p>
<blockquote>
<p>Once the test suite goes from ❌ to ✅, you have solved the challenge.</p>
</blockquote>
<p>If you manage to solve it, I would recommend that you share your solution on Twitter under the <a target="_blank" href="https://twitter.com/hashtag/JavaScriptmas?src=hashtag_click">#JavaScriptmas hashtag.</a> This hashtag will serve as a way for the community to check out each others' solutions.</p>
<p>If you didn't manage to solve the challenge, no worries. Dylan will provide the solution the following day. But I encourage you to give it an honest shot, as we will pick a daily winner amongst the submissions who will get free access to Scrimba for a year, plus a grand prize on Christmas Eve.</p>
<p>To give everyone a chance to win - regardless of skill-level - we will pick a random winner from the submissions. So you are actually only competing against yourself. If you increase your JavaScript proficiency as a consequence of this advent calendar, you are a winner. 👏</p>
<p>The first challenge is already live, so head over to <a target="_blank" href="https://scrimba.com/learn/adventcalendar?utm_source=freecodecamp.org&amp;utm_medium=referral&amp;utm_campaign=javascriptmas_freecodecamp_launch">24 Days of JavaScriptmas</a> right now and get started growing those JavaScript skills. And make sure to bookmark this article, as I'll update it every day with the newest challenge.</p>
<p>Merry Christmas! 🎅🏻</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git Clone Branch – How to Clone a Specific Branch ]]>
                </title>
                <description>
                    <![CDATA[ Unlike older centralized version control systems such as SVN and CVS, Git is distributed. Every developer has the full history and control of their code locally or remotely. They can also access or manipulate several parts of the code as they deem fi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/git-clone-branch-how-to-clone-a-specific-branch/</link>
                <guid isPermaLink="false">66d84e0f29e30bc0ad477548</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Bolaji Ayodeji ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jun 2020 18:56:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/article-banner--1-.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Unlike older centralized version control systems such as SVN and CVS, Git is distributed. Every developer has the full history and control of their code locally or remotely. They can also access or manipulate several parts of the code as they deem fit from different locations.</p>
<p>Since Linus Torvalds (the famous creator of the Linux operating system kernel) created Git in 2005 for Linux kernel development, it has become the most widely used modern version control system in the world.</p>
<p>In this article, I'll introduce you to the Git clone and Git branch workflows and I'll show you how you can clone a specific branch based on your needs. Let's begin! ?</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>Basic knowledge of the terminal</p>
</li>
<li><p>Ability to type commands in the terminal</p>
</li>
<li><p>Git installed (I'll still show you how)</p>
</li>
<li><p>A GitHub account</p>
</li>
<li><p>A smile on your face (Put up that smile friend ?)</p>
</li>
</ul>
<h2 id="heading-quick-introduction-to-git-and-github">Quick Introduction to Git and GitHub</h2>
<p>According to <a target="_blank" href="https://en.wikipedia.org/wiki/Git">Wikipedia</a>,</p>
<blockquote>
<p><strong>Git</strong> is a distributed version control system designed to track changes to a project (code) in software development. It is intended to enforce coordination, collaboration, speed, and efficiency among developers.</p>
</blockquote>
<p><strong>GitHub,</strong> on the other hand, is a web-based hosting service for version control using Git. It offers all of the distributed version control and source code management functionality of Git as well as adding more features for computer code.</p>
<h2 id="heading-how-to-install-git-on-windows">How to Install Git on Windows</h2>
<p>Download and install the latest <a target="_blank" href="https://git-for-windows.github.io/">Git for Windows Installer here.</a></p>
<h2 id="heading-how-to-install-git-on-linux">How to Install Git on Linux</h2>
<p>Here are the commands based on your Linux distro:</p>
<h3 id="heading-debian-or-ubuntu">Debian or Ubuntu</h3>
<pre><code class="lang-python">sudo apt-get update
sudo apt-get install git
</code></pre>
<h3 id="heading-fedora">Fedora</h3>
<pre><code class="lang-python">sudo dnf install git
</code></pre>
<h3 id="heading-centos">CentOS</h3>
<pre><code class="lang-python">sudo yum install git
</code></pre>
<h3 id="heading-arch-linux">Arch Linux</h3>
<pre><code class="lang-python">sudo pacman -Sy git
</code></pre>
<h3 id="heading-gentoo">Gentoo</h3>
<pre><code class="lang-python">sudo emerge --ask --verbose dev-vcs/git
</code></pre>
<h2 id="heading-how-to-install-git-on-a-mac">How to Install Git on a Mac</h2>
<p>Download and install the latest <a target="_blank" href="https://sourceforge.net/projects/git-osx-installer/files/">Git for Mac installer here</a>.</p>
<p>Or you can type this command:</p>
<pre><code class="lang-python">brew install git
</code></pre>
<p>Now that we've got Git installed, let's move on to the tutorial.</p>
<h2 id="heading-introduction-to-git-clone">Introduction to Git Clone</h2>
<p>Git allows you to manage and version your project(s) in a "repository". This repository is stored on a web-based hosting service for version control, like GitHub.</p>
<p>You can then clone this repository to your local machine and have all the files and branches locally (I'll explain more about branches soon).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-23-at-5.47.48-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For example, you can clone freeCodeCamp's repository with SSH like so:</p>
<pre><code class="lang-python">git clone git@github.com:freeCodeCamp/freeCodeCamp.git
</code></pre>
<h2 id="heading-introduction-to-git-branches">Introduction to Git Branches</h2>
<p>When working on a project, you will likely have different features. And multiple contributors will be working on this project and its features.</p>
<p>Branches allow you to create a "playground" with the same files in the <code>master</code> branch. You can use this branch to build independent features, test new features, make breaking changes, create fixes, write docs or try out ideas without breaking or affecting the production code. When you're done, you merge the branch into the production <code>master</code> branch.</p>
<p>Branching is a core concept in Git which is also used in GitHub to manage workflows of different versions of one project. The <code>master</code> branch is always the default branch in a repository that is most often considered "production and deployable code". New branches like <code>passwordless-auth</code> or <code>refactor-signup-ux</code> can be created from the <code>master</code> branch.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-22-at-2.47.53-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>All branches in freeCodeCamp's repository</em></p>
<h2 id="heading-how-to-clone-git-branches">How to Clone Git Branches</h2>
<p>While you can clone repositories with the <code>git clone</code> command, keep in mind that this clones the branch and the remote <code>HEAD</code>. This is usually <code>master</code> by default and includes all other branches in the repository.</p>
<p>So when you clone a repository, you clone the <code>master</code> and all other branches. This means you will have to checkout another branch yourself.</p>
<p>Let's say your task on a project is to work on a feature to add passwordless authentication to a user dashboard. And this feature is in the <code>passwordless-auth</code> branch.</p>
<p>You really don't need the <code>master</code> branch since your "feature branch" will be merged into <code>master</code> afterward. How then do you clone this <code>passwordless-auth</code> branch without fetching all other branches with "a bunch of files you don't need"?</p>
<p>I created this sample repository to explain this. This repository holds a simple blog built with Nextjs and has four dummy branches:</p>
<ul>
<li><p>master</p>
</li>
<li><p>dev</p>
</li>
<li><p>staging</p>
</li>
<li><p>passwordless-auth</p>
</li>
</ul>
<p>In Nextjs, any file inside the folder <code>pages/api</code> is mapped to the <code>/api/*</code> path and will be treated as an API endpoint instead of a <code>page</code>. In our repository, I have created different dummy APIs <a target="_blank" href="https://github.com/BolajiAyodeji/nextjs-blog/tree/master/pages/api">in this directory</a> to make each branch different.</p>
<p>The <code>master</code> branch holds the file <strong>pages/api/hello.js</strong> while <code>passwordless-auth</code> holds the file <strong>pages/api/auth.js</strong>. Each file just returns a dummy text response. See <code>master</code>'s hello API response <a target="_blank" href="https://nextjs-blog.bolajiayodeji.vercel.app/api/hello">here</a> (with a special message for you ?).</p>
<p>Let's clone the repository:</p>
<pre><code class="lang-python">git clone git@github.com:BolajiAyodeji/nextjs-blog.git
</code></pre>
<p>This gives us access to all branches in this repository and you can easily toggle between each to see each version and its files.</p>
<pre><code class="lang-python">git branch -a
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-22-at-4.51.56-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Wondering where the <strong>remotes/origin/..</strong> branches came from?</p>
<p>When you clone a repository, you pull data from a repository on the internet or an internal server known as the <strong>remote</strong>. The word origin is an alias created by your Git to replace the remote URL (you can change or specify another alias if you want).</p>
<p>These <strong>remotes/origin/..</strong> branches point you back to the origin repository you cloned from the internet so you can still perform pull/push from the origin.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-23-at-5.24.43-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>So when you clone <code>master</code> onto your machine, <code>remotes/origin/master</code> is the original <code>master</code> branch on the internet, and <code>master</code> is on your local machine. So you will pull/push from and to the <code>remotes/origin/master</code>.</p>
<p>In summary <strong>Remote</strong> is the URL that points you to the repository on the internet while <strong>Origin</strong> is an alias for this remote URL.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-23-at-5.28.06-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-clone-a-specific-branch">How to Clone a Specific Branch</h2>
<p>Now let's clone a specific branch from our demo repository. There are two ways to clone a specific branch. You can either:</p>
<ul>
<li><p>Clone the repository, fetch all branches, and checkout to a specific branch immediately.</p>
</li>
<li><p>Clone the repository and fetch only a single branch.</p>
</li>
</ul>
<h3 id="heading-option-one">Option One</h3>
<pre><code class="lang-python">git clone --branch &lt;branchname&gt; &lt;remote-repo-url&gt;
</code></pre>
<p>or</p>
<pre><code class="lang-python">git clone -b &lt;branchname&gt; &lt;remote-repo-url&gt;
</code></pre>
<p>With this, you fetch all the branches in the repository, checkout to the one you specified, and the specific branch becomes the configured local branch for <code>git push</code> and <code>git pull</code> . But you still fetched all files from each branch. This might not be what you want right? ?</p>
<p>Let's test it:</p>
<pre><code class="lang-python"> git clone -b passwordless-auth git@github.com:BolajiAyodeji/nextjs-blog.git
</code></pre>
<p>This automatically configures <code>passwordless-auth</code> as the local branch but still tracks other branches.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-23-at-5.30.01-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-30-at-3.27.31-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-option-two">Option Two</h3>
<pre><code class="lang-python">git clone --branch &lt;branchname&gt; --single-branch &lt;remote-repo-url&gt;
</code></pre>
<p>or</p>
<pre><code class="lang-python">git clone -b &lt;branchname&gt; --single-branch &lt;remote-repo-url&gt;
</code></pre>
<p>This performs the same action as option one, except that the <code>--single-branch</code> option was introduced in Git version 1.7.10 and later. It allows you to only fetch files from the specified branch without fetching other branches.</p>
<p>Let's test it:</p>
<pre><code class="lang-python">git clone -b passwordless-auth --single-branch git@github.com:BolajiAyodeji/nextjs-blog.git
</code></pre>
<p>This automatically configures <code>passwordless-auth</code> as the local branch and only tracks this branch.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-23-at-5.31.12-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-30-at-3.29.07-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you run <code>cd pages/api</code> you'll find the <code>auth.js</code> file in the <code>passwordless-auth</code> branch as expected from the previous setup.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You might be running out of internet or storage space but you need to work on a task in a specific branch. Or you might want to clone a specific branch with limited files for various reasons. Fortunately, Git provides you the flexibility to do this. Flex your muscles and try it out, there's much more "Git" to learn.</p>
<p>One at a time, yeah? ✌?</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 5 things I Learned Mentoring 2,500 Aspiring Developers ]]>
                </title>
                <description>
                    <![CDATA[ By Mehul Mohan Earlier this month, I started a free mentorship program for everyone who aspires to become a developer and wants a little nudge or tips and tricks from me. The response there was tremendous.  Almost a month in, after talking one-on-one... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/5-mentorship-learnings/</link>
                <guid isPermaLink="false">66d46040b6b7f664236cbe0e</guid>
                
                    <category>
                        <![CDATA[ 100DaysOfCode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mentorship ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 27 Jun 2020 01:43:47 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9a04740569d1a4ca230a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mehul Mohan</p>
<p>Earlier this month, I started a <a target="_blank" href="https://www.freecodecamp.org/news/free-mentorship-to-developers/">free mentorship program for everyone</a> who aspires to become a developer and wants a little nudge or tips and tricks from me. The response there was tremendous. </p>
<p>Almost a month in, after talking one-on-one with so many developers on WhatsApp, I have a much better understanding of the current generation of aspiring developers.</p>
<h2 id="heading-1-web-development-is-popular">#1: Web Development is popular</h2>
<p>Going by the messages exchanged between me and 2,500 other developers, people want to learn web development. Almost 80% of people want to learn, are learning, or want to switch careers into web development.</p>
<p>Why is that? Well, if you look at the data, it becomes much more clear:</p>
<ol>
<li>Almost every business that sells has a website.</li>
<li>Web developers are needed to create/maintain/update and change the technologies powering so many websites.</li>
<li>The web is rapidly expanding, improving, and growing. More people are getting online each day, the opportunity is tremendous for the people who control what millions of people could see through web pages.</li>
<li>The web is vast - you can pick up your little tech stack, master it, and earn through freelancing, or as an independent contractor or firm.</li>
</ol>
<p>Does that mean you should learn web development? Well, it depends. Keep reading the article to know why.</p>
<h2 id="heading-2-a-good-chunk-of-people-are-doing-it-wrong">#2: A good chunk of people are doing it wrong</h2>
<p>I won't write "most people", but yes, a lot of people are learning competitive programming when they should really be learning web development, or music, or anything else.</p>
<p>A lot of the people I talked to are "stuck" learning something because their job apparently demands it. Or because they are waiting for internships or on-campus placements 100 years from now (sarcasm). Or because that's what is taught in their universities. Or because their friends are doing it.</p>
<p>If you fall into one of those categories you're not doing yourself a favor.</p>
<p>Take a step back and seriously reconsider the road you're taking. If you're not happy with the end goal and the path, if you're not excited about programming, coding, doing and learning what you do right now, it's not going to be something you'll master – you are going to give up somewhere along the way.</p>
<p>Don't get twisted though. This doesn't mean the usual "because-it-does-not-work" code frustration that happens all the time when you're learning. Please reconsider your field, but make sure you're doing what makes and keeps you happy. There's no shame in picking up things you like and things you don't.</p>
<h2 id="heading-3-you-want-to-master-everything">#3: You want to master everything</h2>
<p>You can't imagine all the confusion I saw. </p>
<p>People want to become full-stack developers, contribute to all Open Source projects, get a job at Facebook, create a rocket at NASA, leave the solar system, and set up another civilization in another galaxy all at once.</p>
<p>This is not how any of this works. You cannot be a full-stack or even a frontend developer in a day. And if anyone says that to you, that person is lying. </p>
<p>Being a full-stack developer or mastering a tech stack isn't a destination. You would never wake up one day and say that this is the day when I become a full-stack developer. </p>
<p>It is a journey. You'll learn so much along the journey. And the journey is going to be a long one, whether you like it or not. You also cannot effectively master everything.</p>
<p>Remember that my definition of mastering is not watching a 4 hour YouTube video on React and considering yourself eligible to work on the flight control dashboard on SpaceX rocket. It takes time and experience to master a tech stack, and you probably won't feel that you know everything even when you really know a lot of stuff.</p>
<p>Although the secret of being successful is mastering one thing, I often tell people to try out as many things as they can – just to develop a taste of what they like and what they don't. Maybe you'll like Rust, maybe someone else will like C++. </p>
<p>You never know until you try.</p>
<h2 id="heading-4-you-dont-want-to-put-in-the-work">#4: You don't want to put in the work</h2>
<p>I contacted so many people and told them to report their progress in a week. What surprised me is that most of them didn't complete the work I assigned. </p>
<p>"I was busy this week due to work", "I had a test coming up", "I was busy learning X" – excuses. Plain excuses. </p>
<p>Please realize that putting in constant effort for a sustained amount of time is one of the few things which cannot be bought or transferred with a hyperlink. You <strong>have</strong> to do it. </p>
<p>If you're not doing it, figure out why – is it because you don't like the thing you're doing? If that's the case, consider point #2. Is it because you don't have resources/you get confused? – ASK me! Is it because of some other reason? – TELL me!</p>
<p>People don't like to share things online fearing that they will be judged. Trust me, neither of us are that interesting. </p>
<p>When you share things, you give someone in a similar situation a chance to relate, get motivated, and even help you out.</p>
<h2 id="heading-5-know-your-tools-ask-for-help">#5: Know your tools – Ask for help</h2>
<p>A technology you're learning might not be for you at all.</p>
<p>I chatted with so many Python and ML/AI enthusiasts struggling to learn backend development because they couldn't make sense of Node.js. Why would you want to learn Node for backend when you already know Python? Go and learn about Flask and Linux systems. </p>
<p>This is just one example of many people who didn't have guidance and mentorship early on. And I wonder how many human hours could have been saved if everyone was mentored and given a slight push to correct their trajectory.</p>
<p>When in doubt, ask for help. Dev forums, Google, Reddit, StackOverflow, Twitter – there are so many places to ask for help! </p>
<p>It would be so easy for someone to get stuck without the internet and all the smart people on it. The internet is a blessing, so use it!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I'm trying my best to manage the 2,500 people the in the program now, and plan to open up for mentorship again when I can take on more people.</p>
<p>This mentorship is part of <a target="_blank" href="https://codedamn.com">codedamn – a platform for developers to connect and learn</a>. If you want, you can follow me on <a target="_blank" href="https://twitter.com/mehulmpt">Twitter</a> and <a target="_blank" href="https://instagram.com/mehulmpt">Instagram</a> to keep yourself updated about the things I code and my life in general.</p>
<p>Let's connect!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
