<?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: Latz</title>
    <description>The latest articles on DEV Community by Latz (@latz).</description>
    <link>https://dev.to/latz</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%2F183069%2Faf46e611-5f59-4440-a674-a11682aa49ff.jpeg</url>
      <title>DEV Community: Latz</title>
      <link>https://dev.to/latz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/latz"/>
    <language>en</language>
    <item>
      <title>NodeJS: async.queue does not display error messages by default</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Wed, 26 Feb 2025 14:27:01 +0000</pubDate>
      <link>https://dev.to/latz/nodejs-asyncqueue-does-not-display-error-messages-by-default-2lib</link>
      <guid>https://dev.to/latz/nodejs-asyncqueue-does-not-display-error-messages-by-default-2lib</guid>
      <description>&lt;p&gt;Currently, I’m creating a custom web crawler and the easiest method to implement concurrency is to use the npm package “async“.&lt;/p&gt;

&lt;p&gt;While coding, I came across the problem, that the program wasn’t working correctly, but the terminal didn’t display any errors.&lt;/p&gt;

&lt;p&gt;So I tested the queued function outside of async, and it threw an error as expected. What was happening here?&lt;/p&gt;

&lt;p&gt;It turned out that async.queue is catching errors by default and that you have to handle them explicitly. This can be done by adding an error callback to the queue:&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;var&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;();&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="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;task&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;task experienced an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently, this not very helpful but of course you can display the error easily:&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;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;task&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Async error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There we have it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Async error: ReferenceError: xxx is not defined&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>node</category>
    </item>
    <item>
      <title>JavaScript – Rounding floating point numbers</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Wed, 22 May 2024 18:10:48 +0000</pubDate>
      <link>https://dev.to/latz/javascript-rounding-floating-point-numbers-3a9c</link>
      <guid>https://dev.to/latz/javascript-rounding-floating-point-numbers-3a9c</guid>
      <description>&lt;p&gt;There are six different functions in JavaScript’s Math library for rounding floating point numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;abs()&lt;/li&gt;
&lt;li&gt;ceil()&lt;/li&gt;
&lt;li&gt;floor()&lt;/li&gt;
&lt;li&gt;round()&lt;/li&gt;
&lt;li&gt;trunc()&lt;/li&gt;
&lt;li&gt;fround()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the difference between these functions?&lt;/p&gt;

&lt;h3&gt;
  
  
  abs()
&lt;/h3&gt;

&lt;p&gt;abs() is the absolute value of a number. Mathematically speaking, it is the distance of a number from zero. As a distance cannot be negative, the absolute value is always the positive value of a number:&lt;/p&gt;

&lt;p&gt;Math.abs(7.89012) = 7.89012&lt;br&gt;
Math.abs(-7.89012) = 7.89012&lt;/p&gt;

&lt;h3&gt;
  
  
  ceil()
&lt;/h3&gt;

&lt;p&gt;ceil() rounds up a number to the nearest integer value greater than or equal to the given number:&lt;/p&gt;

&lt;p&gt;Math.ceil(7.1) = 8&lt;br&gt;
Math.ceil(7.8) = 8&lt;br&gt;
Math.ceil(-7.1) = -7&lt;br&gt;
Math.ceil(-7.8) = -7&lt;/p&gt;

&lt;p&gt;Please note that the next largest integer from -7.1 is not -8, but -7.&lt;/p&gt;

&lt;h3&gt;
  
  
  floor()
&lt;/h3&gt;

&lt;p&gt;floor() is the counterpart to ceil(), so it rounds the given number to the next smaller or equal number to the given number:&lt;/p&gt;

&lt;p&gt;Math.floor(7.1) = 7&lt;br&gt;
Math.floor(7.8) = 7&lt;br&gt;
Math.floor(-7.1) = -8&lt;br&gt;
Math.floor(-7.8) = -8&lt;/p&gt;

&lt;h3&gt;
  
  
  round()
&lt;/h3&gt;

&lt;p&gt;round() rounds the given number to the nearest whole number:&lt;/p&gt;

&lt;p&gt;Math.round(7.1) = 7&lt;br&gt;
Math.round(7.8) = 8&lt;br&gt;
Math.round(-7.1) = -7&lt;br&gt;
Math.round(-7.8) = -8&lt;/p&gt;

&lt;p&gt;The function works mathematically correctly:&lt;/p&gt;

&lt;p&gt;math.round(7.49) = 7&lt;br&gt;
math.round(7.5) = 8&lt;/p&gt;

&lt;h3&gt;
  
  
  trunc()
&lt;/h3&gt;

&lt;p&gt;Math.trunc(7.1) = 7&lt;br&gt;
Math.trunc(7.8) = 7&lt;br&gt;
Math.trunc(-7.1) = -7&lt;br&gt;
Math.trunc(-7.8) = -7&lt;/p&gt;

&lt;p&gt;fround()&lt;br&gt;
This function is only required in special situations where you have to work with 32-bit numbers, e.g. in graphics or audio programming. It enables more precise rounding than the more general round().&lt;br&gt;
Here is a more detailed explanation than is useful in this article.&lt;/p&gt;

&lt;p&gt;(Foto von &lt;a href="https://unsplash.com/de/@kommumikation?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Mika Baumeister&lt;/a&gt; auf &lt;a href="https://unsplash.com/de/fotos/weisses-druckpapier-mit-zahlen-Wpnoqo2plFA?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;)&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to loop through an array with a variable starting element</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Tue, 17 Oct 2023 11:21:41 +0000</pubDate>
      <link>https://dev.to/latz/how-to-loop-through-an-array-with-a-variable-starting-element-3cdm</link>
      <guid>https://dev.to/latz/how-to-loop-through-an-array-with-a-variable-starting-element-3cdm</guid>
      <description>&lt;p&gt;Recently I was faced with an interesting problem. I needed to create a simplified (pseudo-) cron interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wKy_LZh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2t5bblwmbf43toh6twyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wKy_LZh_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2t5bblwmbf43toh6twyh.png" alt="Image description" width="659" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The task is to find the next selected day.&lt;/p&gt;

&lt;p&gt;My first attempt was a naive one. Loop to the end of the array and if nothing was found, start a second loop at the beginning and move to the current day (pseudocode, no error detection, performance optimization or edge casing):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Array&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="kc"&gt;true&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="kc"&gt;true&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="kc"&gt;false&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="nv"&gt;$today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="c1"&gt;// Thursday&lt;/span&gt;
&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;today&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="c1"&gt;// loop index starts at the next day (Friday)&lt;/span&gt;
&lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&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="c1"&gt;// loop abort variable&lt;/span&gt;
&lt;span class="c1"&gt;// iterate to the end of the array&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$today&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&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="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// day checkbox is selected&lt;/span&gt;
      &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&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="c1"&gt;// no truthy element was found&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&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="c1"&gt;// start at the beginninf of the array&lt;/span&gt;
    &lt;span class="c1"&gt;// iterate from the start to the current day&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$today&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&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="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// day checkbox is selected&lt;/span&gt;
          &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&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="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 (Monday)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem can be abstracted: Printing all the indices of an array in sequence, using a variable starting point. In the example above: &lt;code&gt;5, 6, 0, 1, 2, 3, 4&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Array&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="kc"&gt;true&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="kc"&gt;false&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="kc"&gt;false&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="nv"&gt;$max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$start&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="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    
   &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 5, 6&lt;/span&gt;
   &lt;span class="nv"&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="nv"&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="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 0, 1, 2, 3, 4&lt;/span&gt;
    &lt;span class="nv"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look at the output, you’ll notice that the numbers are all integers and less than or equal to &lt;code&gt;max&lt;/code&gt;.&lt;br&gt;
There’s a special, lesser-known operator that comes in handy in this case: &lt;a href="https://en.wikipedia.org/wiki/Modular_arithmetic"&gt;modulo&lt;/a&gt;. In a nutshell, modulo returns the integer remainder of a division, e.g:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 mod 5 → 1 (0 remaining 1)&lt;/li&gt;
&lt;li&gt;2 mod 5 → 2 (0 remaining 2)&lt;/li&gt;
&lt;li&gt;3 mod 5 → 3 (0 remaining 3)&lt;/li&gt;
&lt;li&gt;4 mod 5 → 4 (0 remaining 4)&lt;/li&gt;
&lt;li&gt;5 mod 5 → 0 (1 remaining 0)&lt;/li&gt;
&lt;li&gt;6 mod 5 → 1 (1 remaining 1)&lt;/li&gt;
&lt;li&gt;7 mod 5 → 2 (1 remaining 2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will notice two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the result is always less than or equal to the dividend (&lt;code&gt;5&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;the result is repeated after the dividend (&lt;code&gt;1, 2, 3, 4, 5, 6, 7&lt;/code&gt;) exceeds the value of the divisor (&lt;code&gt;5&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s exactly what we need. Let’s put something like this, with different numbers, into code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4, 5, 6, 7, 8, 9, 10&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4, 5, 6, 0, 1, 2, 3&lt;/span&gt;
    &lt;span class="nv"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index &lt;code&gt;i&lt;/code&gt; exceeds the length of the array, but we’re using &lt;code&gt;i mod max&lt;/code&gt; and not the loop index itself. The result makes a round trip after reaching max and starts again at &lt;code&gt;0&lt;/code&gt;. All indexes of the array are covered, starting from the middle index &lt;code&gt;4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The actual code now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Array&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="kc"&gt;true&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="kc"&gt;true&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="kc"&gt;false&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="nv"&gt;$today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="c1"&gt;// THursday&lt;/span&gt;

&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$today&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="nv"&gt;$max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$today&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt;&lt;span class="p"&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="nv"&gt;$max&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1 (Monday)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code may not look as readable as before, so why are we doing this?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because we can!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And it’s fun to come up with a clever solution to a problem. We’re programmers, after all.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The modern way of checking radio groups</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Fri, 06 Oct 2023 21:34:32 +0000</pubDate>
      <link>https://dev.to/latz/the-modern-way-of-checking-radio-groups-9j9</link>
      <guid>https://dev.to/latz/the-modern-way-of-checking-radio-groups-9j9</guid>
      <description>&lt;p&gt;Checking radio groups in JavaScript has always been a bit tricky because you can only check if a particular radio button is selected, not the whole group at once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fruits"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"banana"&lt;/span&gt; &lt;span class="na"&gt;checked=&lt;/span&gt;&lt;span class="s"&gt;"checked"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;Banana
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fruits"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;Apple
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fruits"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cherry"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;Cherry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, that looks archaic. There must be a better way using the new ES6 features, and there is! As of ES2015, &lt;code&gt;NodeList&lt;/code&gt; contains a &lt;code&gt;forEach&lt;/code&gt; method(). This makes things much easier:&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;var&lt;/span&gt; &lt;span class="nx"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fruits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selectedFruit&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="nx"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;selectedFruit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still a lot of lines. We can make the code much tighter, but also much more unreadable:&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="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fruits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selectedFruit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checked&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires a bit of explanation, because in order to achieve it we have to dig deep into our bag of tricks.&lt;/p&gt;

&lt;p&gt;First we convert the &lt;code&gt;NodeList&lt;/code&gt; to an array using the spread operator to have all the funky &lt;code&gt;Array()&lt;/code&gt; methods available.&lt;br&gt;
The &lt;code&gt;Array()&lt;/code&gt; method we use is &lt;code&gt;some()&lt;/code&gt;. This method loops over an array until the callback function returns true. In our case we exit the loop by checking for “&lt;code&gt;fruit.checked&lt;/code&gt;” which is true if the radio button is checked.&lt;/p&gt;

&lt;p&gt;The second trick is to include the assignment of the loop variable fruit to the upper scope variable &lt;code&gt;selectedFruit&lt;/code&gt;. This assignment always returns true, and therefore does not affect the result of the whole statement when it’s linked with &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator to the other comparison.&lt;/p&gt;

&lt;p&gt;BTW, we don’t need to declare an upper scope variable any more here because we don’t enter a new scope in the callback function. New scopes require curly braces which we don’t need here because the callback function only contains a single statement.&lt;br&gt;
You can be picky and point our that &lt;code&gt;selectedFruit&lt;/code&gt; is undeclared, but the code works nevertheless. So what?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
We reduced the code from six lines to three and from 193 to 115 characters. Not bad and your code will look much cooler on GitHub!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
    </item>
    <item>
      <title>Chrome side panel: Simulate close event</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Thu, 14 Sep 2023 13:30:18 +0000</pubDate>
      <link>https://dev.to/latz/chrome-side-panel-simulate-close-event-354h</link>
      <guid>https://dev.to/latz/chrome-side-panel-simulate-close-event-354h</guid>
      <description>&lt;p&gt;The new side panel in Chrome does not contain a close event, which could come handy if you want to clean up stuff after the panel has been closed. &lt;/p&gt;

&lt;p&gt;You can simulate the event by opening a permanent connection between the side panel and the background script. This connection fires an &lt;code&gt;onDisconnect&lt;/code&gt; event if the side panel gets closed. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;sidepanel.js&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="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mySidepanel&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;The background script can add a listener and react accordingly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;background.js:&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="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mySidepanel&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;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onDisconnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sidepanel closed.&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="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;Note that switching between panels is not sufficient, the event will only fire if the side panel is fully closed.&lt;/p&gt;

</description>
      <category>chrome</category>
      <category>extension</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Chrome extensions, Manifest v3 and local storage views</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Thu, 09 Mar 2023 15:05:21 +0000</pubDate>
      <link>https://dev.to/latz/chrome-extensions-manifest-v3-and-local-storage-views-362j</link>
      <guid>https://dev.to/latz/chrome-extensions-manifest-v3-and-local-storage-views-362j</guid>
      <description>&lt;p&gt;The other day I started coding a Chrome extension that makes heavy use of Chrome's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB"&gt;IndexedDB&lt;/a&gt;. Until this time then I had no problem inpecting any local storage using the DevTool's "Application" tab. Those were extensions that used Manifest v2 but as of June 2023 Google will only acept Manifest v3 extensions. &lt;br&gt;
One of the main changes is that background pages are replaced with service workers. So I changed my code accordingly from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"background": {
    "page": "background/background.html"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"background": {
    "service_worker": "background.js",
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and coded happily on. When I reached the local storage part and wanted to check the local storage by clicking on the new "service worker" link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V_Z-vo88--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhcz9k7un864flhvocyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V_Z-vo88--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhcz9k7un864flhvocyu.png" alt="Image description" width="546" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surprisingly the IndexedDB pane in the "Application" tab was empty though I definitely knew that there was data stored:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--csTy8IP6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80re4ycle2bqkdz88hen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--csTy8IP6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80re4ycle2bqkdz88hen.png" alt="Image description" width="533" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;o what was happening? After a long search on the Internets I came across &lt;a href="https://stackoverflow.com/a/32471596/259184"&gt;an answer on StackOverflow&lt;/a&gt; that saved my day.&lt;/p&gt;

&lt;p&gt;If your extension contains a popup  you can right click and select "Inspect" to open the correct DevTools window:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MNDw7WHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j25kev7syixiityq2cn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MNDw7WHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j25kev7syixiityq2cn8.png" alt="Image description" width="235" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there you go:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CrCM_EJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2yn77z41ms3ub1dt531.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CrCM_EJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2yn77z41ms3ub1dt531.png" alt="Image description" width="730" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what do you do if your extension does not containa popup? There is a solution though it's a bit more complicated.&lt;br&gt;
Open the extension page and look for the extension's ID:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p9ondX3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkd4bv7egk3iwhtt1sy8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p9ondX3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkd4bv7egk3iwhtt1sy8.png" alt="Image description" width="438" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy that ID and enter the following URL into the address bar, replacing "ID" with the actual ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chrome-extension://ID/manifest.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right click on the window and select "Inspect":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5NBcQ9AU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9o2acxsls5kttztzvngv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5NBcQ9AU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9o2acxsls5kttztzvngv.png" alt="Image description" width="539" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One last problem: In contrast to the "classical" DevTools popup this one disappears if you reload the extension. Fortunately you can bookmark the tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nJNEuMNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu0xwyxvhoa6aiukfu16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nJNEuMNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu0xwyxvhoa6aiukfu16.png" alt="Image description" width="282" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; You don't actullay need to insert the ID manually but you can click on any script in your default Devtools window (opened with "Inspect views service worker" link), right click on any script in the "Sources" pane, select "Open in new tab" and, just like above, right click the tab and select "Inspect":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lLgbSG81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qzhdjz0y1dw1sgelx7z0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lLgbSG81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qzhdjz0y1dw1sgelx7z0.png" alt="Image description" width="736" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only question that remains is: Why, Google, why has this be so complicated?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How-to split a number into equal chunks</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Wed, 17 Aug 2022 21:31:14 +0000</pubDate>
      <link>https://dev.to/latz/how-to-split-a-number-into-equal-chunks-4njc</link>
      <guid>https://dev.to/latz/how-to-split-a-number-into-equal-chunks-4njc</guid>
      <description>&lt;p&gt;The other day I had to iterate over a large number of items but to avoid a timeout I could only compute a certain amount at a time. So I had to split the number into equal chunks and a remainder. Here’s an easy way to determine the chunk size:&lt;br&gt;
&lt;code&gt;$totalNumber = 50321;&lt;br&gt;
$chunkSize = 1023;&lt;br&gt;
$remainder =  $totalNumber % $chunkSize;&lt;br&gt;
$chunks = ($totalNumber - $remainder) / $chunkSize;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The code return the following values:&lt;br&gt;
$remainder =&amp;gt; 194&lt;br&gt;
$chunks =&amp;gt; 49&lt;br&gt;
Verification: (49 * 1023) + 194 = 50321&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;br&gt;
In line 5 &lt;code&gt;$totalNumber&lt;/code&gt; is divided by a modulo operator (“%” is the PHP token for modulo). The operator returns the remainder of the division (194). By subtracting this value from $&lt;code&gt;totalNumber&lt;/code&gt; it becomes a whole number multiple of $chunks and the division with &lt;code&gt;$chunkSize&lt;/code&gt; equals the desired number of &lt;code&gt;$chunks&lt;/code&gt; (line 6).&lt;br&gt;
Now you have the number of necessary iterations and the remaining part.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Firefox Addon: Add options menu to browser action icon</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Thu, 20 May 2021 13:49:06 +0000</pubDate>
      <link>https://dev.to/latz/firefox-addon-add-options-menu-to-browser-action-icon-3ed5</link>
      <guid>https://dev.to/latz/firefox-addon-add-options-menu-to-browser-action-icon-3ed5</guid>
      <description>&lt;p&gt;Especially during development it’s annoying to reach the option page of a Firefox addon:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hamburger&lt;/li&gt;
&lt;li&gt;Addons and Themes&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;Options&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There should be a faster way. At least for your own Add-ons you can quite easily add an “Options” menu item to the browser action:&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;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contextMenus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Options&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contexts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;browser_action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openOptionsPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally to have to add a new permission to the manifest.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"contextMenus"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8IVRqMc0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggd5rpx8mvwj6ydw5fln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8IVRqMc0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggd5rpx8mvwj6ydw5fln.png" alt="menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That was easy!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Set selections in a multiple select element with ES6</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Mon, 01 Mar 2021 15:07:09 +0000</pubDate>
      <link>https://dev.to/latz/set-selections-in-a-multiple-select-element-with-es6-3dn</link>
      <guid>https://dev.to/latz/set-selections-in-a-multiple-select-element-with-es6-3dn</guid>
      <description>&lt;p&gt;If you're looking on the web for a solution to programmatically set the selections of a multiple select element in JavaScript you most likely find answers using jQuery, an indexed loop and an if condition, or some other complicated stuff. Modern browsers and ES6 gives you a simple solution in (almost) a single line of code:&lt;/p&gt;

&lt;h4&gt;
  
  
  HTML
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"selectElement"&lt;/span&gt; &lt;span class="na"&gt;size=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;multiple&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"oranges"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Oranges&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"apples"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Apples&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"cherries"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cherries&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  JavaScript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selectElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selectElement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;oranges&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;cherries&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;option&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;selectElement&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;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you go!&lt;br&gt;
(&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@amartino20?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Anthony Martino&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/choice?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Big Tech 0wns web development</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Mon, 11 Jan 2021 13:42:05 +0000</pubDate>
      <link>https://dev.to/latz/big-tech-0wns-web-development-4hkk</link>
      <guid>https://dev.to/latz/big-tech-0wns-web-development-4hkk</guid>
      <description>&lt;p&gt;Web development is based on free software by developers like you and me, isn’t it? At first glance, this seems to be the case. Let’s take a look at the main tools modern web is mainly developed with nowadays:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visual Studio Code&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;GitHub&lt;/li&gt;
&lt;li&gt;Chrome&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of the tools are Open Source projects (VS Code only in parts, npm is proprietary). So where are the big companies? Well, all six tools and sites are owned by Big Tech:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Microsoft&lt;/li&gt;
&lt;li&gt;Microsoft&lt;/li&gt;
&lt;li&gt;Facebook&lt;/li&gt;
&lt;li&gt;Microsoft&lt;/li&gt;
&lt;li&gt;Microsoft&lt;/li&gt;
&lt;li&gt;Google&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tools we use all day rise and fall with the benevolence of companies typically seen as enemies of Free Software by the majority of Open Source developers.&lt;/p&gt;

&lt;p&gt;Especially GitHub and npm are irreplaceable because of their large data collection. If Microsoft decides to pull the plug from one moment to the next, the access to the vast collection of free code will be gone at least for some time and the build processes of millions of programs will break.&lt;/p&gt;

&lt;p&gt;Of course, these services can and would be replaced by others, but it would take some time until dominant services will emerge and web developers would need to find an interim way of accessing their externalized source code.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>bigtech</category>
    </item>
    <item>
      <title>Javascript – Swap classes of an HTML element</title>
      <dc:creator>Latz</dc:creator>
      <pubDate>Thu, 01 Oct 2020 09:21:09 +0000</pubDate>
      <link>https://dev.to/latz/javascript-swap-classes-of-an-html-element-4772</link>
      <guid>https://dev.to/latz/javascript-swap-classes-of-an-html-element-4772</guid>
      <description>&lt;p&gt;Recently I came across the problem, that I had to programmatically change a div’s color from red to green. Sounds simple and it’s actually quite simple if you know your JavaScript.&lt;/p&gt;

&lt;p&gt;jQuery contains a function called “toggleClass()” that swaps class attributes in and out of an element. I looked for a similar function in ES6 but couldn’t find one. Florian Brinkmann (@FloBrinkmann) pointed me to “classList.toggle()” which does exactly the thing I’m looking for (it’s hidden in the “Examples” passage).&lt;/p&gt;

&lt;p&gt;Here’s the naive solution to my problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;toggleClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;element&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;element&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;
     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className2&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;myDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myDiv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="nx"&gt;toggleClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myDiv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&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;green&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;The jQuery implementation contains the ability to define more than two classes to add or remove from the element. Using a new ES6 element (the spread operator) this can be implemented like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;toggleClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;classNames&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="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;className&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;element&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;className&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="nx"&gt;toggleClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myDiv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;green&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="nx"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;jQuery's "toggleClass()" has some more functionality available but currently I don't have any need for it. For a start this is enough.&lt;/p&gt;

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