<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cornelia</title>
    <description>The latest articles on DEV Community by Cornelia (@soliloquizin).</description>
    <link>https://dev.to/soliloquizin</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%2F686240%2Fda0e8d43-0d14-4dc5-a07e-f15b2101c9e5.jpeg</url>
      <title>DEV Community: Cornelia</title>
      <link>https://dev.to/soliloquizin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/soliloquizin"/>
    <language>en</language>
    <item>
      <title>Why Focusing on the 'Why' Matters in Scrum</title>
      <dc:creator>Cornelia</dc:creator>
      <pubDate>Fri, 29 Dec 2023 12:47:41 +0000</pubDate>
      <link>https://dev.to/soliloquizin/the-importance-of-value-communication-in-scrum-1nd8</link>
      <guid>https://dev.to/soliloquizin/the-importance-of-value-communication-in-scrum-1nd8</guid>
      <description>&lt;p&gt;It's so easy to forget the &lt;em&gt;why&lt;/em&gt; when the feature requests already tell you what you're supposed to do. But something's wrong. It feels like you're going back and forth and sideways, just like a wobbly wheel. It's hard to get a grasp on what you're actually working on and it slowly affects your work satisfaction and team morale.&lt;/p&gt;

&lt;p&gt;As a developer and Product Owner, I've experienced what the lack of clearly communicated values can do to a Scrum team and its product. In this article, I explore the importance of transparent value in various elements of Scrum:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Product Vision,&lt;/li&gt;
&lt;li&gt;Product Backlog Items,&lt;/li&gt;
&lt;li&gt;Sprint Goal, and&lt;/li&gt;
&lt;li&gt;Sprint Review&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Product Vision
&lt;/h3&gt;

&lt;p&gt;The Product Vision provides guidance. It describes what we want to achieve and why, and who we want to achieve it for.&lt;/p&gt;

&lt;p&gt;I've worked on a couple of projects already where the developers didn't really know what the Product Vision was. There were two reasons for that. Either the Product Vision wasn't communicated clearly, but the Product Owner tried to keep things aligned with the vision. Developers also make decisions while they work on the product. Therefore it's crucial for them to also know what the long-term goal is.&lt;/p&gt;

&lt;p&gt;In the other cases, there simply was no vision - or rather, the vision was like a leaf in the wind. In my experience, this has the most negative impact on team morale. A lack of vision often results in evaluating, planning, and developing features only to discover late in the process or afterwards that this feature isn't needed, or essential requirements and specifications were missing or wrong. Again, and again, and again. Besides the confusion, it also gives the feeling of investing a lot of effort to produce fancy waste. The constant change of direction can cause more impediments with external dependencies and in the stakeholder communication. All of this resulting in a team of developers that - in the best case - stop being interested in and caring for the product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product Backlog Items
&lt;/h3&gt;

&lt;p&gt;The lack of a proper product vision often also causes the lack of communicated value on Product Backlog Items. It should always be clear which user need causes a Product Backlog Item. The solution to that need should be open for discussion and experimentation and is therefore optional! If the provided solution is already verified, the item should still state the value it's expected to achieve. This ensures that team members still think about it and challenge the suggested solution if they can think of potentially better ways to approach this need.&lt;/p&gt;

&lt;p&gt;Providing the expected value also supports keeping the focus on what you want to achieve with this product. Items that provide value that doesn't contribute to the Product Vision can be easily identified.&lt;/p&gt;

&lt;p&gt;Having the value on each Product Backlog Item nurtures team alignment and the team's engagement. As a consequence, the team is more likely interested and invested in the product, which has a positive impact on the team's mood.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sprint Goal
&lt;/h3&gt;

&lt;p&gt;Most Scrum teams I've worked with as a developer struggled with defining Sprint Goals. Sprint Goals state the main value the team wants to create in the Sprint. They, therefore, provide guidance, focus and a common ground to work with. In addition, without a proper Sprint Goal, it's far easier to fall into the trap of making the Daily Scrum a reporting meeting instead of a working and work coordination session.&lt;/p&gt;

&lt;p&gt;When Product Backlog Items aren't prioritized (correctly), Sprint Planning is difficult and the team's planned work items are all over place, providing no clear value and thus no clear Sprint Goal. Usually, this is a consequence of the lack of a clear Product Vision and/or lack of value on the Backlog Items. Sometimes, there are other reasons, like availability of the Product Owner, or lack of ownership.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sprint Review
&lt;/h3&gt;

&lt;p&gt;It's important to communicate the Product Vision and the Sprint Goal in the Sprint Review. It provides context for what the team aimed to achieve and reminds the participants of what parameters to base their feedback on. I've attended reviews that lacked this clear communication and thus opened doors for feature requests that were irrelevant for the current product vision. It also opens doors for turning this working session into a reporting meeting.&lt;/p&gt;

&lt;p&gt;Another effect this can have is that stakeholders stop attending the Sprint Reviews. Stakeholders are usually very busy, so it's crucial for them to understand why it's important that they attend and provide feedback. Providing context makes it easier for them to contribute and thus provide value for the product development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaway
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Gaps in value communication cause confusion and wasted effort.&lt;/li&gt;
&lt;li&gt;When we focus on the 'why' in what we build, we increase team and stakeholder engagement, product quality, and team satisfaction.&lt;/li&gt;
&lt;li&gt;When you define the destination, the path becomes clear and is more enjoyable to follow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Can you relate to any of those experiences? Where have you encountered gaps in value communication?&lt;/p&gt;

&lt;p&gt;Thanks for reading and keep asking 'why'!&lt;/p&gt;

</description>
      <category>scrum</category>
      <category>productmanagement</category>
      <category>agile</category>
      <category>productdevelopment</category>
    </item>
    <item>
      <title>Debugging beyond console.log</title>
      <dc:creator>Cornelia</dc:creator>
      <pubDate>Sun, 17 Jul 2022 23:36:30 +0000</pubDate>
      <link>https://dev.to/soliloquizin/debugging-beyond-consolelog-4am5</link>
      <guid>https://dev.to/soliloquizin/debugging-beyond-consolelog-4am5</guid>
      <description>&lt;p&gt;In the past 10 years, I’ve worked with many other web developers and noticed something odd: many devs do not use the full arsenal for debugging in the browser - no matter what level they are at.&lt;/p&gt;

&lt;p&gt;For this article I’ve set up a simple application on &lt;a href="https://stackblitz.com" rel="noopener noreferrer"&gt;stackblitz&lt;/a&gt; you can use to follow along as we explore how to debug using &lt;strong&gt;breakpoints&lt;/strong&gt;, &lt;strong&gt;watch&lt;/strong&gt;, the &lt;strong&gt;Call Stack&lt;/strong&gt; and various &lt;strong&gt;console methods&lt;/strong&gt; for improved logging. Finally, we will also look into &lt;strong&gt;debugging with redirects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo application
&lt;/h2&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%2Fpuyzglrg2gvuhvonrakr.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%2Fpuyzglrg2gvuhvonrakr.JPG" alt="Image description" width="545" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app is a modified version of &lt;a href="https://www.w3schools.com/howto/howto_js_todolist.asp" rel="noopener noreferrer"&gt;W3School’s “How TO - Create a To Do List” app&lt;/a&gt;. It is a simple to-do app that lets you add texts via input field and button to a list of existing to-dos. You cannot add empty or duplicate values to the list. After adding an item, the input field is cleared. Clicking on a list item toggles its done-state. Each entry also has a button to delete it.&lt;/p&gt;

&lt;p&gt;The button below the list redirects the user to another stackblitz app that redirects to google. It’s initially disabled but we will use it at the end of the tutorial to look into debugging despite page loads or redirects.&lt;/p&gt;

&lt;p&gt;For the first sections, we only need the rendered app and the developer tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://js-cl89rs.stackblitz.io" rel="noopener noreferrer"&gt;Open the demo app to follow along&lt;/a&gt;.&lt;br&gt;
Can’t wait to see the code? &lt;a href="https://stackblitz.com/edit/js-cl89rs?file=index.html,index.js" rel="noopener noreferrer"&gt;Check out the app in edit mode&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakpoints
&lt;/h2&gt;

&lt;p&gt;Do you ever wonder what happens to a value in a function that calls twenty other functions to modify it? Do you then find yourself logging it after each and every one of them? You can use breakpoints for these and other situations. A breakpoint will halt the execution of a script allowing you to check exactly what is going on, which value variables have and what is available in that scope. You can then follow the script step by step to the end of execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard breakpoints
&lt;/h3&gt;

&lt;p&gt;To do so, open your developer tools and navigate to “Sources”. Locate the JavaScript file that includes the line of code you want to stop at. In this case, you are looking for &lt;code&gt;top/js-cl89rs.stackblitz.io/~/index.js&lt;/code&gt;. Alternatively, you can click on &lt;code&gt;index.js:69&lt;/code&gt; in the console next to the “Let’s debug!” output for quicker access.&lt;/p&gt;

&lt;p&gt;To add a breakpoint simply click on the line number. It will be highlighted in blue and the line of code will show up in the breakpoints section on the right. There you can also deactivate it. Remove breakpoints either by clicking their highlighted line number or via the context menu in the breakpoints section to the right.&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%2Fhfc8peb44i1ulh44eoh6.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%2Fhfc8peb44i1ulh44eoh6.JPG" alt="Image description" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now add a breakpoint on line 53, the first check within the &lt;code&gt;validateNewTodo&lt;/code&gt; function. If you now add a new to-do, the execution will stop when it reaches the breakpoint. You can then hover over the variable, use the console and access everything available within the scope you’re currently at. You can also see available functions and variables in the “Scope” section on the righthand side.&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%2Fxrr19xgj03i2bctg3a3k.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%2Fxrr19xgj03i2bctg3a3k.JPG" alt="Image description" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To simply continue execution use the button “Resume script execution” (resume) on the right or on top of the rendered app.&lt;br&gt;
If you want to follow the execution step by step, use “Step over next function call” (step over). Stepping over will not follow the execution into functions but will let you check a value before and after it’s executed.&lt;br&gt;
If you want to follow it into function calls, use “Step into next function call” (step into) instead. If you step into the filter function on line 56, you will see each value being checked. Now, if you don’t want to keep following the execution for each to-do, you can use “Step out of current function” (step out) to skip the rest of the execution of the filter method and continue to the next line.&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%2Fws8eoem33y5col1wxqlv.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%2Fws8eoem33y5col1wxqlv.jpg" alt="Image description" width="583" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conditional breakpoints
&lt;/h3&gt;

&lt;p&gt;Breakpoints are great, but what happens if we want to check only a specific type of item, one of - let’s say - one thousand? You’re probably thinking, “Well, I just add an if with a &lt;code&gt;console.log&lt;/code&gt;”. That’s one way to do it, but you could also use Conditional Breakpoints. These breakpoints will only stop the execution of the script if a logical check resolves to true.&lt;/p&gt;

&lt;p&gt;Right-click your breakpoint on line 53 and select “Edit breakpoint…”. If you already removed the breakpoint, right-click on the line number and select “Add conditional breakpoint…”. Fill in your condition, for example, &lt;code&gt;val == 'stop'&lt;/code&gt;.Now the script will only halt if the value you want to add is “stop”.&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%2Fmyfrv53jgx0n2gio4daw.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%2Fmyfrv53jgx0n2gio4daw.JPG" alt="Image description" width="772" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Logpoints
&lt;/h3&gt;

&lt;p&gt;If you only need a simple log, you can also add a logpoint instead of modifying the code of the application. Edit your breakpoint again and choose “Logpoint” from the dropdown and add what you want to log to the input.&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%2F2qnl2nibgjl5ciybra0x.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%2F2qnl2nibgjl5ciybra0x.JPG" alt="Image description" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch
&lt;/h2&gt;

&lt;p&gt;If you want to keep track of a specific variable, especially when it is in global scope, it might be hard to keep track of it within the Scope section; maybe a property of &lt;code&gt;window&lt;/code&gt;. In this case, you can use the “Watch” section.&lt;/p&gt;

&lt;p&gt;The app keeps track of how many to-dos you have in your list and stores it in &lt;code&gt;window.todoCount&lt;/code&gt;. To keep an eye on what happens to the list, hit the plus in the header of the “Watch”-section and enter “window.todoCount”. You now see the current amount of to-dos in your list.&lt;/p&gt;

&lt;p&gt;Remove or disable all your breakpoints. Now add or remove one or more to-dos. The watched variable will not update automatically, but you can reload it with the “refresh” icon next to the plus. If you re-enable or add a breakpoint at line 60 and then step over the &lt;code&gt;addTodo&lt;/code&gt; function call, you can see that the watch now updates automatically.&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%2F2yqtbxzk7did1m3kswrs.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%2F2yqtbxzk7did1m3kswrs.JPG" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Call Stack
&lt;/h2&gt;

&lt;p&gt;Many functions are called by a lot of different other functions. Sometimes it’s tricky to figure out where a specific call came from. To check that we can look at the Call Stack.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;renderTodos&lt;/code&gt; method is called from four different places within the app. Let’s find out which ones by using the Call Stack.&lt;/p&gt;

&lt;p&gt;Add a breakpoint at the top of the &lt;code&gt;renderTodos&lt;/code&gt; function in line 14 and then reload the page. On the right in the “Call Stack” section you can see that you currently are at renderTodos in index.js:14, indicated by the arrow to the left of the line. If you now click on the line below you jump to the anonymous function that called it. If you go further down the Call Stack you can look at the inner workings of stackblitz. Resume the script.&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%2Fram5g5ki2jwhjdgq3ex1.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%2Fram5g5ki2jwhjdgq3ex1.JPG" alt="Image description" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One down, only three to go. Now add a new to-do to your list. Notice, this time the Call Stack is a lot smaller. We can see that the function was called by &lt;code&gt;addTodo&lt;/code&gt; which was called by &lt;code&gt;validateNewTodo&lt;/code&gt;. Look at the Call Stack when deleting an entry and when toggling the done status.&lt;/p&gt;

&lt;h2&gt;
  
  
  Console methods
&lt;/h2&gt;

&lt;p&gt;Besides log, there are many other useful methods that you can use to output information. Feel free to fork the app and add the different outputs as we work through the methods.&lt;/p&gt;

&lt;p&gt;Fork the &lt;a href="https://stackblitz.com/edit/js-cl89rs?file=index.html,index.js" rel="noopener noreferrer"&gt;demo app on stackblitz&lt;/a&gt;. Since stackblitz doesn’t forward the output of all methods to the integrated console, open the app in a separate tab (“Open in New Window - live” button at the top right).&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%2F4dmm0ncwrjrcyucn6rmu.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%2F4dmm0ncwrjrcyucn6rmu.JPG" alt="Image description" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .info vs .log
&lt;/h3&gt;

&lt;p&gt;As an alternative to log, there is the info method. Some browsers, like Chrome, treat both the exact same way. They consider them at the same level and render them in the same style. Other browsers, like Firefox, differentiate between the two. In Firefox, you can toggle their visibility separately and info output comes with a little information icon.&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%2Fu32acc6rrwj4ywqzumks.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%2Fu32acc6rrwj4ywqzumks.JPG" alt="Image description" width="800" height="149"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why bother? Most devs will configure their linter to not accept console.log, if you want to log (relevant) information you can still use the info method. This way, you will always know log-outputs are dev only, info-output can stay.&lt;/p&gt;

&lt;h3&gt;
  
  
  .warn &amp;amp; .error
&lt;/h3&gt;

&lt;p&gt;As indicated by their names, these are to output warnings and errors. They each have a separate logging level that you can show or hide in the console.&lt;/p&gt;

&lt;p&gt;Let’s include them in our application. Let’s output a warning before a to-do is deleted by adding &lt;code&gt;console.warn(‘Deleting todo’, todos[i].text);&lt;/code&gt; at line 32. Within the &lt;code&gt;validateNewTodo&lt;/code&gt; function let’s output errors in both cases the validation fails.&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%2Fe0rhj1fxxnre692zwjyk.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%2Fe0rhj1fxxnre692zwjyk.JPG" alt="Image description" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .table
&lt;/h3&gt;

&lt;p&gt;When logging arrays of objects, it can be daunting to check a specific property on multiple entries. To easily compare these, you can use the table method. Try it out for yourself by adding &lt;code&gt;console.table(todos);&lt;/code&gt; to the &lt;code&gt;addTodo&lt;/code&gt; function.&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%2Fgw1s6ait66s8m2eq7x2h.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%2Fgw1s6ait66s8m2eq7x2h.JPG" alt="Image description" width="469" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .assert
&lt;/h3&gt;

&lt;p&gt;We’ve learned about conditional breakpoints, but how about conditional logs without an if? You can use the assert method and pass a condition as the first and the message to log as a second argument. The assert will output an error when the condition renders false.&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%2F8nvescgdoixima5zk910.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%2F8nvescgdoixima5zk910.JPG" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .time &amp;amp; .timeEnd
&lt;/h3&gt;

&lt;p&gt;Another useful thing you can do directly with console methods is checking how long the execution of functions takes. To do that, add &lt;code&gt;console.time(‘new-todo’);&lt;/code&gt; at the beginning of the &lt;code&gt;validateNewTodo&lt;/code&gt; function. The string we pass is the label of the timer. Now add &lt;code&gt;console.timeEnd(‘new-todo’);&lt;/code&gt; before both returns and at the end of the function to ensure the timer is stopped even if the validation fails.&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%2Fcl64lpghq20s6lfjv6il.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%2Fcl64lpghq20s6lfjv6il.JPG" alt="Image description" width="634" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .count &amp;amp; .countReset
&lt;/h3&gt;

&lt;p&gt;You can use the count method to track how often the script runs a certain part of the logic. In the demo application, the function &lt;code&gt;renderTodos&lt;/code&gt; is called multiple times. Add &lt;code&gt;console.count(‘render-todos’);&lt;/code&gt; at the top of the function. The string we pass acts as the label of the counter. If you now reload the app and add, toggle and remove to-dos, you’ll see an output with the label and the number of times the line has been run. You can reset the counter by calling &lt;code&gt;console.countReset(‘render-todos’);&lt;/code&gt;.&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%2Fcjk0rtzgujkg4oy0odjw.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%2Fcjk0rtzgujkg4oy0odjw.JPG" alt="Image description" width="514" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .trace
&lt;/h3&gt;

&lt;p&gt;You can also easily output the Call Stack to the console by calling the trace function.&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%2Ff0aos3m4k9rmeexu4ssw.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%2Ff0aos3m4k9rmeexu4ssw.JPG" alt="Image description" width="512" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .group &amp;amp; .groupEnd
&lt;/h3&gt;

&lt;p&gt;By this point, the console gets full quickly. To keep a better overview, you can group the output. To do that, simply add &lt;code&gt;console.group(‘add-todo’);&lt;/code&gt; at the beginning and &lt;code&gt;console.groupEnd(‘add-todo’);&lt;/code&gt; at the end of the &lt;code&gt;addTodo&lt;/code&gt; function. The string is the label of the group that will be shown at the top, where you can toggle it open or closed.&lt;/p&gt;

&lt;p&gt;Add another group to the &lt;code&gt;renderTodos&lt;/code&gt; function. Since the &lt;code&gt;addTodo&lt;/code&gt; function calls &lt;code&gt;renderTodos&lt;/code&gt;, the groups are nested.&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%2Fe1we4jd5dgyk05csae2o.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%2Fe1we4jd5dgyk05csae2o.JPG" alt="Image description" width="511" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out even more methods in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/console" rel="noopener noreferrer"&gt;mdn web docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging with redirects
&lt;/h2&gt;

&lt;p&gt;Debugging an application that redirects can be tricky, but there are a couple of things that can help us.&lt;/p&gt;

&lt;p&gt;First remove the disabled attribute on the button in the index.html file. If you now click the button below the to-do list, it will redirect you to another stackblitz project that logs something and redirects to google. However, feel free to redirect to another page directly.&lt;/p&gt;

&lt;p&gt;If you know where the redirection happens, you can add a breakpoint at the trigger. Now you can use the Call Stack to check what happens up to this point within the application. However, if you try to step into or over the replace call, you’ll notice that the script will not pause on the new page. If this page also redirects, it can be especially hard to check what exactly happens. In this case, watching the &lt;code&gt;window.location&lt;/code&gt; can be useful, but it will also update once the script resumes.&lt;/p&gt;

&lt;p&gt;You can preserve the console output and the network. The log will at least list all URLs you’ve been redirected to and the network tab will show you which resources have been loaded, including scripts that caused further navigation.&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%2Fd6y2p938am8qsfj2t65l.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%2Fd6y2p938am8qsfj2t65l.JPG" alt="Image description" width="771" height="939"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;What you should take away:&lt;/p&gt;

&lt;p&gt;Next time you need to debug something and find yourself constantly going back to log various variables, think of this article. Likely, one or more of the things you’ve learned working your way through it will speed up the process. Good luck and happy debugging!&lt;/p&gt;




&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Cache-Control header &amp; Cache-Busting</title>
      <dc:creator>Cornelia</dc:creator>
      <pubDate>Sun, 10 Jul 2022 02:06:09 +0000</pubDate>
      <link>https://dev.to/soliloquizin/cache-control-header-cache-busting-dh0</link>
      <guid>https://dev.to/soliloquizin/cache-control-header-cache-busting-dh0</guid>
      <description>&lt;p&gt;A while ago, I found a bug in one of my company’s earliest PWAs; some users’ devices did not fully receive the latest update. Investigating this issue led me down the rabbit hole of cache-busting and caching strategies.&lt;br&gt;
This article focuses on the Cache-Control Header and possible cache-busting strategies. I might publish a second part, that will focus on caching with service workers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cache-Control Header
&lt;/h2&gt;

&lt;p&gt;The Cache-Control header provides the ability to manage the cache per asset. It can have one or multiple directives.&lt;/p&gt;
&lt;h3&gt;
  
  
  public
&lt;/h3&gt;

&lt;p&gt;This directive allows any cache to store the resource (incl. browser caches and CDNs). Resources that do not include user-specific data could be cached using this directive.&lt;br&gt;
If a resource specifies other directives, but neither &lt;code&gt;public&lt;/code&gt; nor &lt;code&gt;private&lt;/code&gt;, &lt;code&gt;public&lt;/code&gt; is set implicitly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  private
&lt;/h3&gt;

&lt;p&gt;This directive indicates that only a browser can cache the resource. &lt;code&gt;private&lt;/code&gt; is useful for responses that are unique to each user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: private
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  no-store
&lt;/h3&gt;

&lt;p&gt;If this directive is set, no cache will store the resource. Use this directive for resources that include sensitive or time-critical information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: no-store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  no-cache
&lt;/h3&gt;

&lt;p&gt;Caches will always re-validate resources that have this directive.&lt;br&gt;
The cache will ask the server for a newer version. If it has one, it replies with a 200 and the new file to download and use. If the cached version is the latest one, it responds with 304. The cache then serves the asset it already has.&lt;br&gt;
Since &lt;code&gt;no-cache&lt;/code&gt; will always trigger a re-validation, it cannot be combined with the &lt;code&gt;max-age&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: no-cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  max-age
&lt;/h3&gt;

&lt;p&gt;This directive sets a time (in seconds) within the asset is safe to use. After that time has passed, the file will be considered stale. Stale files will be re-validated the next time the client requests the file and restarts the &lt;code&gt;max-age&lt;/code&gt;. Note that caches might eject stale files. In that case the client will need to download the resource again.&lt;br&gt;
If the user explicitly refreshes the page, the browser will re-validate the resource even though the &lt;code&gt;max-age&lt;/code&gt; hasn’t passed yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: max-age=60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  s-maxage
&lt;/h3&gt;

&lt;p&gt;This directive overwrites the &lt;code&gt;max-age&lt;/code&gt; directive for shared caches (like proxy servers or CDNs).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: max-age=86400, s-maxage=3600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  must-revalidate
&lt;/h3&gt;

&lt;p&gt;Use this directive in combination with &lt;code&gt;max-age&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;must-revalidate&lt;/code&gt; prevents caches from ejecting the resource.&lt;br&gt;
Again, refreshing the page will cause re-validation even if the specified time hasn’t passed yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: must-revalidate, max-age=600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  proxy-revalidate
&lt;/h3&gt;

&lt;p&gt;This directive overwrites the must-revalidate directive for public caches.&lt;/p&gt;

&lt;h3&gt;
  
  
  stale-while-revalidate
&lt;/h3&gt;

&lt;p&gt;This directive allows caches to serve the stale file while re-validating the resource for a specified amount of time (in seconds).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: max-age=31536000, stale-while-revalidate=86400
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  stale-if-error
&lt;/h3&gt;

&lt;p&gt;If this directive is set, the cache will serve the stale resource for the specified amount of seconds if the server responds with a 5xx error upon re-validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: max-age=2419200, stale-if-error=86400
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  no-transform
&lt;/h3&gt;

&lt;p&gt;This directive prevents intermediaries from modifying responses. For example, a telco provider might optimise images by default. You most likely want to prevent that because it would likely cause a loss in quality. &lt;br&gt;
Since intermediaries are not allowed to modify responses on HTTPS connections, this directive will only affect HTTP connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: no-transform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  immutable
&lt;/h3&gt;

&lt;p&gt;This directive specifies the amount of time within the resource will not change. During that time, caches will not re-validate it, not even on manual page refreshes, nor download newer versions. So, ensure a good cache-busting (see below) strategy before using the &lt;code&gt;immutable&lt;/code&gt; directive!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache-Control: max-age=31536000, immutable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cache-busting
&lt;/h2&gt;

&lt;p&gt;Cache-busting strategies define how cached resources can be updated or replaced. These are some strategies that you can use:&lt;/p&gt;

&lt;h3&gt;
  
  
  Fingerprinting filenames
&lt;/h3&gt;

&lt;p&gt;A random hash is added to directories, per example: images-rzt87032ztr. This is usually easier to set up but could cause a lot of unnecessary traffic. Caches will need to download all resources within the folder, even though only a couple might have changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query String
&lt;/h3&gt;

&lt;p&gt;A specific version is requested via parameter, per example: style.css?v=1.0.0. This provides cache-busting per individual file but might still be an insufficient solution since many proxy servers and CDNs omit query strings while serving from the cache. Therefore these caches cannot be busted using this strategy.&lt;/p&gt;

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

&lt;p&gt;What you should take away:&lt;br&gt;
Work out a cache-busting strategy first, then define a caching strategy.&lt;/p&gt;




&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>Calculations with booleans</title>
      <dc:creator>Cornelia</dc:creator>
      <pubDate>Wed, 18 Aug 2021 21:00:15 +0000</pubDate>
      <link>https://dev.to/soliloquizin/calculations-with-booleans-1i1p</link>
      <guid>https://dev.to/soliloquizin/calculations-with-booleans-1i1p</guid>
      <description>&lt;p&gt;Sometimes I like to take a look at the quirkiness of the language I code in and compare it to other languages. This time, I thought I'd share my findings with you, in case you also find them entertaining and interesting. On this occasion I looked at a quirk featured in &lt;a href="https://github.com/denysdovhan/wtfjs#math-with-true-and-false" rel="noopener noreferrer"&gt;WTFJS&lt;/a&gt;, namely doing Math with booleans. Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  true + true = ?
&lt;/h2&gt;

&lt;p&gt;In Javascript, we use the + operator to concatenate strings as well as to add up numbers, but what happens when we through some booleans into the mix? Let's try!&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&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;// output: "Hitrue"&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// output: "trueHi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so far, so good, Javascript notices that we use a string with a + operator and treats the boolean like a String and concatenates the two. Now, let's take a look at the numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&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;// output: 6&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// output: 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait, what? Let's take a closer look at what's happening here.&lt;/p&gt;

&lt;h3&gt;
  
  
  the Number-function
&lt;/h3&gt;

&lt;p&gt;The boolean value is passed to the &lt;code&gt;Number&lt;/code&gt;-function, which converts it to a Number; &lt;code&gt;true&lt;/code&gt; is converted to 1 and &lt;code&gt;false&lt;/code&gt; to 0.&lt;/p&gt;




&lt;h4&gt;
  
  
  Note
&lt;/h4&gt;

&lt;p&gt;The Javascript Number type has limits to what it can store and also limits on how high the numbers stored in can be. All Numbers are stored as floating-point values.&lt;/p&gt;




&lt;p&gt;If it fails to convert the value into a number, it will return NaN. It can convert true, false, null, as well as a decimal and hexadecimal number (in strings).&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="nc"&gt;Number&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;// output: 1&lt;/span&gt;
&lt;span class="nc"&gt;Number&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="c1"&gt;// output: 0&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// output: 0&lt;/span&gt;
&lt;span class="nc"&gt;Number&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="c1"&gt;// output: NaN&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x7E5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// output: 2021&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0x7E5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// output: 2021&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12.5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// output: 12.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  calculation with booleans only
&lt;/h3&gt;

&lt;p&gt;When we only add boolean operands, Javascript will still try and convert them into Numbers, rather than interpreting both as being strings.&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="kc"&gt;true&lt;/span&gt; &lt;span class="o"&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;// output: 2&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// output: 1&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// output: 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Beyond the addition
&lt;/h2&gt;

&lt;p&gt;The same effect, of course, happens with subtractions, multiplications and divisions, as well as when using unary operators (positive and negative - although NaN will not be signed).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;       &lt;span class="c1"&gt;// output: 1&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;      &lt;span class="c1"&gt;// output: 0&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;       &lt;span class="c1"&gt;// output: 0&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;  &lt;span class="c1"&gt;// output: NaN&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x75E&lt;/span&gt;      &lt;span class="c1"&gt;// output: 2021&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0x75E&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;    &lt;span class="c1"&gt;// output: 2021&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12.5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;     &lt;span class="c1"&gt;// output: 12.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Is it just JS
&lt;/h2&gt;

&lt;p&gt;You might know all of this already, so let's compare it to a few other languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP&lt;/strong&gt; and &lt;strong&gt;Python&lt;/strong&gt; will also allow calculations with booleans. They both also convert &lt;code&gt;true&lt;/code&gt; to 1 and &lt;code&gt;false&lt;/code&gt; to 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt; and &lt;strong&gt;Rust&lt;/strong&gt; on the other hand, will both refuse calculations with boolean values and throw an error during compilation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;error: bad operand types for binary operator '+'&lt;br&gt;
&lt;em&gt;Java&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;error [E0277]: cannot add &lt;code&gt;bool&lt;/code&gt; to &lt;code&gt;{integer}&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Rust&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I hope you had fun reading about calculations with booleans. Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>quirks</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
