<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leonardo Theodoro</title>
    <description>The latest articles on DEV Community by Leonardo Theodoro (@thdr).</description>
    <link>https://dev.to/thdr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F213901%2Fbfb0c035-50cd-4fa2-aad8-6a302e7d57d9.jpg</url>
      <title>DEV Community: Leonardo Theodoro</title>
      <link>https://dev.to/thdr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thdr"/>
    <language>en</language>
    <item>
      <title>Avoiding Catastrophic Backtracking in Regular Expressions</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Fri, 21 Feb 2025 12:27:07 +0000</pubDate>
      <link>https://dev.to/thdr/avoiding-catastrophic-backtracking-in-regular-expressions-29lp</link>
      <guid>https://dev.to/thdr/avoiding-catastrophic-backtracking-in-regular-expressions-29lp</guid>
      <description>&lt;p&gt;Hey everyone! Today, I want to talk about a problem that can turn your regular expressions into real ticking time bombs for your application's performance: &lt;strong&gt;Catastrophic Backtracking&lt;/strong&gt;. You might have encountered this without even realizing it, especially if your regex handles complex searches or unexpectedly locks up.&lt;/p&gt;

&lt;p&gt;So, if you want to avoid freezes, infinite loops, and major headaches when working with regex, this article is for you. Let’s break down this issue and how to prevent it!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Catastrophic Backtracking?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Backtracking&lt;/strong&gt; is a mechanism that most regex engines use to find matches. Basically, when a regex fails to match a pattern, the engine backtracks a few steps and tries another approach.&lt;/p&gt;

&lt;p&gt;The problem arises when the regex is structured in a way that creates &lt;strong&gt;too many possible matching combinations&lt;/strong&gt; before finally failing. This causes the regex engine to go through an &lt;strong&gt;exponential&lt;/strong&gt; number of attempts before giving up, potentially freezing your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the problem occur in practice?
&lt;/h2&gt;

&lt;p&gt;Let's understand this issue with a practical example. Imagine you want to validate a string that contains only the letter "a" followed by the letter "b," and you write the following expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's test it with a string that should fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;a+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;+b$/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aaab&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true (valid)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aaaaaaaaaaaaaaaaaaaaa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Fails, but not immediately!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first test works correctly, but the second one can cause the regex engine to freeze. This happens because the pattern &lt;strong&gt;(a+)+&lt;/strong&gt; allows multiple ways to group the "a" characters, and the engine attempts all these combinations before realizing the string doesn’t contain a "b" at the end.&lt;/p&gt;

&lt;p&gt;Let’s visualize what the engine is doing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It starts by trying to group all the "a" characters inside the first (a+).&lt;/li&gt;
&lt;li&gt;Since there’s another (a+) wrapping this group, it attempts to redistribute the "a" characters in multiple ways.&lt;/li&gt;
&lt;li&gt;When it reaches the end of the string and doesn't find "b," it backtracks and tries different ways to group the "a" characters.&lt;/li&gt;
&lt;li&gt;Since there are so many ways to distribute the "a" characters, the number of attempts grows exponentially, causing the engine to freeze.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This behavior is called &lt;strong&gt;Catastrophic Backtracking&lt;/strong&gt; because the execution time grows unpredictably depending on the input size.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Avoid Catastrophic Backtracking?
&lt;/h2&gt;

&lt;p&gt;Now that you understand the problem, let’s go over some solutions to prevent it:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Avoid Unnecessary Groups&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you don’t need to capture something, &lt;strong&gt;remove the parentheses&lt;/strong&gt;. In the previous example, &lt;code&gt;^(a+)+b$&lt;/code&gt; can be simplified to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Use Boundary Anchors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Whenever possible, use &lt;code&gt;^&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; to mark the start and end of the string, preventing unnecessary backtracking attempts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. **Use Lazy Quantifiers (*?, +?, ??)
&lt;/h3&gt;

&lt;p&gt;If you need to use repetitive quantifiers, try using the &lt;strong&gt;lazy&lt;/strong&gt; version to reduce the number of attempts. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;b$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Use Atomic Groups (&lt;/strong&gt;&lt;code&gt;(?&amp;gt;...)&lt;/code&gt;&lt;strong&gt;)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you're dealing with repetitive groups, you can tell the engine &lt;strong&gt;not to backtrack inside the group&lt;/strong&gt; using &lt;code&gt;(?&amp;gt;...)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;(?&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;If you've ever had regex slow down or crash your application, now you know that &lt;strong&gt;Catastrophic Backtracking&lt;/strong&gt; might be the culprit. Avoiding this problem is just a matter of applying best practices.&lt;/p&gt;

&lt;p&gt;See you next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>regex</category>
    </item>
    <item>
      <title>What Are Async Generators and What Are They Used For?</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Wed, 19 Feb 2025 13:01:50 +0000</pubDate>
      <link>https://dev.to/thdr/what-are-async-generators-and-what-are-they-used-for-4kna</link>
      <guid>https://dev.to/thdr/what-are-async-generators-and-what-are-they-used-for-4kna</guid>
      <description>&lt;p&gt;As a developer, you've probably dealt with data streams that aren’t immediately available – think about data coming from an API, chunked downloads, or even reading large files. In these scenarios, it’s crucial to have an elegant and efficient approach to processing data as it arrives. This is where &lt;strong&gt;async iterators&lt;/strong&gt; come in. But before diving into this concept, let’s first understand how synchronous iterators work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Iterators?
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;iterator&lt;/strong&gt; is an object that defines a sequence and knows how to access its elements one at a time through a method called &lt;code&gt;next()&lt;/code&gt;. In JavaScript, to make an object iterable – meaning it can be traversed using a &lt;code&gt;for..of&lt;/code&gt; loop – we define a special method called &lt;code&gt;Symbol.iterator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Imagine we have a &lt;code&gt;range&lt;/code&gt; object that represents a range of numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints: 1, 2, 3, 4, 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, each call to &lt;code&gt;next()&lt;/code&gt; returns an object with the structure &lt;code&gt;{ value, done }&lt;/code&gt;. As long as &lt;code&gt;done&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, the loop continues, allowing &lt;code&gt;for..of&lt;/code&gt; to iterate over all values in the range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations of Iterators
&lt;/h2&gt;

&lt;p&gt;While synchronous iterators work well for sequences of immediately available data, they fail when values are only known or available asynchronously – for instance, when each value depends on a network request or a delay (&lt;code&gt;setTimeout&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Imagine you need to iterate over a sequence that depends on an operation that takes time to complete (such as an API call). Using a synchronous iterator won’t work in this case because the &lt;code&gt;next()&lt;/code&gt; method cannot wait for a Promise to resolve or a delay to pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generators: Simplifying Iterator Creation
&lt;/h2&gt;

&lt;p&gt;Manually implementing an iterator can be verbose. &lt;strong&gt;Generators&lt;/strong&gt; simplify this process. They are special functions that can "pause" execution using the &lt;code&gt;yield&lt;/code&gt; keyword, returning values on demand and maintaining internal state between calls.&lt;/p&gt;

&lt;p&gt;A generator is defined using &lt;code&gt;function*&lt;/code&gt; and can be used to create iterators concisely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints: 1, 2, 3, 4, 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Introducing Async Iterators
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Async iterators&lt;/strong&gt; were created specifically to handle scenarios where values are obtained asynchronously. They work similarly to synchronous iterators but with some key differences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Iteration method:&lt;/strong&gt; Instead of implementing &lt;code&gt;Symbol.iterator&lt;/code&gt;, we use &lt;code&gt;Symbol.asyncIterator&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;**next()**&lt;/code&gt;** method:** In an async iterator, &lt;code&gt;next()&lt;/code&gt; returns a Promise that resolves to an object &lt;code&gt;{ value, done }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iteration loop:&lt;/strong&gt; To consume values, we use &lt;code&gt;for await...of&lt;/code&gt;, which waits for each Promise to resolve before proceeding.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s refactor the &lt;code&gt;range&lt;/code&gt; example so that values are returned with a 1-second delay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asyncIterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Simulating a delay (as if waiting for a network response)&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;asyncRange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints: 1, 2, 3, 4, 5 (with a 1-second interval)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, each iteration waits for the delay to resolve before proceeding, allowing data to be processed as it arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Async Iterators?
&lt;/h2&gt;

&lt;p&gt;Now that we understand the difference between synchronous iterators and async iterators, let’s explore the advantages of using async iterators in everyday coding:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. On-Demand Processing
&lt;/h3&gt;

&lt;p&gt;In many cases, data arrives in fragments. Instead of waiting for all data to be available, an async iterator allows processing each value as soon as it arrives. This is especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paginated requests:&lt;/strong&gt; Processing API results page by page instead of loading everything at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data streams:&lt;/strong&gt; Such as downloading or uploading files where data is received in chunks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Integration with Asynchronous APIs
&lt;/h3&gt;

&lt;p&gt;Many modern APIs (such as Fetch API or Streams API) handle data asynchronously. Async iterators allow integrating these data flows naturally and consistently, avoiding "hacks" or excessive code coupling.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Performance and Efficiency Improvements
&lt;/h3&gt;

&lt;p&gt;By processing data on demand, we avoid loading large volumes of data into memory all at once. This can lead to significant performance improvements, especially when dealing with large data streams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Example: Paginating Data with Async Iterators
&lt;/h2&gt;

&lt;p&gt;A classic example of using async iterators is paginating data. Suppose we need to fetch commits from a GitHub repository, where each request returns a page with 30 commits and provides a link to the next page.&lt;/p&gt;

&lt;p&gt;Using an async iterator, we can create a &lt;code&gt;fetchCommits(repo)&lt;/code&gt; function that handles all pagination logic and allows us to iterate over the commits seamlessly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;fetchCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/repos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/commits`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User-Agent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Our App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Extracts the link to the next page, if available&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nextPageMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;;&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*rel="next"/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nextPageMatch&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;nextPageMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;fetchCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username/repository&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Process each commit as it arrives&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern allows you to process commits continuously and efficiently, without worrying about pagination logic in each call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Considerations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Async iterators&lt;/strong&gt; are a powerful tool for working with asynchronously arriving data. By allowing on-demand iteration, they simplify integration with modern APIs, make code cleaner and more expressive, and help avoid performance issues when handling large data streams.&lt;/p&gt;

&lt;p&gt;In summary, opting for async iterators provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; Processing data as it becomes available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; Using &lt;code&gt;for await...of&lt;/code&gt; for more intuitive code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Avoiding unnecessary large memory loads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration:&lt;/strong&gt; Easy handling of asynchronous APIs and real-time data streams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Where do our variables go - A brief guide to Call Stack and Memory Heap</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Wed, 19 Feb 2025 11:23:15 +0000</pubDate>
      <link>https://dev.to/thdr/where-do-our-variables-go-a-brief-guide-to-call-stack-and-memory-heap-jge</link>
      <guid>https://dev.to/thdr/where-do-our-variables-go-a-brief-guide-to-call-stack-and-memory-heap-jge</guid>
      <description>&lt;p&gt;Have you written countless JavaScript codes and developed various systems, but have you ever stopped to wonder how some things work behind the scenes?&lt;/p&gt;

&lt;p&gt;Today, I want to introduce you to two terms that I didn't know before and found interesting to learn about: Call Stack and Memory Heap.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Memory Model
&lt;/h2&gt;

&lt;p&gt;First, we need to understand what happens when we declare a variable and initialize it. In the example below, I declared the variable &lt;code&gt;x&lt;/code&gt; with the value of 1 and created another variable equivalent to &lt;code&gt;x&lt;/code&gt;, then changed the value of &lt;code&gt;x&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Result?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think will happen when we print &lt;code&gt;y&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;If you think the value of &lt;code&gt;y&lt;/code&gt; will be 2, you're wrong—but let me explain why.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When &lt;code&gt;x&lt;/code&gt; was created, JavaScript generated a unique identifier and allocated it to a memory address (e.g., &lt;code&gt;M001&lt;/code&gt;) while also storing the variable's value at that memory address.&lt;/li&gt;
&lt;li&gt;When I said &lt;code&gt;let y = x&lt;/code&gt;, I meant that &lt;strong&gt;&lt;code&gt;y&lt;/code&gt; is equivalent to the memory address &lt;code&gt;M001&lt;/code&gt; and not equal to the value of &lt;code&gt;x&lt;/code&gt;.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;When I changed the value of &lt;code&gt;x&lt;/code&gt;, &lt;strong&gt;JavaScript allocated a new memory address and saved the value 2 at address &lt;code&gt;M002&lt;/code&gt;.&lt;/strong&gt; &lt;strong&gt;This happens because primitive data types (string, number, boolean, undefined, and symbol) are immutable.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is the Role of the Call Stack?
&lt;/h2&gt;

&lt;p&gt;The Call Stack works like a stack (FILO - First In, Last Out). &lt;strong&gt;It organizes function calls, adding and removing them after the code is executed.&lt;/strong&gt; Additionally, &lt;strong&gt;it is responsible for storing primitive types.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s also in the Call Stack that a phenomenon you’ve probably heard of occurs: &lt;strong&gt;Stack Overflow.&lt;/strong&gt; This happens when functions are stacked indefinitely, and the stack exceeds the maximum memory limit.&lt;/p&gt;

&lt;p&gt;Here’s a quick example of how we can cause a stack overflow using recursion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recursion&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;recursion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;recursion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  So, what does the Memory Heap do?
&lt;/h2&gt;

&lt;p&gt;Unlike the Call Stack, the Memory Heap is where non-primitive data (arrays, objects, and functions) is stored. It allows data to grow dynamically and be organized in a non-sequential manner.&lt;/p&gt;

&lt;p&gt;Here’s how the Memory Heap works. Check out this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, when we declare the variable &lt;code&gt;arr&lt;/code&gt;, the &lt;strong&gt;Call Stack saves a reference value pointing to the Memory Heap, where the actual values are managed.&lt;/strong&gt; In this case, the &lt;code&gt;push&lt;/code&gt; modifies the Heap's content but not the reference address in the Call Stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;const&lt;/code&gt; and Non-Primitive Data
&lt;/h3&gt;

&lt;p&gt;When we declare a variable with &lt;code&gt;const&lt;/code&gt;, we cannot reassign its value. However, for arrays and objects, it’s possible to modify the items internally. This happens because the identifier in the Call Stack remains the same, while the values are managed in the Heap.&lt;/p&gt;

&lt;p&gt;In summary, when we perform a &lt;code&gt;push&lt;/code&gt; on an array, it doesn’t change the memory address—it changes the value in the Heap. The same applies to objects.&lt;/p&gt;

&lt;p&gt;Here’s a reference table to make this clearer:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Call Stack&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Heap&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;td&gt;Address&lt;/td&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;CS001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;y&lt;/td&gt;
&lt;td&gt;CS002&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;arr&lt;/td&gt;
&lt;td&gt;CS003 (points to H001)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;H001 (points to -&amp;gt;)&lt;/td&gt;
&lt;td&gt;[]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Can Primitive Types Ever "Go" to the Heap?
&lt;/h3&gt;

&lt;p&gt;Yes, there are cases where primitive types can "go" to the Heap, and this happens indirectly when you use a wrapper.&lt;/p&gt;

&lt;p&gt;For example, if I declare a variable as &lt;code&gt;new String("Text")&lt;/code&gt; instead of a plain string, the value is treated as an object and stored in the Heap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Garbage Collection and Memory Leaks
&lt;/h2&gt;

&lt;p&gt;JavaScript has automatic memory management, meaning it cleans up unreferenced addresses (i.e., those no longer in use) automatically. This process is called "garbage collection" and uses the &lt;a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection#Na%C3%AFve_mark-and-sweep" rel="noopener noreferrer"&gt;Mark and Sweep&lt;/a&gt; algorithm, which identifies and removes inaccessible variables.&lt;/p&gt;

&lt;p&gt;However, Memory Leaks (when available memory is exceeded) can still occur. Here are the most common causes of Memory Leaks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Global Variables&lt;/strong&gt;&lt;br&gt;
Global variables are difficult to collect because they are always accessible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Event Listeners&lt;/strong&gt;&lt;br&gt;
Event listeners that are not removed can remain active, causing leaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Add an event listener to the button&lt;/span&gt;
&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Button clicked!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; 

&lt;span class="c1"&gt;// Problem: the listener will not be removed even if the button is deleted from DOM &lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;setInterval&lt;/strong&gt;&lt;br&gt;
Funções dentro de um &lt;code&gt;setInterval&lt;/code&gt; nunca são coletadas, a menos que o intervalor seja limpo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Understanding the JavaScript memory model is essential to writing more efficient code and avoiding issues like memory leaks.&lt;/p&gt;

&lt;p&gt;Remember:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primitive types are immutable and stored in the Call Stack as values.&lt;/li&gt;
&lt;li&gt;Non-primitive types reside in the Memory Heap and are stored as references.&lt;/li&gt;
&lt;li&gt;Exceeding the stack limit causes a Stack Overflow.&lt;/li&gt;
&lt;li&gt;Exceeding the available memory causes Memory Leaks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And if you want to learn more about value and reference variables, read this &lt;a href="https://dev.to/thdr/why-cant-we-compare-arrays-and-objects-with--5h0j"&gt;article&lt;/a&gt; I wrote, explaining why we can't compare arrays and objects using &lt;code&gt;===&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I found it interesting to learn a bit about this and hope you find it helpful too. See you next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>learning</category>
    </item>
    <item>
      <title>Why can’t we compare arrays and objects with ===</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Wed, 29 Jan 2025 10:53:13 +0000</pubDate>
      <link>https://dev.to/thdr/why-cant-we-compare-arrays-and-objects-with--5h0j</link>
      <guid>https://dev.to/thdr/why-cant-we-compare-arrays-and-objects-with--5h0j</guid>
      <description>&lt;p&gt;Hi everyone, I decided to write this article to answer a question I’ve always had: why can’t we compare arrays and objects with &lt;code&gt;===&lt;/code&gt;? So, I did some research, and this is what I found about how JavaScript works under the hood.&lt;/p&gt;

&lt;p&gt;JavaScript has five data types that are passed by &lt;strong&gt;value&lt;/strong&gt;: &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, and &lt;code&gt;number&lt;/code&gt;. These are called &lt;strong&gt;primitive types&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;JavaScript has three data types that are passed by &lt;strong&gt;reference&lt;/strong&gt;: &lt;code&gt;array&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;, and &lt;code&gt;object&lt;/code&gt;. Technically, all three are objects, so we can refer to them collectively as objects. These are called &lt;strong&gt;non-primitive types&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Primitive Types (Value)
&lt;/h2&gt;

&lt;p&gt;When you declare a variable of a primitive type, it stores the value directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;'John'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;age&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Simple as that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-Primitive Types (Reference)
&lt;/h2&gt;

&lt;p&gt;Variables holding non-primitive values are assigned a reference to that value. This reference points to the location of the object in memory. In this case, the variable stores the reference, not the value itself.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="nx"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a representation of what happens in these lines:&lt;/p&gt;

&lt;p&gt;First line:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;[]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Second line:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;['Banana']&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What happens when we declare a reference variable?
&lt;/h2&gt;

&lt;p&gt;When a reference variable is copied using &lt;code&gt;=&lt;/code&gt;, the reference address is copied, not the value. &lt;strong&gt;Objects are copied by reference, not by value.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yellowFruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fruits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;['Banana']&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yellowFruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If we add a fruit to the &lt;code&gt;yellowFruits&lt;/code&gt; array, we’re also adding it to the &lt;code&gt;fruits&lt;/code&gt; array since they share the same reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;yellowFruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pineapple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;['Banana', 'Pineapple']&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yellowFruits&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Reassigning a reference variable
&lt;/h2&gt;

&lt;p&gt;When we reassign a reference variable, it replaces the reference, not the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In memory, this happens:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;person&lt;/td&gt;
&lt;td&gt;H002&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;{ nome: 'John' }&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;H002&lt;/td&gt;
&lt;td&gt;{ nome: 'Mary' }&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The old reference still exists, but the variable now points to the new reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why can’t we compare arrays with &lt;code&gt;===&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;===&lt;/code&gt; is used with reference types (non-primitive data), the condition will only return true if both variables have the same reference. This is because &lt;strong&gt;&lt;code&gt;===&lt;/code&gt; checks references, not values&lt;/strong&gt;, for non-primitive types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if they are different objects, even with the same value, the references differ, so the comparison returns &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Function Parameters
&lt;/h2&gt;

&lt;p&gt;When we pass primitive values as parameters, the behavior is simple: the value is copied into the parameter, as if using &lt;code&gt;=&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;score&lt;/code&gt; is &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;multiplier&lt;/code&gt; is &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;10&lt;/code&gt;, and &lt;code&gt;y&lt;/code&gt; is &lt;code&gt;2&lt;/code&gt;. This happens because the value is copied into the parameter.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;score&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;multiplier&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;multiply&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;H001&lt;/td&gt;
&lt;td&gt;function(x,y)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;y&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Pure Functions
&lt;/h3&gt;

&lt;p&gt;Pure functions don’t affect anything outside their own scope, and all variables used within them are cleared once the function returns a value.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;multiply&lt;/code&gt; above is an example of a pure function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impure Functions
&lt;/h3&gt;

&lt;p&gt;Impure functions can receive objects and modify their state outside their scope. This happens because they receive the reference of the value, and any modification to this reference within the function affects the object outside as well. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;changeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;john&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;changeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;john&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;john&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Mary&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Mary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens because within the function, we’re modifying the value at the reference, which is shared between &lt;code&gt;john&lt;/code&gt; and &lt;code&gt;maria&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making it a pure function
&lt;/h3&gt;

&lt;p&gt;To make this function pure, we create a copy of the object inside the function, manipulate it, and return the copy. This avoids altering the original reference.&lt;/p&gt;

&lt;p&gt;Here’s the refactored version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;changeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPerson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nx"&gt;newPerson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newPerson&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;john&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;changeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;john&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;john&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// John&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Mary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this function, we convert the object to a string (a primitive type) and back to an object, creating a new reference. The original reference remains untouched.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Primitive Types&lt;/strong&gt;: Store values directly in variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-Primitive Types&lt;/strong&gt;: Store a reference to the value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference Copying&lt;/strong&gt;: Objects sharing the same reference reflect changes mutually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;===&lt;/code&gt; Operator&lt;/strong&gt;: Compares references, not values, in non-primitive types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pure Functions&lt;/strong&gt;: Don’t alter values outside their scope.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impure Functions&lt;/strong&gt;: Can modify the state of shared references.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making Functions Pure&lt;/strong&gt;: Creating copies prevents changes to original references.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’d like to learn more about how variables are stored in JavaScript, check out this &lt;a href="https://dev.to/thdr/where-do-our-variables-go-a-brief-guide-to-call-stack-and-memory-heap-jge"&gt;article&lt;/a&gt; I wrote about the Call Stack and Memory Heap.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed this, see you soon!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Before TDD: Why you need to know what Mocks, Stubs, and Spies are?</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Thu, 09 Jan 2025 17:21:21 +0000</pubDate>
      <link>https://dev.to/thdr/before-tdd-why-you-need-to-know-what-mocks-stubs-and-spies-are-1ehg</link>
      <guid>https://dev.to/thdr/before-tdd-why-you-need-to-know-what-mocks-stubs-and-spies-are-1ehg</guid>
      <description>&lt;p&gt;Hello, everyone! Today, I bring a topic that I believe is very interesting. I know there are dozens of articles online discussing TDD, BDD, design patterns for testing, how to write tests, and many other related topics. However, I see very few articles explaining more basic terms within the testing universe—those functions we often use but don’t always fully understand what they mean or how they behave. If you’re just starting to learn about testing and don’t know exactly what the library functions do, this article is for you. Enjoy the read!&lt;/p&gt;

&lt;h1&gt;
  
  
  What are mocks?
&lt;/h1&gt;

&lt;p&gt;The first thing you might come across as soon as you start writing tests is mocks. Sometimes you already use them but don’t know exactly what they mean. So, let’s dive in.&lt;/p&gt;

&lt;p&gt;Mocks are primarily used in unit testing. They are tools used to simulate content, objects, or responses that usually come from an external dependency, or when you need the content to have specific information.&lt;/p&gt;

&lt;p&gt;Imagine you’re testing a movie recommendation system. This system fetches a list of movies from an API and returns it to you. &lt;/p&gt;

&lt;p&gt;The problem is: if every time you run the tests, the real API is called, it could be slow and inconsistent (movies might vary, or the API could be down), making the tests unreliable.&lt;/p&gt;

&lt;p&gt;Alright, Leo, I get the problem, &lt;strong&gt;but how does a mock solve this?&lt;/strong&gt; Well, it’s simple: instead of calling the API, you use its response as a static list of movies. It’s basically “faking” the API response with that list of movies.&lt;/p&gt;

&lt;p&gt;In the movie system example, if you want to test a function called &lt;code&gt;fetchMoviesFromAPI()&lt;/code&gt; that uses the API to fetch movies, you can create a mock to simulate the API response like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is the mock&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MOVIES_FROM_API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Interstellar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nosferatu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Here, we’re telling fetchMoviesFromAPI to return our mock instead of calling the real API. This is a stub, which you’ll learn about in the next section.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchMoviesFromAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockResolvedValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MOVIES_FROM_API&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedMovies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MOVIES_FROM_API&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;movies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchMoviesFromAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MOVIES_FROM_API&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With mocks, your tests become more efficient since they don’t depend on external services. Moreover, they gain reliability because you have total control over the returns, allowing the focus to remain on validating the functionality without worrying about potential API instabilities or downtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mocks are static objects that simulate responses from calls or other objects needed for testing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the end, it’s like testing a car without using real gasoline. You create a controlled environment to ensure the engine is working before taking it out on the road.&lt;/p&gt;

&lt;h1&gt;
  
  
  I get mocks, now what are stubs?
&lt;/h1&gt;

&lt;p&gt;Stubs are also testing tools but serve a slightly different purpose. They replace the behavior of functions with something predetermined, often using mocks to return specific values.&lt;/p&gt;

&lt;p&gt;Stubs replace the function’s behavior. For example, when I access that movie API, the function won’t make the real call but will look at our mock (the static list of movies).&lt;/p&gt;

&lt;p&gt;They also serve as a reminder that &lt;strong&gt;our tests shouldn’t depend on external services or the internet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me give you some context: imagine you’re testing an application that calculates the total value of an online purchase. The calculation includes fees fetched from an external service. Every time you run the test, this calculation needs to be done, meaning the external service would need to be called. This could result in a slow, unstable, costly (because the external service might charge per request), and inconsistent test (values could change).&lt;/p&gt;

&lt;p&gt;Using a stub, you’ll replace the real service call with a fixed, predefined value (yes, a mock). Instead of calling the fee service, you say: &lt;em&gt;“Always return the value 10 as the fee.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine you want to test the function &lt;code&gt;calculateTotalPurchase()&lt;/code&gt; that sums up the cart items’ values and adds the shipping fee. Using stubs, you replace the shipping fee service with a value that always returns “10” as the shipping fee. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function we want to test&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateTotalPurchase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getShippingFee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shippingFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getShippingFee&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;totalItems&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;shippingFee&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Stub to replace the real shipping service&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getShippingFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockResolvedValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Items in the cart&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;// Calculating the total with the stub&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;calculateTotalPurchase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getShippingFee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Testing the result&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 50 + 30 + 10&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simplifies the test and ensures its reproducibility, meaning it will always work the same way. Moreover, stubs help isolate the test, eliminating the need to worry about the state or availability of the fee API.&lt;/p&gt;

&lt;p&gt;In summary, it’s like testing a cake recipe using a measuring cup that always says 200ml of milk instead of measuring the actual amount of milk. This way, you’re only testing if you can mix the ingredients without worrying about whether the milk is being measured correctly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mocks, stubs... and finally, what are spies?
&lt;/h1&gt;

&lt;p&gt;We’ve explored mocks, which simulate objects, and stubs, which mimic function behaviors. Now, let’s talk about spies: what exactly do they do?&lt;/p&gt;

&lt;p&gt;Spies monitor functions, recording how many times they were called, what parameters they received, and the results of each execution. They allow you to observe the function’s behavior without altering it, ensuring everything is working as expected.&lt;/p&gt;

&lt;p&gt;Imagine you’re testing the notification module of your project. Every time an order is completed, the system should send a message to the customer and log an entry. In this case, you only want to make sure these actions are performed but don’t want to replace any of them. With a spy, you monitor these functions without altering their behavior. This allows you to see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the function was called&lt;/li&gt;
&lt;li&gt;How many times it was called&lt;/li&gt;
&lt;li&gt;What arguments it received&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if you want to test the &lt;code&gt;completeOrder()&lt;/code&gt; function that sends a notification to the customer and logs the entry, with a spy, you can verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the notification function was called&lt;/li&gt;
&lt;li&gt;If the log function was called&lt;/li&gt;
&lt;li&gt;What arguments these functions received.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function we want to test&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;completeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logEntry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;saveLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Order completed for customer: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Mocks for auxiliary functions&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendNotification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logEntry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="p"&gt;;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Mock customer&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Calling the function we want to test&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;completeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logEntry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Checking if auxiliary functions were called&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saveLog&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saveLog&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Order completed for customer: John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To conclude, it’s like placing a camera to observe what a chef does in the kitchen. You don’t interfere with what they’re doing; you just check if they’re following the recipe correctly.&lt;/p&gt;

&lt;p&gt;So, that’s it! You’ve learned and understood the terms mocks, stubs, and spies, which are fundamental elements for creating reliable and efficient tests. Now you can continue deepening your studies. See you there, goodbye!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why you should use URL Constructor instead of template literals</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Wed, 24 Jul 2024 13:20:54 +0000</pubDate>
      <link>https://dev.to/thdr/why-should-you-use-url-constructor-instead-of-template-literals-1gp0</link>
      <guid>https://dev.to/thdr/why-should-you-use-url-constructor-instead-of-template-literals-1gp0</guid>
      <description>&lt;p&gt;Hey everyone! Today, I'm sharing a quick tip that improved the semantics of my code significantly.&lt;/p&gt;

&lt;p&gt;Often, whether working in frontend or backend development, we need to construct URLs with parameters, right?&lt;/p&gt;

&lt;p&gt;I used to write the URLs of my requests like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`http://localhost:3000/endpoint?param1=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;var1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;param2=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;param3=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;var3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We agree that this URL is hard to read and maintain; we always need to identify which parts are parameters, which are variables, and which are just Javascript syntax.&lt;/p&gt;

&lt;p&gt;To address this semantic issue, I discovered the &lt;strong&gt;URL Constructor&lt;/strong&gt;, which accomplishes the same task but in more efficient and elegant way.&lt;/p&gt;

&lt;p&gt;Now, we can rewrite the same code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/endpoint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;param1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;var1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;param2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;param3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;var3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code clearly indicates what it's doing. In the first line, we create the base URL and in the subsequent lines, we add the necessary search parameters.&lt;/p&gt;

&lt;p&gt;Done. Now, the variable &lt;code&gt;url&lt;/code&gt; contains the same search parameters as before, but now we are using the &lt;code&gt;URL&lt;/code&gt; class, making the code much simpler and easier to maintain.&lt;/p&gt;

&lt;p&gt;What about you? Have you used the &lt;code&gt;URL&lt;/code&gt; class before? Maybe for another purpose? Feel free to share your experiences with me.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Incluindo gráficos em um PDF usando Laravel e Chartjs</title>
      <dc:creator>Leonardo Theodoro</dc:creator>
      <pubDate>Thu, 02 Apr 2020 18:46:05 +0000</pubDate>
      <link>https://dev.to/thdr/incluindo-graficos-em-um-pdf-usando-laravel-e-chartjs-4kk3</link>
      <guid>https://dev.to/thdr/incluindo-graficos-em-um-pdf-usando-laravel-e-chartjs-4kk3</guid>
      <description>&lt;p&gt;Se você teve que gerar algum pdf que precisasse utilizar gráficos, sabe o quão difícil é conseguir incluir um gráfico dentro de um pdf, principalmente se você estiver usando gráficos em Javascript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://quickchart.io/" rel="noopener noreferrer"&gt;Quickchart.io&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.chartjs.org/" rel="noopener noreferrer"&gt;Chartjs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://laravel.com/" rel="noopener noreferrer"&gt;Laravel&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Quickchart.io
&lt;/h2&gt;

&lt;p&gt;Depois de procurar várias formas para incluir os gráficos dentro de um pdf, acabei encontrando um site que se chama &lt;a href="https://quickchart.io/" rel="noopener noreferrer"&gt;quickchart.io&lt;/a&gt;, o que ele faz é basicamente transformar gráficos javascript em imagens estáticas que podem ser utilizadas em qualquer lugar, inclusive em um pdf.&lt;/p&gt;

&lt;p&gt;Ele funciona da seguinte maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://quickchart.io/chart?c={type:'bar',data:{labels:[2012,2013,2014,2015,2016],datasets:[{label:'Users',data:[120,60,50,180,120]}]}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você envia um &lt;code&gt;query param&lt;/code&gt; na url do site com o nome &lt;code&gt;c&lt;/code&gt; e o valor é um objeto com as configurações e dados do gráfico, da mesma forma que você cria no &lt;code&gt;chartjs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O resultado dessa requisição é uma imagem png com o gráfico:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JyCXQ6bk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://quickchart.io/chart%3Fc%3D%7Btype:%2527bar%2527%2Cdata:%7Blabels:%5B2012%2C2013%2C2014%2C2015%2C2016%5D%2Cdatasets:%5B%7Blabel:%2527Users%2527%2Cdata:%5B120%2C60%2C50%2C180%2C120%5D%7D%5D%7D%7D" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JyCXQ6bk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://quickchart.io/chart%3Fc%3D%7Btype:%2527bar%2527%2Cdata:%7Blabels:%5B2012%2C2013%2C2014%2C2015%2C2016%5D%2Cdatasets:%5B%7Blabel:%2527Users%2527%2Cdata:%5B120%2C60%2C50%2C180%2C120%5D%7D%5D%7D%7D" alt="Imagem do gráfico" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Incluindo a imagem no PDF usando Laravel
&lt;/h2&gt;

&lt;p&gt;Nesse caso, estarei usando o &lt;a href="https://github.com/dompdf/dompdf" rel="noopener noreferrer"&gt;dompdf&lt;/a&gt; e o &lt;code&gt;Laravel 5.5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Primeiro passo, tenha os dados na estrutura correta que pede o &lt;code&gt;chartjs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s2"&gt;"type"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'horizontalBar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"labels"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Coluna 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Coluna 2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Coluna 3'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"datasets"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"label"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Dados"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"backgroundColor"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'#27ae60'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'#f1c40f'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'#e74c3c'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt; 
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois, transforme essa estrutura em &lt;code&gt;json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e mande ela pra URL do &lt;code&gt;quickchart.io&lt;/code&gt; usando &lt;code&gt;urlencode&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$chartURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://quickchart.io/chart?width=300&amp;amp;height=200&amp;amp;c="&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sim, é possível você escolher o &lt;code&gt;width&lt;/code&gt; e o &lt;code&gt;height&lt;/code&gt; do gráfico. A api fornece alguns parâmetros personalizáveis, é só dar uma olhadinha na documentação do &lt;a href="https://quickchart.io/" rel="noopener noreferrer"&gt;quickchart.io&lt;/a&gt; 🥰&lt;/p&gt;

&lt;p&gt;Feito isso, se você colocar a variável &lt;code&gt;$chartURL&lt;/code&gt; dentro de uma tag &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, a imagem deve aparecer. Porém, eu tive alguns problemas com inserir a variável direto e a imagem não aparecer dentro do pdf, então eu prefiro transformar essa imagem em &lt;code&gt;base64&lt;/code&gt; e ai sim enviar para o pdf.&lt;/p&gt;

&lt;p&gt;Para transformar a imagem em &lt;code&gt;base64&lt;/code&gt; é simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$chartURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="nv"&gt;$chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'data:image/png;base64, '&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$chartData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após, isso a variável &lt;code&gt;$chart&lt;/code&gt; já vai possuir o &lt;code&gt;base64&lt;/code&gt; da imagem, como vocês podem notar, eu concatenei no começo da variável o &lt;code&gt;data:image/png;base64,'&lt;/code&gt; porque é algo necessário para a tag &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; entender que a fonte da imagem é &lt;code&gt;base64&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Após todos esses passos, estamos prontos para enviar essa variável para o template &lt;code&gt;blade&lt;/code&gt; que irá gerar o pdf e incluir o gráfico dentro dele.&lt;/p&gt;

&lt;p&gt;Para enviar e incluir a imagem é simples, basta fazer isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$pdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PDF&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;loadView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'report.pdf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'chart'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$chart&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$pdf&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E no arquivo &lt;code&gt;report.blade.php&lt;/code&gt; (template do &lt;code&gt;report.pdf&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{$chart}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira, o gráfico aparecerá corretamente dentro do seu pdf.&lt;/p&gt;

&lt;p&gt;Qualquer dúvida, fico a disposição para ajudar.&lt;/p&gt;

&lt;p&gt;Meu github&lt;br&gt;
&lt;a href="https://github.com/leotheodoro" rel="noopener noreferrer"&gt;https://github.com/leotheodoro&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>javascript</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
