<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thomas Betous</title>
    <description>The latest articles on Forem by Thomas Betous (@tbetous).</description>
    <link>https://forem.com/tbetous</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%2F182466%2F51394d9a-819e-4f51-9811-739191d40cb7.png</url>
      <title>Forem: Thomas Betous</title>
      <link>https://forem.com/tbetous</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tbetous"/>
    <language>en</language>
    <item>
      <title>Cracking the code: How Copilot supercharged my last CTF and where it fell short</title>
      <dc:creator>Thomas Betous</dc:creator>
      <pubDate>Mon, 30 Jun 2025 12:02:18 +0000</pubDate>
      <link>https://forem.com/doctolib/cracking-the-code-how-copilot-supercharged-my-last-ctf-and-where-it-fell-short-5g1i</link>
      <guid>https://forem.com/doctolib/cracking-the-code-how-copilot-supercharged-my-last-ctf-and-where-it-fell-short-5g1i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnzc1aa74fjnzjzgs9hd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnzc1aa74fjnzjzgs9hd.jpg" alt="Using AI for CTF" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the years, I’ve always been drawn to riddles and brainteasers. It’s no surprise, then, that as a software engineer, I’ve always been interested in &lt;a href="https://en.wikipedia.org/wiki/Capture_the_flag_(cybersecurity)" rel="noopener noreferrer"&gt;Capture The Flag&lt;/a&gt; (CTF) cybersecurity challenges. In these challenges, you need to find a solution (hack) to retrieve a secret string hidden somewhere. This could be in a website, social media, assembly code, images, or any medium that can conceal information. These challenges require a broad range of knowledge, particularly in computer science and software engineering, but also creativity and inventiveness. However, I never dared to try because, in my mind, CTFs were reserved for the elite: the seasoned hackers with skills far beyond my own.&lt;/p&gt;

&lt;p&gt;Now, at 35, life is busier than ever. I recently became a father, and finding time for new pursuits feels almost impossible. But the itch to finally try a CTF remained. My main obstacles? A lack of time and the belief that I didn’t have enough knowledge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea61ht9dj43tqb9t0cgf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea61ht9dj43tqb9t0cgf.jpg" alt="Hacker vs me" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s when generative AI, like &lt;a href="https://openai.com/chatgpt/overview/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;, &lt;a href="https://gemini.google.com/" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt;, &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Github Copilot&lt;/a&gt; sparked an idea: what if I tried hacking with AI as my sidekick? To my surprise, not only were CTF challenges more accessible than I’d imagined, but AI assistants also helped me save precious time by accelerating my learning and problem-solving. Thanks to this partnership, I completed the &lt;a href="https://www.404ctf.fr/" rel="noopener noreferrer"&gt;404 CTF&lt;/a&gt; — one of France’s most famous competitions — and finished in a respectable 165th place out of more than 2,800 participants.&lt;/p&gt;

&lt;p&gt;In this article, I’ll share how I used AI to supercharge my hacking journey, the tips I picked up along the way, and where the limits of AI became clear. As a disclaimer before diving in, while I used &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; for this article, other technologies like &lt;a href="https://www.cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;, &lt;a href="https://claude.ai/login" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, and similar tools are equally valid choices. You can even use several of them simultaneously, the end goal remains the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  💬 Prompts I used the most and how I used them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Explain me the purpose of XXX?
&lt;/h3&gt;

&lt;p&gt;GitHub Copilot is an excellent assistant that &lt;a href="https://code.visualstudio.com/docs/copilot/overview" rel="noopener noreferrer"&gt;integrates seamlessly with VS Code&lt;/a&gt;. Microsoft’s plugin provides a powerful interface where you can query specific lines of code or use a dedicated console to focus Copilot’s attention on particular files or directories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxdkjtx4zbn4zdfqfuc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxdkjtx4zbn4zdfqfuc4.png" alt="Github Copilot inegration in VS Code" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since most CTF challenges begin with analyzing files, Copilot proved to be a perfect investigation tool. My typical workflow starts by asking Copilot to analyze the project, explain its purpose, and map out the function of each file. Then, I examine each file in detail, and whenever I encounter something unfamiliar, I ask Copilot to explain specific sections.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Copilot, could you explain the purpose of this project? Could you describe the function of each file and directory?"&lt;/em&gt; — prompt example&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For instance, one web security challenge included an nginx configuration file. While I don't regularly work with nginx configurations, by asking Copilot to explain specific instructions, I could quickly understand their purpose without leaving VS Code. This allowed me to learn just enough to efficiently identify potential attack vectors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2nsyaryzao8nazc5gpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2nsyaryzao8nazc5gpl.png" alt="Asking Copilot what's proxy_cache my_cache;" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An important consideration is that files aren't always immediately readable by Copilot (or any AI assistant). Sometimes you need to be creative with file formatting. For example, when challenges provide binary files, Copilot can't interpret them directly. The solution is to export the binary's hexadecimal or assembly code to a text file. This conversion makes the content accessible to Copilot for analysis. While this approach is valuable for initial investigation, sometime specialized tools are necessary for deeper analysis. In my last example, after the initial examination with Copilot, I had to switch to BinaryNinja for a more thorough investigation of the binary file.&lt;/p&gt;

&lt;p&gt;Another interesting example involves analyzing a pcapng file containing network captures. The challenge was to discover how a malicious user extracted a password from numerous network packets. While this file wasn't readable in VS Code and required Wireshark for viewing, it contained an overwhelming amount of data, including many irrelevant packets. To effectively analyze such data with an AI assistant, you first need to filter out the relevant packets (in my case, HTTP packets) through Wireshark and then export them to a more comprehensible format like JSON. It's essential to perform this initial filtering step, as otherwise, the AI assistant won't be able to analyze the data effectively due to the sheer volume of information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you see any security issues or unusual elements?
&lt;/h3&gt;

&lt;p&gt;After analyzing the structure of a challenge, there are times when I don't immediately spot relevant issues. In such scenarios, I ask Copilot to identify potential security vulnerabilities. Often, Copilot suggests multiple issues that provide a good foundation for starting to hack. This is where your skills as a hacker/developer become crucial, you need to evaluate and filter these suggestions, identifying which are viable and which aren't. You also need to find synergies and discover exploits that Copilot didn't explicitly mention. Frequently, challenges require exploiting multiple security vulnerabilities in combination rather than just a single issue.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Copilot, do you see any security issue or unusual elements in route.py? Do you see any deprecated dependencies?"&lt;/em&gt; — prompt example&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, in one web security challenge from the 404CTF, solving it required combining multiple vulnerabilities that Copilot helped identify such as issues in both the backend and proxy cache server. Out of the various potential problems Copilot pointed out, I had to analyze, select, and connect the relevant ones to reach the solution and extract the flag. This experience shows how AI can accelerate the investigative process, but still requires human intuition to piece everything together.&lt;/p&gt;

&lt;p&gt;Finally, when Copilot identifies vulnerabilities, the method of exploitation isn't always obvious. You can continue the conversation with your AI assistant by asking how to exploit these vulnerabilities and requesting more detailed information. Don't hesitate to ask about specific tools or request step-by-step instructions for executing your hack. Those questions are always instructive and provides valuable learning opportunities.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Copilot, what's a smuggle request and how can I do it ? Can you guide me step-by-step?"&lt;/em&gt; — prompt example&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Write a Python script to accomplish XXX?
&lt;/h3&gt;

&lt;p&gt;The analysis process generates numerous ideas. Generally, these ideas require some coding to create a proof of concept for a vulnerability. When you're unsure where to start and time is limited, asking an AI to write a small code snippet can be valuable. Copilot can adapt to your repository structure and generate files in the appropriate locations with the requested code. While not essential, this approach saves time.&lt;/p&gt;

&lt;p&gt;One crucial point to notice is that you need to be precise with your requirements; otherwise, the generated code may not align with your needs. Don't hesitate to specify the programming language, preferred libraries, and your desired outcome. The goal isn't to obtain perfect code, but rather to get something you can easily customize to suit your specific needs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Copilot, can you write a Python script with pwntools that connects to [IP] and [PORT], receives two numbers, adds them, and sends back the result."&lt;/em&gt; — prompt example&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔄 It's an iterative process
&lt;/h2&gt;

&lt;p&gt;This process is often iterative. Basically, after the global analysis, I enter a loop where I filter the data I have, analyze it, ask questions, inquire about security issues, and reflect on the results. Then, I reiterate again and again until I start to assemble pieces of the puzzle to solve the challenge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepursja1jo6dgvf8odb6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepursja1jo6dgvf8odb6.jpg" alt="Using AI for CTF process" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💔 What's the drawback of using AI for a CTF
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using AI is exhausting
&lt;/h3&gt;

&lt;p&gt;Using AI allows me to learn quickly, but it's exhausting. While you can access specific information and documentation faster than ever, it involves processing a lot of knowledge in a short time. You need to read extensively, maintain focus, and review every suggestion and generated code snippet. It's a different style of work. Counter-intuitively, working with an AI assistant actually consumes more energy than working alone. While one might think that having a computer do the thinking would require less effort, the reality is quite different.&lt;/p&gt;

&lt;p&gt;Working without an AI assistant is a steady hike; working with one is a sprint - you move faster, but it takes a lot more energy.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI == cheat?
&lt;/h3&gt;

&lt;p&gt;A legitimate question might be: is using AI cheating in a CTF? For the easiest challenges, like the Intro or Easy levels in 404CTF, AI can sometimes hand you the solution on a silver platter. But as soon as you move up to Medium or harder, the problems get too complex for Copilot or any AI to just solve for you.&lt;/p&gt;

&lt;p&gt;That's why I don't see AI as a cheat code. In reality, it's just one tool among many, like the ones real hackers use to break systems in the wild. Sometimes it helps, sometimes it doesn't, and it rarely cracks the tough challenges on its own. In cybersecurity, there are no shortcuts, just different methods and tools to reach your goal. And honestly, no hacker would refuse a useful tool just because it feels "unfair."&lt;/p&gt;

&lt;p&gt;AI mostly raises the floor, not the ceiling. It helps beginners level up faster, but expert won't suddenly become stronger thanks to AI alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI can be censored for certain types of questions
&lt;/h3&gt;

&lt;p&gt;Sometimes I encountered limitations with Copilot, likely due to ethical considerations. When attempting to create attacks, Copilot sometimes refuses to provide assistance. As a workaround, I needed to specify in my initial prompt that I was working in a CTF context. However, even with this clarification, Copilot might still censor certain responses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tfqys4grjqhymm3l1kn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tfqys4grjqhymm3l1kn.png" alt="Oups, Copilot don't want help me - Example of censorship" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's amusing to realize that you sometimes have to find creative ways to "hack" Copilot itself. It reminds me of Asimov's novels, where clever loopholes are found in the famous three laws of robotics. In a similar way, you need to think outside the box to get Copilot to do what you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI can push you to do some unsecure actions
&lt;/h3&gt;

&lt;p&gt;While asking Copilot how to exploit vulnerabilities, I sometimes received recommendations for tools whose safety I wasn't entirely confident about. When investigating these tools on GitHub, regardless of their quality, they often had few stars, indicating limited usage, and were frequently unmaintained with commits dating back years. This didn't inspire much confidence.&lt;/p&gt;

&lt;p&gt;For example, when I was looking for a password generator based on social knowledge, Copilot recommended tools like pypasswords. While I won't judge this tool's quality, it may be good but pypasswords' last commit was 5 years ago and the project only had 1 star. Without looking in more details, it can be dangerous to install such a library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyai7ti6lw2ehrxo49z8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyai7ti6lw2ehrxo49z8e.png" alt="Copilot tell me how to install pypasswords" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's why, as personal advice, I recommend not blindly trusting what your AI suggests when it comes to running commands or installing libraries. Always verify what you're about to execute.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI can lead you down the wrong path
&lt;/h3&gt;

&lt;p&gt;I think it's part of the experience, but I've lost count of the times Copilot has hallucinated issues where there were none, or assured me everything was fine when there was actually a subtle problem. I once spent hours trying to craft a smuggling request that turned out to be impossible - simply because Copilot suggested it might work. But as I mentioned earlier, this is a valuable lesson: don't blindly trust everything your AI suggests.&lt;/p&gt;

&lt;p&gt;That said, I'd put this into perspective based on your goals with CTFs. If your aim is to learn new skills, sometimes following the wrong leads can be incredibly educational.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Beyond the CTF
&lt;/h2&gt;

&lt;p&gt;Using AI to solve CTFs is fun, and I strongly encourage you to try it. You'll sharpen your AI skills for analysis and programming while learning extensively about specific domains. Personally, I focused mainly on web security since I specialize in web development. The knowledge I gained is valuable and helps me spot issues I might have missed before. It's all about honing your skills.&lt;/p&gt;

&lt;p&gt;At Doctolib, we actively encourage software engineers to embrace AI, not to work less, but to free up time for higher-value tasks that truly matter. This philosophy mirrors exactly what I experienced during my CTF journey.&lt;/p&gt;

&lt;p&gt;Just as I used AI to accelerate my learning and problem-solving in cybersecurity challenges, at Doctolib, we leverage tools like GitHub Copilot, Cursor, and Claude Code to streamline routine coding tasks, accelerate debugging, and enhance code exploration. The goal isn't to replace our expertise, but to augment it allowing us to focus on architectural decisions, complex problem-solving, and innovative solutions that improve healthcare for millions of patients.&lt;/p&gt;

&lt;p&gt;Whether it's analyzing nginx configurations in a CTF challenge or refactoring critical healthcare infrastructure at Doctolib, AI serves as an amplifier of human intelligence. The key lesson from both contexts remains the same: AI is most powerful when it enhances human judgment, not when it replaces it.&lt;/p&gt;

&lt;p&gt;Thank you for reading. If you have any questions or insights to share, feel free to reach out or leave a comment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Special thanks to Justin Rabiller for reviewing this article and providing valuable insights.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>ai</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>Javascript console API : 9 helpful tips</title>
      <dc:creator>Thomas Betous</dc:creator>
      <pubDate>Mon, 27 Jan 2020 13:51:29 +0000</pubDate>
      <link>https://forem.com/tbetous/javascript-console-api-9-helpful-tips-3fa9</link>
      <guid>https://forem.com/tbetous/javascript-console-api-9-helpful-tips-3fa9</guid>
      <description>&lt;p&gt;If you daily work with javascript, I bet you use the &lt;code&gt;console.log&lt;/code&gt; method a lot. But have you already tried to see what the &lt;code&gt;console&lt;/code&gt; object looks like ?&lt;/p&gt;

&lt;p&gt;Well, let's have a look :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0pyow1s3sclpk2g3jlq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0pyow1s3sclpk2g3jlq.PNG" alt="Alt console object" width="499" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, &lt;code&gt;console&lt;/code&gt; object own far more methods than &lt;code&gt;log&lt;/code&gt;. The purpose of this article is to demistify &lt;code&gt;console&lt;/code&gt; API and show you what you can do with it. At the end of this article you should be able to display your logs correctly, evaluate performance of your code and debug your code more efficiently. This article should be useful if you use javascript both for browser or nodeJS !&lt;/p&gt;

&lt;h2&gt;
  
  
  🎛️ Use logging levels
&lt;/h2&gt;

&lt;p&gt;Use different logging levels can be very useful to easily debug and observe how your application runs. Console API has several methods to log a message :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log" rel="noopener noreferrer"&gt;&lt;code&gt;log&lt;/code&gt;&lt;/a&gt; : It will display general message in the console&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/debug" rel="noopener noreferrer"&gt;&lt;code&gt;debug&lt;/code&gt;&lt;/a&gt; : It will display debug message in the console&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/info" rel="noopener noreferrer"&gt;&lt;code&gt;info&lt;/code&gt;&lt;/a&gt; : It will display informative message in the console&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/warn" rel="noopener noreferrer"&gt;&lt;code&gt;warn&lt;/code&gt;&lt;/a&gt; : It will display a warning message in the console&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/error" rel="noopener noreferrer"&gt;&lt;code&gt;error&lt;/code&gt;&lt;/a&gt; : It will display a error message in the console &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these methods can be used with two different ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can pass as argument one or more objects you want to display&lt;/li&gt;
&lt;li&gt;You can pass as first argument a string with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions" rel="noopener noreferrer"&gt;substitution strings&lt;/a&gt; and each of these will pull the next argument in order to format the string.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see an 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="c1"&gt;// with one or more objects as arguement&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;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toto&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Displays log :&lt;/span&gt;
&lt;span class="c1"&gt;// Toto 1 {test: 1}&lt;/span&gt;

&lt;span class="c1"&gt;// With the substitution strings&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;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, my name is %s. I am %d.&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="s2"&gt;Thomas&lt;/span&gt;&lt;span class="dl"&gt;"&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="c1"&gt;// Displays log :&lt;/span&gt;
&lt;span class="c1"&gt;// Hello, my name is Thomas. I am 30.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you log a lot of messages, keep in mind that some browsers like Chrome or Firefox allow to filter logs with regex and logging level :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frukhg89x07ppbe3f8s1c.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frukhg89x07ppbe3f8s1c.PNG" alt="Alt Chrome : console example with log filter" width="499" height="645"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console example with log filter (exclude warning)






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohxehwj2gukhx5hs3v3m.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohxehwj2gukhx5hs3v3m.PNG" alt="Alt Firefox : console example with log filter" width="501" height="644"&gt;&lt;/a&gt;&lt;/p&gt;
Firefox : console example with log filter (exclude warning)



&lt;p&gt;Note that the logging level of messages produce with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log" rel="noopener noreferrer"&gt;&lt;code&gt;log&lt;/code&gt;&lt;/a&gt; method can be different between browsers. For example Chrome will not make differences between &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log" rel="noopener noreferrer"&gt;&lt;code&gt;log&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/info" rel="noopener noreferrer"&gt;&lt;code&gt;info&lt;/code&gt;&lt;/a&gt; while Firefox will.&lt;/p&gt;

&lt;p&gt;Finally, if you use nodeJS, you should know that &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt; and &lt;code&gt;info&lt;/code&gt; are the same methods, they all print messages to &lt;code&gt;stdout&lt;/code&gt;. &lt;code&gt;warn&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt; are the same methods, they both print messages to &lt;code&gt;stderr&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗃️ Group logs
&lt;/h2&gt;

&lt;p&gt;Sometime it can be useful to group your log messages in order to make them more readable. Console API has several methods to group log messages :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/group" rel="noopener noreferrer"&gt;&lt;code&gt;group&lt;/code&gt;&lt;/a&gt; : Creates a new inline group, indenting all following output by another level. To move back out a level, call &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/groupEnd" rel="noopener noreferrer"&gt;&lt;code&gt;groupEnd()&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/groupCollapsed" rel="noopener noreferrer"&gt;&lt;code&gt;groupCollapsed&lt;/code&gt;&lt;/a&gt; : Creates a new inline group, indenting all following output by another level. However, unlike &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/group" rel="noopener noreferrer"&gt;&lt;code&gt;group()&lt;/code&gt;&lt;/a&gt; this starts with the inline group collapsed requiring the use of a disclosure button to expand it. To move back out a level, call &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/groupEnd" rel="noopener noreferrer"&gt;&lt;code&gt;groupEnd()&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/groupEnd" rel="noopener noreferrer"&gt;&lt;code&gt;groupEnd&lt;/code&gt;&lt;/a&gt; : Exits the current inline group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a trivial 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;sharedFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sharedFunc&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="nx"&gt;n&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="mi"&gt;1&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;n&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I have been called %d !&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&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="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;sharedFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;groupEnd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;groupCollapsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&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="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;sharedFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;groupEnd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;foo&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="nf"&gt;bar&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="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;foo&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;The result of this will group your log messages by indenting them and making them more readable :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyet3rqdg0n1zsisfzqt2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyet3rqdg0n1zsisfzqt2.PNG" alt="Alt Chrome : Group log messages" width="499" height="740"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : Group log messages



&lt;p&gt;You can see there is a little arrow next to each group that allow to fold or unfold the content of a group.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/group" rel="noopener noreferrer"&gt;&lt;code&gt;group&lt;/code&gt;&lt;/a&gt; method, the group is automatically unfold&lt;/li&gt;
&lt;li&gt;When you use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/groupCollapsed" rel="noopener noreferrer"&gt;&lt;code&gt;groupCollapsed&lt;/code&gt;&lt;/a&gt; method, the group is automatically fold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the interface may differ between browsers.&lt;/p&gt;

&lt;p&gt;Finally, if you use nodeJS you will not have the ability to fold or unfold groups and only the indentation will be displayed. Consequently, &lt;a href="https://nodejs.org/api/console.html#console_console_group_label" rel="noopener noreferrer"&gt;&lt;code&gt;group&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://nodejs.org/api/console.html#console_console_groupcollapsed" rel="noopener noreferrer"&gt;&lt;code&gt;groupCollapsed&lt;/code&gt;&lt;/a&gt; are the same method.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Assert what is expected
&lt;/h2&gt;

&lt;p&gt;Have you already written a piece of code which the goal is to debug by displaying a log message if something is wrong? Console API has a method to check an assert and display a log message if it is false:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log" rel="noopener noreferrer"&gt;&lt;code&gt;assert&lt;/code&gt;&lt;/a&gt; : Log a message and stack trace to console if the first argument is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method can be used with two different ways :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can pass as argument one or more objects you want to display&lt;/li&gt;
&lt;li&gt;You can pass as first argument a string with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions" rel="noopener noreferrer"&gt;substitution strings&lt;/a&gt; and each of these will pull the next argument in order to format the string.
&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;test&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="c1"&gt;// with one or more objects as arguement&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;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toto&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Displays error log :&lt;/span&gt;
&lt;span class="c1"&gt;// Assertion failed: Toto 1 {test: 1}&lt;/span&gt;

&lt;span class="c1"&gt;// With the substitution strings&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;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;life should be %d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Displays error log :&lt;/span&gt;
&lt;span class="c1"&gt;// Assertion failed: life should be 42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result you will have in Chrome :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspwvgs0gdzxv2bzxoiqb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspwvgs0gdzxv2bzxoiqb.PNG" alt="Alt Chrome : console.assert result" width="499" height="336"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console.assert result



&lt;p&gt;With this syntax you can write your debug code with a faster and easier way than a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/error" rel="noopener noreferrer"&gt;&lt;code&gt;console.error&lt;/code&gt;&lt;/a&gt; wrapped in a condition block.&lt;/p&gt;

&lt;p&gt;Finally, if you use nodeJS, you should know that even if &lt;a href="https://nodejs.org/api/console.html#console_console_assert_value_message" rel="noopener noreferrer"&gt;&lt;code&gt;assert&lt;/code&gt;&lt;/a&gt; method works well, it sends log messages to &lt;code&gt;stdout&lt;/code&gt;. It is recommended to use &lt;a href="https://nodejs.org/api/assert.html" rel="noopener noreferrer"&gt;assertion API&lt;/a&gt; that provides more methods and sends log messages to &lt;code&gt;stderr&lt;/code&gt; by throwing &lt;a href="https://nodejs.org/api/assert.html#assert_class_assert_assertionerror" rel="noopener noreferrer"&gt;AssertionError&lt;/a&gt; when assertion is false.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧮 Count code execution
&lt;/h2&gt;

&lt;p&gt;While you are debbuging, you may want to know how many time a piece of code or a function is executed. Console API has several methods to log how many time your code has been executed :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/count" rel="noopener noreferrer"&gt;&lt;code&gt;count&lt;/code&gt;&lt;/a&gt; : Log the number of times this line has been called with the given label.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/countReset" rel="noopener noreferrer"&gt;&lt;code&gt;countReset&lt;/code&gt;&lt;/a&gt; : Resets the value of the counter with the given label.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/count" rel="noopener noreferrer"&gt;&lt;code&gt;count&lt;/code&gt;&lt;/a&gt; method associates a label with a count value in the same way as a map. Each time you will call the method you will increment the associate value by one and display its value in log. Note that if no label is given, the string 'default' is set as label. Let's see an 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;resetDay&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wake&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exercise&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eat&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;work&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;play&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;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sleep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;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="mi"&gt;0&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="mi"&gt;2&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`day &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wake&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exercise&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eat&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;work&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eat&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;work&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;play&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eat&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;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sleep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nf"&gt;resetDay&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;groupEnd&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;Here is the result you will have in Chrome :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87m8bzi6kib2pora0or5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87m8bzi6kib2pora0or5.PNG" alt="Alt Chrome : console.count result" width="559" height="543"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console.count result



&lt;h2&gt;
  
  
  ⏱️ Time code execution
&lt;/h2&gt;

&lt;p&gt;When your app seems to be slow you may want to start to time your code in order to know where you need optimizations. Console API has several methods to time your code execution :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/time" rel="noopener noreferrer"&gt;&lt;code&gt;time&lt;/code&gt;&lt;/a&gt; : Starts a timer with a name specified as an input parameter.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/timeLog" rel="noopener noreferrer"&gt;&lt;code&gt;timeLog&lt;/code&gt;&lt;/a&gt; : Logs the value of the specified timer to the console.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd" rel="noopener noreferrer"&gt;&lt;code&gt;timeEnd&lt;/code&gt;&lt;/a&gt; : Stops the specified timer and logs the elapsed &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/time" rel="noopener noreferrer"&gt;&lt;code&gt;time&lt;/code&gt;&lt;/a&gt;in seconds since it started.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that if no name is given, the string 'default' is set as name. Let's see an 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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&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;timeLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nf"&gt;setTimeout&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;timeEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&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="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result in Chrome : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6zdrujn4z53u1edyjm8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6zdrujn4z53u1edyjm8.PNG" alt="Alt Chrome : Time the execution" width="559" height="589"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : Time the execution



&lt;h2&gt;
  
  
  📍 Add markers
&lt;/h2&gt;

&lt;p&gt;If you use browser performance tool, you should know that it is possible to add markers in the execution workflow. This displays events in the tool interface making your debugging easier. Console API has a method to do that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/timeStamp" rel="noopener noreferrer"&gt;&lt;code&gt;timeStamp&lt;/code&gt;&lt;/a&gt; : Adds a marker to the browser's performance tools.
&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeStamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&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 is the result in Firefox : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgr9y7sseetrhisjhrh93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgr9y7sseetrhisjhrh93.png" alt="Alt Firefox Performance tool: console.timeStamp result" width="501" height="645"&gt;&lt;/a&gt;&lt;/p&gt;
Firefox Performance tool: console.timeStamp result with string 'test'



&lt;h2&gt;
  
  
  ✨ Display data in a table
&lt;/h2&gt;

&lt;p&gt;When you want to display a complex object or array in the console, you should known that it is possible to display it as a table easying its read. Console API has a method to do that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/table" rel="noopener noreferrer"&gt;&lt;code&gt;table&lt;/code&gt;&lt;/a&gt; : Displays tabular data as a table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an 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;robert&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="s2"&gt;Robert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;30&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;favoriteColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&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;jack&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="s2"&gt;Jack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;35&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;favoriteColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pink&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;marie&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="s2"&gt;Marie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;favoriteColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&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;tom&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="s2"&gt;Tom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;favoriteColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&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;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;robert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;marie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tom&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;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jack&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;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result in Chrome : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl13g9jm7xhi0kitqlnxd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl13g9jm7xhi0kitqlnxd.PNG" alt="Alt Chrome : console.table result" width="499" height="543"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console.table result



&lt;h2&gt;
  
  
  🔎 Display stack trace
&lt;/h2&gt;

&lt;p&gt;While debugging you may want to know the call path of a point of your code execution while running. Console API has a method to display the stack trace :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/trace" rel="noopener noreferrer"&gt;&lt;code&gt;trace&lt;/code&gt;&lt;/a&gt; : Outputs a stack trace.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is how to use it :&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;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bar&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;trace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here is the result in Chrome : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcexwgjec7wvd3pm7myn6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcexwgjec7wvd3pm7myn6.PNG" alt="Alt Chrome : console.trace result" width="499" height="543"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console.trace result



&lt;h2&gt;
  
  
  🧼 Clean the console
&lt;/h2&gt;

&lt;p&gt;When your console become a mess and you want to erase all of it, the console API provide you with a method to do that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/clear" rel="noopener noreferrer"&gt;&lt;code&gt;clear&lt;/code&gt;&lt;/a&gt; : Clear the console.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is how to use it :&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 will clear the console&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;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result in Chrome : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxymjiw4avns7l5rdnud.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxymjiw4avns7l5rdnud.PNG" alt="Alt Chrome : console.clear result" width="559" height="543"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome : console.clear result



&lt;h2&gt;
  
  
  🎉 Congratulations !
&lt;/h2&gt;

&lt;p&gt;Congratulations ! You know all you need to know about console API ! Hope it will help you in your future debugging sessions.&lt;/p&gt;

&lt;p&gt;If you liked this post, do not hesitate to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow me on twitter: &lt;a href="https://twitter.com/tbetous" rel="noopener noreferrer"&gt;@tbetous&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Share this post !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for showing interest and reading this 🎉&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>👷 How to make conditionnal resources in terraform?</title>
      <dc:creator>Thomas Betous</dc:creator>
      <pubDate>Wed, 11 Sep 2019 07:54:30 +0000</pubDate>
      <link>https://forem.com/tbetous/how-to-make-conditionnal-resources-in-terraform-440n</link>
      <guid>https://forem.com/tbetous/how-to-make-conditionnal-resources-in-terraform-440n</guid>
      <description>&lt;p&gt;I’d like to share my experience about conditional resources in terraform with this short article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case 🤔
&lt;/h2&gt;

&lt;p&gt;Here is my use case. I am currently experiment lambdas (AWS cloud functions) for a project. My problem is that I don’t know which programming language is the most suitable for my use case. This is why I would like to make a benchmark about execution time and memory consumption for each language.&lt;/p&gt;

&lt;p&gt;What I want is to create a terraform configuration that is able to switch my lambda from javascript to java by setting a parameter to &lt;code&gt;"javascript"&lt;/code&gt; or &lt;code&gt;"java"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 🤯
&lt;/h2&gt;

&lt;p&gt;My solution was using &lt;a href="https://www.terraform.io/docs/configuration/resources.html#meta-arguments" rel="noopener noreferrer"&gt;meta-arguments&lt;/a&gt;. The &lt;a href="https://www.terraform.io/docs/configuration/resources.html#count-multiple-resource-instances-by-count" rel="noopener noreferrer"&gt;count&lt;/a&gt; meta-argument allows to specify how many instances you want to create.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Step 1 : Create your input parameter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"lambda_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"string"&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"java"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👉 Step 2 : Create your resources
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;my_function_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"awesome-function"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"my_lambda_java"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.jar"&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;my_function_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;handler&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Handler"&lt;/span&gt;
  &lt;span class="nx"&gt;runtime&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"java8"&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lambda_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"java"&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"my_lambda_javascript"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.jar"&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;my_function_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;handler&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"index.handler"&lt;/span&gt;
  &lt;span class="nx"&gt;runtime&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nodejs10.x"&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lambda_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"javascript"&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the ternary condition to set &lt;code&gt;count&lt;/code&gt; to 0 or 1 in function of &lt;code&gt;lambda_type&lt;/code&gt; value.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Step 3 : Create a data variable to access your conditional resources from the same id
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"my_lambda"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;my_function_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aws_lambda_function.my_lambda_java"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function.my_lambda_javascript"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// For instance if your lambda is attached to another resource, &lt;/span&gt;
&lt;span class="c1"&gt;// you just have to use the same resource id for both (java &amp;amp; javascript)&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_permission"&lt;/span&gt; &lt;span class="s2"&gt;"my_lambda_permission"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;statement_id&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AllowExecutionFromSNS"&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_lambda_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;my_lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;principal&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sns.amazonaws.com"&lt;/span&gt;
  &lt;span class="nx"&gt;source_arn&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;aws_sns_topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that the &lt;code&gt;depends_on&lt;/code&gt; property is really important. If you don't use that property, terraform will try to fetch lambda function that doesn't exist yet. Plus, this only work for terraform 0.12 which allows to &lt;a href="https://github.com/hashicorp/terraform/issues/15285#issuecomment-447971852" rel="noopener noreferrer"&gt;use &lt;code&gt;depends_on&lt;/code&gt; with resource with &lt;code&gt;count = 0&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Step 4 : Plan and apply your terraform
&lt;/h3&gt;

&lt;p&gt;Finally, you just have to apply your terraform configuration with the suitable parameter :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For javascript&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform plan &lt;span class="nt"&gt;--var&lt;/span&gt; &lt;span class="s2"&gt;"lambda-type=javascript"&lt;/span&gt;
&lt;span class="c"&gt;# If the plan is correct to what you expect :&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform apply &lt;span class="nt"&gt;--var&lt;/span&gt; &lt;span class="s2"&gt;"lambda-type=javascript"&lt;/span&gt;

&lt;span class="c"&gt;# For java&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform plan &lt;span class="nt"&gt;--var&lt;/span&gt; &lt;span class="s2"&gt;"lambda-type=java"&lt;/span&gt;
&lt;span class="c"&gt;# If the plan is correct to what you expect :&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform apply &lt;span class="nt"&gt;--var&lt;/span&gt; &lt;span class="s2"&gt;"lambda-type=java"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👉 Step 5 : Clean resources (optional)
&lt;/h3&gt;

&lt;p&gt;If you did some tests by following this article, do not forget to clean your environment by destroying resources !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Congratulations ! 🎉
&lt;/h2&gt;

&lt;p&gt;Congratulations ! You did it ! Now you can add resources conditionnaly and therefore make your terraform configuration more parameterizable !&lt;/p&gt;

&lt;p&gt;If you liked this post, do not hesitate to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow me on twitter: &lt;a href="https://twitter.com/tbetous" rel="noopener noreferrer"&gt;@tbetous&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Share this post !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank You for showing interest and reading this 🎉&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>cloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🛡️ How to safely access deeply nested values in javascript?</title>
      <dc:creator>Thomas Betous</dc:creator>
      <pubDate>Thu, 05 Sep 2019 15:56:10 +0000</pubDate>
      <link>https://forem.com/tbetous/how-to-safely-access-deep-nested-values-in-javascript-5b2a</link>
      <guid>https://forem.com/tbetous/how-to-safely-access-deep-nested-values-in-javascript-5b2a</guid>
      <description>&lt;p&gt;I would like to share a problem I had today and how I solved it. It is about the way to access deeply nested values in javascript. Here is a simple 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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enablePrivateMessage&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="na"&gt;enableCommentResponse&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's the problem ?
&lt;/h2&gt;

&lt;p&gt;This works fine, however what's happen if &lt;code&gt;options&lt;/code&gt; or &lt;code&gt;notification&lt;/code&gt; are &lt;code&gt;undefined&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot read property 'notification' of undefined&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&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;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot read property 'enablePrivateMessage' of undefined&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Yep, that's embarrassing ! It's not safe to access deeply nested values if you're not sure that the intermediate values are set. In the previous example, I tried to access the property &lt;code&gt;enablePrivateMessage&lt;/code&gt; of &lt;code&gt;notification&lt;/code&gt;, but unfortunately &lt;code&gt;notification&lt;/code&gt; has not been set in &lt;code&gt;options&lt;/code&gt; and consequently is equal to &lt;code&gt;undefined&lt;/code&gt;. The error message tells me that I tried to access &lt;code&gt;enablePrivateMessage&lt;/code&gt; propery from something &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve it ?
&lt;/h2&gt;

&lt;p&gt;A first solution to this problem could be to browse nested properties one at a time and check if their values are &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; before accessing to the following nested 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;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&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;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt; 
&lt;span class="c1"&gt;// enablePrivateMessage == undefined&lt;/span&gt;

&lt;span class="c1"&gt;// alternative way&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
    &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
        &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt; 
&lt;span class="c1"&gt;// enablePrivateMessage == undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this works for simple cases, it could be painful to write that if your object is very depth. The code would be very long and difficult to read. Fortunately as the same way as &lt;a href="https://github.com/lodash/lodash/blob/master/get.js" rel="noopener noreferrer"&gt;lodash &lt;code&gt;get&lt;/code&gt; function&lt;/a&gt;, we can design a function to safely access properties. Here it is :&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPropValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&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;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&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="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;o&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;o&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;object&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;options&lt;/span&gt; &lt;span class="o"&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;enablePrivateMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPropValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notification.enablePrivateMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// enablePrivateMessage == undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does it work ? &lt;code&gt;getPropValue&lt;/code&gt; is a function that takes two parameters. The first one is the &lt;code&gt;object&lt;/code&gt; to query and the second one is the &lt;code&gt;path&lt;/code&gt; to a nested prop we hope to find. When the function is executed, we split the path in an array in order to get all nested properties to browse.&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;// Example&lt;/span&gt;
&lt;span class="c1"&gt;// path = 'notification.enablePrivateMessage'&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notification.enablePrivateMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// ['notification', 'enablePrivateMessage']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we execute a &lt;a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce" rel="noopener noreferrer"&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/a&gt; function from that array with an aggregator initially set with the object to query. The &lt;code&gt;reduce&lt;/code&gt; function browses all properties in the path and if one of these have an undefined value, then the result will be &lt;code&gt;undefined&lt;/code&gt;. Otherwise the value of the nested prop is returned.&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;// Example 1 : All properties are defined in the path&lt;/span&gt;
&lt;span class="c1"&gt;// object = {notification: {enablePrivateMessage: true}}&lt;/span&gt;
&lt;span class="c1"&gt;// path = 'notification.enablePrivateMessage'&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notification&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;enablePrivateMessage&lt;/span&gt;&lt;span class="dl"&gt;'&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;o&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="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="nx"&gt;o&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;o&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;enablePrivateMessage&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="c1"&gt;// {notification: {enablePrivateMessage: true}} 'notification'&lt;/span&gt;
&lt;span class="c1"&gt;// {enablePrivateMessage: true} 'enablePrivateMessage'&lt;/span&gt;
&lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// Example 2 : notification is undefined&lt;/span&gt;
&lt;span class="c1"&gt;// object = {}&lt;/span&gt;
&lt;span class="c1"&gt;// path = 'notification.enablePrivateMessage'&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notification&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;enablePrivateMessage&lt;/span&gt;&lt;span class="dl"&gt;'&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;o&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="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="nx"&gt;o&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;o&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="c1"&gt;// {} 'notification'&lt;/span&gt;
&lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's about ES6 destructuring ?
&lt;/h2&gt;

&lt;p&gt;Well, that's good ! But since ES6, destructuring feature is available in Javascript. This feature is really nice and allows developpers to easily declare and set variables with the nested properties of an object.&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enablePrivateMessage&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="na"&gt;enableCommentResponse&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&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;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// true&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;enableCommentResponse&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;p&gt;However, I cannot use my &lt;code&gt;getPropValue&lt;/code&gt; function in this case. If &lt;code&gt;options&lt;/code&gt; is &lt;code&gt;undefined&lt;/code&gt;, then the previous destructuring will result an error.&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot destructure property `notification` of 'undefined' or 'null'.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple way to protect our code against that error is to set a fallback value if &lt;code&gt;options&lt;/code&gt; is &lt;code&gt;undefined&lt;/code&gt;. But it is not enough.&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot destructure property `enablePrivateMessage` of 'undefined' or 'null'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you did that, you need to set default values for all your nested properties before to get the wanted properties.&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enableCommentResponse&lt;/span&gt;&lt;span class="p"&gt;}&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;options&lt;/span&gt; &lt;span class="o"&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;enablePrivateMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// undefined&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;enableCommentResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not as convenient as &lt;code&gt;getPropValue&lt;/code&gt; function if the properties you want are very depth. In this case, you should consider that destructuring may not be the best way to access your properties because your instruction will be too long to be readable. In this case I recommand to access your properties one at a time with &lt;code&gt;getPropValue&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lodash can help you !
&lt;/h2&gt;

&lt;p&gt;You should know that &lt;code&gt;getPropValue&lt;/code&gt; is a function I designed for this post. In real life I use the &lt;a href="https://lodash.com/docs/4.17.11#get" rel="noopener noreferrer"&gt;lodash &lt;code&gt;get&lt;/code&gt; function&lt;/a&gt;. It is really usefull in many cases and work likely &lt;code&gt;getPropValue&lt;/code&gt;. There is an extra parameter that allow you to set a fallback value if your path reach an undefined value before to get the targeted property.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enablePrivateMessage&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="na"&gt;enableCommentResponse&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Example 1 : Simple case&lt;/span&gt;
&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notification.enablePrivateMessage&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&lt;/span&gt;

&lt;span class="c1"&gt;// Example 2 : Error case with 'fallback' as fallback value&lt;/span&gt;
&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toto.tata&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;fallback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// 'fallback'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You know all you need to know to safely access deep nested values in javascript! Hope you enjoyed my first post in &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
