<?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: Ivan Spoljaric</title>
    <description>The latest articles on DEV Community by Ivan Spoljaric (@ispoljari).</description>
    <link>https://dev.to/ispoljari</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%2F59142%2Fc65c546f-ffae-4342-9fbc-4c75ec91aea7.png</url>
      <title>DEV Community: Ivan Spoljaric</title>
      <link>https://dev.to/ispoljari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ispoljari"/>
    <language>en</language>
    <item>
      <title>I tried to mount a client-side "attack" on a news website poll by using only Javascript. And I failed miserably.</title>
      <dc:creator>Ivan Spoljaric</dc:creator>
      <pubDate>Wed, 14 Jul 2021 00:18:10 +0000</pubDate>
      <link>https://dev.to/ispoljari/i-tried-to-mount-a-client-side-attack-on-a-news-website-poll-by-using-only-javascript-and-i-failed-miserably-1ebf</link>
      <guid>https://dev.to/ispoljari/i-tried-to-mount-a-client-side-attack-on-a-news-website-poll-by-using-only-javascript-and-i-failed-miserably-1ebf</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2Fofx1p297o3kb1prtxn9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fofx1p297o3kb1prtxn9k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First step - Running the script locally
&lt;/h2&gt;

&lt;p&gt;For academic purposes I tried to create a client-side script to manipulate the results of a random poll on a &lt;a href="https://www.index.hr/vijesti/clanak/velika-anketa-treba-li-cijepljenje-u-skolstvu-zdravstvu-i-socijali-biti-obavezno/2290306.aspx" rel="noopener noreferrer"&gt;Croatian news portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The poll is open at the moment writing, but it probably won't stay that way for long.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/js-ddpj1r?file=backup.js" rel="noopener noreferrer"&gt;Here's the code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code consists of these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;waiting for "DOMContentLoaded" event&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;closing the cookie banner&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;selecting a poll answer&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;MutationObserver indicates changes in the DOMTree target iframe. This means that the results are "in". Then the  localStorage is cleared.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;a timer, which started running immediately after "DOMContentLoaded", reloads the page after 2 seconds. And the script starts from the beginning&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works as intended if you run it directly in the dev tools console.&lt;/p&gt;

&lt;p&gt;You'll probably notice how the code is tightly coupled with the html/css implementation of the web page. &lt;/p&gt;

&lt;p&gt;Since I was creating a proof of concept I didn't bother to  write the functions in a generalised way. &lt;/p&gt;

&lt;p&gt;I used the exact CSS class names from the site, and targeted the poll iframe based on its position in the HTML. &lt;/p&gt;

&lt;p&gt;I had a pretty strong hunch that it won't work anyway (not that it stopped me from trying).&lt;/p&gt;

&lt;h2&gt;
  
  
  Second step - Automating the script
&lt;/h2&gt;

&lt;p&gt;The next step was to think of a way to run the script automatically, without the need to paste the code in the console every time. &lt;/p&gt;

&lt;p&gt;So, I created a custom &lt;a href="https://stackblitz.com/edit/js-uhxg5p?file=content-script.js" rel="noopener noreferrer"&gt;browser extension&lt;/a&gt;, which has only one additional manifest.json file.&lt;/p&gt;

&lt;p&gt;And that didn't work. &lt;/p&gt;

&lt;p&gt;Line 2 is the problem.&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iframe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;contentDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't work because of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" rel="noopener noreferrer"&gt;"Same Origin Policy"&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;It's a "critical security mechanism that restricts how a document or script loaded by one origin can interact with a resource from another origin".&lt;/p&gt;

&lt;p&gt;And this also applies to iframes.&lt;/p&gt;

&lt;p&gt;"External" iframe's can't be accessed, nor manipulated from a document which is not served on the same origin (domain). &lt;/p&gt;

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

&lt;p&gt;For completeness sake, I also tried to use the 3 most popular browser extensions that enable running custom scripts on any web page; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GreaseMonkey&lt;/li&gt;
&lt;li&gt;TamperMonkey&lt;/li&gt;
&lt;li&gt;ViolentMonkey.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tested out a few StackOverflow suggestions, related to the configuration of those extensions, in a foolish attempt to beat the system. &lt;/p&gt;

&lt;p&gt;But with no luck.&lt;/p&gt;

&lt;p&gt;You can't beat the system by breaking its hard rules. Unless you're the One. And it turns out I'm not. At least not yet. &lt;/p&gt;

&lt;h2&gt;
  
  
  A glimmer of hope
&lt;/h2&gt;

&lt;p&gt;Fortunately not all of my work was in vain. &lt;/p&gt;

&lt;p&gt;As I was slowly accepting my fate, and getting ready to completely give up, I stumbled on an alternative approach to this problem. &lt;/p&gt;

&lt;p&gt;There's a method called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" rel="noopener noreferrer"&gt;Window.postMessage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And its API looks kind of promising (with regard to CORS issues caused by external iframe communication).&lt;/p&gt;

&lt;p&gt;So the story continues. Stay tuned. :)&lt;/p&gt;

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

&lt;p&gt;Do you know any other way, or a hack, to bypass the Same Origin Policy? &lt;/p&gt;

&lt;p&gt;Is there another approach to the "external iframe" problem, which I didn't think of?&lt;/p&gt;

&lt;p&gt;Or is it just plain impossible to do this on the client (FE) side (which is a good thing I suppose, because it prevents malicious behaviour).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to create an Angular NavBar with a dynamic slider (and keep your sanity)</title>
      <dc:creator>Ivan Spoljaric</dc:creator>
      <pubDate>Sun, 11 Jul 2021 14:17:43 +0000</pubDate>
      <link>https://dev.to/ispoljari/one-must-imagine-people-who-work-with-angular-happy-or-how-to-create-a-navbar-with-a-dynamic-slider-and-keep-your-sanity-3la</link>
      <guid>https://dev.to/ispoljari/one-must-imagine-people-who-work-with-angular-happy-or-how-to-create-a-navbar-with-a-dynamic-slider-and-keep-your-sanity-3la</guid>
      <description>&lt;h1&gt;
  
  
  One must imagine Angular devs happy
&lt;/h1&gt;

&lt;p&gt;Some time ago I started working on a new project with Angular.&lt;/p&gt;

&lt;p&gt;I immediately noticed that the learning curve for Angular is a lot steeper than for React. And this is probably more true if you are an absolute beginner with zero to little FE experience. &lt;/p&gt;

&lt;h3&gt;
  
  
  - The React way of doing things
&lt;/h3&gt;

&lt;p&gt;For example, to start building with React, you can use the CRA (create-react-app) npm package to bootstrap the application. Then you can open the App.js file and start writing your HTML-like (JSX), Javascript, and even CSS code - by using any of the CSS-in-JS tools like StyledComponents. So all of the concerns go into a single file! &lt;/p&gt;

&lt;p&gt;You also need to understand some basic concepts like components, state, and props. Plus some extremely basic FP stuff. And that's it, more or less. &lt;/p&gt;

&lt;p&gt;Of course, things tend to get more complicated as the complexity of the app grows. And there are more concepts, design patterns, libraries, and tools you need to learn about and eventually master (like React Router, global state management, Redux, R-Thunk, R-Saga, rendering optimisation techniques etc.). &lt;/p&gt;

&lt;p&gt;But all of this is optional (not part of the React core library). Most of the extra stuff comes in the form of 3rd party libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  - The Angular way of doing things
&lt;/h3&gt;

&lt;p&gt;Angular takes things to a whole new level. If you want to build the famous &lt;strong&gt;TO-DO&lt;/strong&gt; list, the "Hello World" equivalent in the single-page application world, you can't just bootstrap an Angular app and start writing Javascript code in a single file.&lt;/p&gt;

&lt;p&gt;First, you have to learn Angular-specific abstractions and some new design patterns, like components, directives, templates, the basics of OOP, dependency injection, and more.&lt;/p&gt;

&lt;p&gt;You can argue that I said the same thing for React. In both cases, you need to learn the library-specific, basic stuff before building anything. And this is true. But in my opinion, Angular has much more of that "basic stuff" compared to React.&lt;/p&gt;

&lt;p&gt;You also need to know Typescript to write Angular apps. It is not a must, but it is an accepted industry standard.&lt;/p&gt;

&lt;p&gt;Also, the HTML, CSS, and TS code is isolated in separate files. It is similar to the classical way of building web apps, with a clear separation of concerns. This has its benefits - but I think I prefer how React handles this.&lt;/p&gt;

&lt;p&gt;Once you master the basics and start to think you're finally getting the hang of things, you pass the first hill on the Dunning-Kruger curve, and fall from the peak of "Mount Stupid" to the Valley of Despair. &lt;/p&gt;

&lt;h3&gt;
  
  
  - Things can quickly become complicated
&lt;/h3&gt;

&lt;p&gt;You eventually realize that Angular has much more stuff baked into its core than React (Router, Animations, RxJS) and that it is a complete SPA development toolbox. This is why people call it a framework. Unlike React, which is "just" a library. &lt;/p&gt;

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

&lt;p&gt;The current point in my Angular learning journey is probably somewhere near the bottom of the D-K curve. And I feel like I just started to roll a massive boulder up the hill of enlightenment. Thee bright side is that I'm slowly getting closer and closer to the summit.&lt;/p&gt;

&lt;h1&gt;
  
  
  The good stuff - How to build a NavBar with a Slider...
&lt;/h1&gt;

&lt;p&gt;...and to keep your sanity during that process. &lt;/p&gt;

&lt;p&gt;Last week I implemented the "NavBar with a dynamic slider underneath" component/feature on the project I'm currently working on (for a company client).&lt;/p&gt;

&lt;p&gt;So, for the purpose of this blog post I've re-created this component in isolation. I ran into an interesting problem along the way. Solving that problem required some creative thinking. &lt;/p&gt;

&lt;p&gt;Here's how the completed component looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/kYhwH6gYqDXBY0vPDL/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/kYhwH6gYqDXBY0vPDL/giphy.gif" width="480" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The NavBar component has 4 navigation items. By clicking on any of the items, the user is redirected to a predefined route ('/home', '/posts', '/random', '/speed') &lt;/p&gt;

&lt;p&gt;The main goal was to indicate the currently &lt;strong&gt;active&lt;/strong&gt; route, and consequently the currently active NavBar item to the user (hence the slider). &lt;/p&gt;

&lt;p&gt;Another requirement was that the slider needed to transition smoothly from one item to the other. &lt;/p&gt;

&lt;p&gt;The slider is implemented as an additional list element, with some basic styling:&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="c"&gt;&amp;lt;!-- navbar.component.html --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;#navElements&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of navItemsList"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; 
        &lt;span class="na"&gt;routerLink=&lt;/span&gt;&lt;span class="s"&gt;"/{{item.route}}"&lt;/span&gt; 
        &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"calcNewIndicatorDOMStyles()"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ item.name }}
      &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; 
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slider"&lt;/span&gt; 
      &lt;span class="na"&gt;[style.width.px]=&lt;/span&gt;&lt;span class="s"&gt;"activeItemWidth"&lt;/span&gt; 
      &lt;span class="na"&gt;[style.left.px]=&lt;/span&gt;&lt;span class="s"&gt;"activeItemLeftMargin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;navbar&lt;/span&gt;&lt;span class="nc"&gt;.component.css&lt;/span&gt;

  &lt;span class="nc"&gt;.slider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&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;You can find the running app &lt;a href="https://angular-ivy-wymmx8.stackblitz.io/name"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An additional requirement is that the slider &lt;strong&gt;width&lt;/strong&gt; needed to change dynamically and match the &lt;strong&gt;width&lt;/strong&gt; of the nav item above it.&lt;/p&gt;

&lt;p&gt;Nav item width change can happen in two scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screen resize.&lt;/strong&gt; The user can pivot his device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text translation change.&lt;/strong&gt; Simulated with the DE/EN button underneath the component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you look at the template file code below, you'll see that I used inline styles to dynamically set the slider's left margin and width:&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="c"&gt;&amp;lt;!-- navbar.component.html --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; 
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slider"&lt;/span&gt; 
    &lt;span class="na"&gt;[style.width.px]=&lt;/span&gt;&lt;span class="s"&gt;"activeItemWidth"&lt;/span&gt;    &lt;span class="err"&gt;&amp;lt;======&lt;/span&gt;
    &lt;span class="na"&gt;[style.left.px]=&lt;/span&gt;&lt;span class="s"&gt;"activeItemLeftMargin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;======&lt;/span&gt;
  &lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="na"&gt;li&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;activeItemWidth&lt;/em&gt; and &lt;em&gt;activeItemLeftMargin&lt;/em&gt; are calculated in this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// navbar.component.ts&lt;/span&gt;

    &lt;span class="nx"&gt;calcNewIndicatorDOMStyles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeItemWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&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;width&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeItemLeftMargin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&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;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method is triggered by the user when a nav item is clicked. Then the new slider position (margin-left) and width need to be re-calculated, so that the slider can transition under the new active item.&lt;/p&gt;

&lt;p&gt;So, the tricky part was figuring out how to get the "freshest" DOM styles (after the template re-renders and new properties are computed). To be more specific, I needed the newest nav element &lt;strong&gt;offsetWidth value (last render), so that it can be used in the &lt;em&gt;calcNewIndicatorDOMStyles()&lt;/em&gt; method to calculate the slider &lt;strong&gt;width&lt;/strong&gt; and &lt;strong&gt;left-margin&lt;/strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step was getting the target list elements from the view DOM. I used the &lt;strong&gt;ViewChildren&lt;/strong&gt; decorator for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// navbar.component.ts&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navElements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;navElements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
     &lt;span class="nx"&gt;QueryList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and this method to extract the new &lt;strong&gt;offsetWidth's&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// navbar.component.ts&lt;/span&gt;

  &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;getNewNavItemDOMWidths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navElementsList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navItemDOMProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;navElementsList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetWidth&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;Finally, I arrived to the reason why I used the word "sanity" in the headline. &lt;/p&gt;

&lt;p&gt;This was the hardest part to figure out. &lt;/p&gt;

&lt;p&gt;I asked myself which lifecycle method can I use to get the newest, freshly computed DOM style properties?&lt;/p&gt;

&lt;p&gt;The most likely candidates were &lt;strong&gt;ngAfterViewInit()&lt;/strong&gt; and &lt;strong&gt;ngAfterViewChecked()&lt;/strong&gt;. All of the other methods fired way too early in the comp lifecycle.&lt;/p&gt;

&lt;p&gt;But, to my surprise, calling the &lt;strong&gt;getNewNavItemDOMWidths()&lt;/strong&gt; method from either of those two methods didn't work. I was still getting the old values (from the previous render). &lt;/p&gt;

&lt;p&gt;So this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getNewNavItemDOMWidths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calcNewIndicatorDOMStyles&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;or this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;ngAfterViewChecked&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getNewNavItemDOMWidths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calcNewIndicatorDOMStyles&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;by itself didn't work.&lt;/p&gt;

&lt;p&gt;Example.&lt;/p&gt;

&lt;p&gt;Let's say that the current selected language was EN, and that the 4 nav items had widths 10, 20, 30, 40 (i am using random numbers here for the purpose of illustration). &lt;/p&gt;

&lt;p&gt;Then if I change the language to DE, this will cause the actual DOM widths to change to 50, 60, 70, 80 -  because the text length is different. &lt;/p&gt;

&lt;p&gt;If I tried to console log this in the &lt;strong&gt;ngAfterViewInit()&lt;/strong&gt; and &lt;strong&gt;ngAfterViewChecked()&lt;/strong&gt; lifecyle methods, I would get 10, 20, 30, 40 (the values from the previous render)&lt;/p&gt;

&lt;p&gt;How I managed to solve this problem.&lt;/p&gt;

&lt;p&gt;I formulated the following questions:&lt;/p&gt;

&lt;p&gt;Is the &lt;strong&gt;ngAfterViewChecked&lt;/strong&gt; lifecycle method called &lt;strong&gt;again&lt;/strong&gt;, after the template view re-renders and new DOM style properties are computed? &lt;/p&gt;

&lt;p&gt;If not, why? How can I force it to run?&lt;/p&gt;

&lt;p&gt;My investigation led me to the conclusion that Angular doesn't run this method by default when new DOM style properties are computed and available. It somehow needs to become aware, or forced, to re-run this method when the new styles become available.&lt;/p&gt;

&lt;p&gt;So, I solved it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;ngAfterViewChecked&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getNewNavItemDOMWidths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;navElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calcNewIndicatorDOMStyles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="mi"&gt;0&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 call to the setTimeout browser API inside this method forces Angular to re-run it every time, just in case. Because the callback fn inside &lt;strong&gt;setTimeout&lt;/strong&gt; can contain code which can potentially affect the View - after it has already been checked!&lt;/p&gt;

&lt;p&gt;And as you probably already noticed the second place in which the &lt;strong&gt;this.calcNewIndicatorDOMStyles()&lt;/strong&gt; is called, is inside the already mentioned lifecycle method.&lt;/p&gt;

&lt;p&gt;What's interesting about this solution, is that it also covers the case when the "window" gets resized. Resizing the viewport will trigger this lifecycle method and the new DOM styles will be fetched and used to updated the slider.&lt;/p&gt;

&lt;p&gt;And that's it, more or less.&lt;/p&gt;

&lt;p&gt;You can find the entire source code &lt;a href="https://stackblitz.com/edit/angular-ivy-wymmx8?file=package.json"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  - The end of this journey
&lt;/h3&gt;

&lt;p&gt;Thanks for reading until the end. &lt;/p&gt;

&lt;p&gt;I hope you learned something new about Angular. Or that the code I provided will help you on future projects.&lt;/p&gt;

&lt;p&gt;Speaking of which, I have a question for the Angular experts who read through this entire post.&lt;/p&gt;

&lt;p&gt;What do you think about my implementation? Is it fine, or is it an obvious antipattern? Is there something I could have done better? Thx&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>angular</category>
      <category>react</category>
    </item>
    <item>
      <title>Is functional programming in JS really worth it?</title>
      <dc:creator>Ivan Spoljaric</dc:creator>
      <pubDate>Fri, 04 Dec 2020 21:55:12 +0000</pubDate>
      <link>https://dev.to/ispoljari/is-functional-programming-in-js-really-worth-it-34cf</link>
      <guid>https://dev.to/ispoljari/is-functional-programming-in-js-really-worth-it-34cf</guid>
      <description>&lt;p&gt;I admit that I am still at the beginning of my FP journey, but it's examples like these that make me sceptical about the whole FP hype which is consuming the JS world.&lt;/p&gt;

&lt;p&gt;Imperative isOdd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOdd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imperative isEven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Declarative / FP isOdd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utilities&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mod2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mod&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eq1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fn2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// end result&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fpIsOdd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eq1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mod2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Declarative / FP isEven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utilities&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// end result&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fpIsEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fpIsOdd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The FP style may be more readable (or is it?), but I needed to write 5-6 utility functions to achieve the same end result, so what are the real benefits here?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I wouldn't even know how I could justify writing code like this to my team members.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;I am already used to writing FP code in moderation (in my JS/TS projects), like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using .map, .reduce, .filter&lt;/li&gt;
&lt;li&gt;constructing pure functions&lt;/li&gt;
&lt;li&gt;using redux for global state management (store, pure reducers, actions) &lt;/li&gt;
&lt;li&gt;doing shallow/deep copying of function params when needed (to minimise mutating reference variables outside of the function's lexical scope) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And implementing these concepts doesn't require so much overhead in code. To be fair, redux does add a layer of indirection but it's totally manageable and justified.&lt;/p&gt;

&lt;p&gt;But the more I learn about advanced FP concepts like pointfree style, composition and piping, the more absurd it seems to use it in my projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  So for me the jury is still out on this one
&lt;/h2&gt;

&lt;p&gt;Maybe I just can't see the grand and majestic FP forest because of all the composition/piping trees that I'm currently surrounded with. &lt;/p&gt;

&lt;p&gt;What do you think about FP? Do you have any experience in using the more advanced techniques in some serious JS/TS projects?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I just created my first NPM package. It ain't much but it's honest work</title>
      <dc:creator>Ivan Spoljaric</dc:creator>
      <pubDate>Fri, 24 Jul 2020 14:50:29 +0000</pubDate>
      <link>https://dev.to/ispoljari/i-just-created-my-first-npm-package-it-ain-t-much-but-it-s-honest-work-5h94</link>
      <guid>https://dev.to/ispoljari/i-just-created-my-first-npm-package-it-ain-t-much-but-it-s-honest-work-5h94</guid>
      <description>&lt;p&gt;Yesterday I learned that these NPM packages exist: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/is-odd" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/is-odd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/is-even" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/is-even&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/is-number" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/is-number&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have to admit that this both surprised and amused me. &lt;/p&gt;

&lt;p&gt;I was under the opinion that the average NPM package is a little bit more contrived than this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// is-odd&lt;/span&gt;

&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// is-number&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;num&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the thing that surprised me the most, is that developers actually use these packages as dependencies on their projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;is-odd&lt;/strong&gt; has 500k weekly downloads!&lt;/p&gt;

&lt;p&gt;And what makes this whole thing even funnier is that this package has a dependency of it's own, and it is the above stated &lt;strong&gt;is-number&lt;/strong&gt; package.&lt;/p&gt;

&lt;p&gt;So the final size of &lt;strong&gt;is-odd&lt;/strong&gt; comes down to cca. 6.5kB.&lt;/p&gt;

&lt;p&gt;I don't understand why this package, nor it's sister &lt;strong&gt;is-even&lt;/strong&gt; package, are so popular when it is so easy to "implement" the functionality they offer with vanilla JS (it requires just a single line of code).&lt;/p&gt;

&lt;p&gt;But don't get me wrong. I am not trying to be negative.&lt;/p&gt;

&lt;p&gt;Who knows why these packages exists and why they became so popular. &lt;/p&gt;

&lt;p&gt;For example, one of the reasons might be that the author initially created &lt;strong&gt;is-odd&lt;/strong&gt; because he was practicing how to publish a package to NPM.&lt;/p&gt;

&lt;p&gt;But this is just conjecture at this point and it is irrelevant to the remainder of this post and moral of the story :)&lt;/p&gt;

&lt;p&gt;I just wanted to explain my motivation before I came to the main topic of the post.&lt;/p&gt;

&lt;h1&gt;
  
  
  I present to you my very own, and first, published NPM package called &lt;strong&gt;linear-array&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Here it is: &lt;a href="https://www.npmjs.com/package/linear-array" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/linear-array&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just to be clear, I am completely aware of the actual uselessness of this package. &lt;/p&gt;

&lt;p&gt;But I decided to create it anyway because of the already stated reasons, and more importantly, because I wanted to learn how NPM packages are published.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Returns an array filed with linearly increasing numbers, starting from 0 up to the given value - 1 (without offset), or from 1 to the value itself (with offset).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to use it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;linearArray&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linear-array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// web&lt;/span&gt;

&lt;span class="nx"&gt;OR&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;linearArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linear-array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// server&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [0]&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [0,1,2]&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [0,1,2,3,4]&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [1]&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [1,2,3]&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="nf"&gt;linearArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//=&amp;gt; [1,2,3,4,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So it turns out that all of this actually isn't very complicated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzrxezc7d4swmsde2ocb1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzrxezc7d4swmsde2ocb1.jpg" alt="Honest work meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a short workflow on how to do it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think of a package that you could create and a unique name (check on the NPM repository that the name is not already taken)&lt;/li&gt;
&lt;li&gt;Create a local folder with the same name as your future NPM package&lt;/li&gt;
&lt;li&gt;Add the necessary files (index.js, README, LICENSE, and test.js if you want) and fill it with markdown and code&lt;/li&gt;
&lt;li&gt;Run

&lt;code&gt;git init&lt;/code&gt;

in your terminal&lt;/li&gt;
&lt;li&gt;Push to Github repo with the same name as the local project name&lt;/li&gt;
&lt;li&gt;Run

&lt;code&gt;npm init&lt;/code&gt;

in your terminal&lt;/li&gt;
&lt;li&gt;Register your profile on &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;https://www.npmjs.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run

&lt;code&gt;npm login&lt;/code&gt;

in your terminal&lt;/li&gt;
&lt;li&gt;Run

&lt;code&gt;npm publish&lt;/code&gt;

in your terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take a look of the project repo of &lt;a href="https://github.com/ispoljari/linear-array" rel="noopener noreferrer"&gt;&lt;strong&gt;linear-array&lt;/strong&gt;&lt;/a&gt; if you get stuck somewhere.&lt;/p&gt;

&lt;h1&gt;
  
  
  That's it.
&lt;/h1&gt;

&lt;p&gt;Thanks for reading this post until the end. &lt;/p&gt;

&lt;p&gt;The moral of the story is, it doesn't matter if you think that your idea for an NPM package is a shitty one. &lt;/p&gt;

&lt;p&gt;What does matter is the learning journey. &lt;/p&gt;

&lt;p&gt;And because it is fun to try new things like this.&lt;/p&gt;

&lt;p&gt;P.S.&lt;/p&gt;

&lt;p&gt;If you actually find some use for my package and decide to install it on your project, I'm begging you to reconsider and that you don't do actually do it. 😂  &lt;/p&gt;

&lt;p&gt;Just copy the code directly from the index.js file on the project repo page.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>npm</category>
      <category>motivation</category>
    </item>
    <item>
      <title>What music do you like to listen while coding? Here are some of my personal favourites that help me get "in the zone".</title>
      <dc:creator>Ivan Spoljaric</dc:creator>
      <pubDate>Fri, 10 Apr 2020 13:10:13 +0000</pubDate>
      <link>https://dev.to/ispoljari/what-music-do-you-like-to-listen-while-coding-here-are-some-of-my-personal-favourites-that-help-me-get-into-the-zone-3ie9</link>
      <guid>https://dev.to/ispoljari/what-music-do-you-like-to-listen-while-coding-here-are-some-of-my-personal-favourites-that-help-me-get-into-the-zone-3ie9</guid>
      <description>&lt;p&gt;I've noticed that listening to music while coding helps me to switch into my &lt;a href="https://medium.com/swlh/deep-work-how-to-develop-the-most-valuable-skill-of-the-21st-century-5ab655e13a42"&gt;deep work&lt;/a&gt; mode. &lt;/p&gt;

&lt;p&gt;Although I sometimes listen to generic stuff, like the current Global Top 50 Hits, most of the time I prefer purely instrumental music (with just a touch of vocals sprinkled in the right places). My personal favorites are soundtracks from sci-fi tv-series and movies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Sci-Fi
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kLqR5BVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/19oi2xu2ddz4qvcbjypm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kLqR5BVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/19oi2xu2ddz4qvcbjypm.jpeg" alt="Dune sandworm" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am a huge fan of the sci-fi genre (also fantasy, but to a lesser extent). Ever since I was a small kid I loved reading novels from great writers like Isaac Asimov (I, Robot), Frank Herbert (Dune), Arthur C. Clarke (The Songs of Distant Earth or 2001: A Space Odyssey) and Carl Sagan (Contact). I also loved watching tv-series like Star Trek, Firefly, Stargate SG1, and movies like Star Wars, Sunshine, The Matrix and Interstellar. This is to name a few. &lt;/p&gt;

&lt;p&gt;That's why my coding playlists have soundtracks like; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/track/50ExtKr8j9cHTY3OEw282G?si=0tjR-QfNQrqDDLDhj2hIHw"&gt;Sunshine: Adagio in D-minor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/track/1wFQuJK6SPvFssKUzSIRwx?si=P-yD4NMFRTGP5ncsTmxo8A"&gt;Interstellar: Day One&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/track/2bqDxQQi37VOK880m5PU8R?si=wnGWGcSBTaSv5vrr5-FvYg"&gt;Children of Dune: Inama Nushif&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open.spotify.com/track/6ZFbXIJkuI1dVNWvzJzown?si=VywquIkpSTiWY3K71tVLMA"&gt;Inception: Time&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't understand completely why these specific songs (or the sci-fi genre in general) strike an "emotional" chord for me, or how they help me to get "in the zone". I believe it has something to do with my emotional attachment to the stories and characters. Like I'm somehow reliving the experiences I had while watching those tv shows or movies. &lt;/p&gt;

&lt;h1&gt;
  
  
  Today's recommendation
&lt;/h1&gt;

&lt;p&gt;Here is something I've been listening to for the past few days. The season 3 soundtracks of the &lt;a href="https://www.imdb.com/title/tt0407362/"&gt;2004-2008 Battlestar Galactica TV Series&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This TV series is absolutely awesome and a must-see for every Sci-Fi fan out there. But so is the music (mainly because of Bear McCreary's brilliance). &lt;/p&gt;

&lt;p&gt;Anyway, I hope you enjoy this playlist as much as I do. My favourites are: 03-Admiral And Commander, 06-Wayward Soldier and 21-All along the Watchtower.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/embed/Q9CqxkuSldY"&gt;Battlestar Galactica Season 3 Soundtrack&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you like to listen to while coding? Feel free to write any suggestions you have in the comments. :)
&lt;/h2&gt;

</description>
      <category>productivity</category>
      <category>discuss</category>
      <category>motivation</category>
    </item>
  </channel>
</rss>
