<?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: Michał Gacka</title>
    <description>The latest articles on DEV Community by Michał Gacka (@m3h0w).</description>
    <link>https://dev.to/m3h0w</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%2F353359%2F9f2f538c-899b-44cd-b11e-23d2129e006e.jpeg</url>
      <title>DEV Community: Michał Gacka</title>
      <link>https://dev.to/m3h0w</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/m3h0w"/>
    <language>en</language>
    <item>
      <title>How to load environment variables in Svelte</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Mon, 28 Feb 2022 09:52:07 +0000</pubDate>
      <link>https://dev.to/3dayweek/how-to-load-environment-variables-in-svelte-19bp</link>
      <guid>https://dev.to/3dayweek/how-to-load-environment-variables-in-svelte-19bp</guid>
      <description>&lt;p&gt;Svelte is a new, up-and-coming framework for building fast web applications. In contrast to React, it does a lot of the heavy lifting in a compile step instead of in the browser. It's very clever and comes with enormous advantages but can also have its pitfalls for developers used to the more popular frameworks. In case of the environment variables, one can't just import &lt;code&gt;dotenv&lt;/code&gt; wherever and assume it will work - a replace plugin of rollup (the bundler) has to be used instead. This tutorial uses &lt;code&gt;yarn&lt;/code&gt; for a package manager and would work the same with &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using dotenv and rollup's replace plugin to load environment variables
&lt;/h2&gt;

&lt;p&gt;In order to be able to load environment variables like we're used to: &lt;code&gt;process.env.&amp;lt;variable-name&amp;gt;&lt;/code&gt;, we will use &lt;code&gt;@rollup/plugin-replace&lt;/code&gt; together with &lt;code&gt;dotenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The magic will happen in the &lt;code&gt;rollup.config.js&lt;/code&gt; file which tells rollup how to build our project. First, go ahead and install the required dependencies using &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;. I'll assume yarn. Run &lt;code&gt;yarn add --dev @rollup/plugin-replace dotenv&lt;/code&gt; and create a &lt;code&gt;.env&lt;/code&gt; file (remember to git ignore it) in the main folder of your repo.&lt;/p&gt;

&lt;p&gt;Now, in your rollup config, tell rollup to use the replace plugin, define which files it should include in the replacement procedure and which strings you want to replace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  .
  .
  .
  plugins: [
    replace({
      include: ["src/**/*.ts", "src/**/*.svelte"],
      preventAssignment: true,
      values: {
        "process.env.TESTVAR": "'replacedtestvar'"
      }
    }),
  .
  .
  .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the replacement happens at compile time which means that if you don't wrap the values of the provided dictionary in an additional quotation, javascript will be looking for a variable of that name instead of understanding that it was supposed to be a string. Thus, in order to use the familiar &lt;code&gt;process.env.&amp;lt;variable-name&amp;gt;&lt;/code&gt; we will make a simple transformation of our config loaded using dotenv.&lt;/p&gt;

&lt;p&gt;First import dotenv at the top of your &lt;code&gt;rollup.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { config } from 'dotenv';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then proceed to transform the env. variables to suit the replace plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const configToReplace = {};
for (const [key, v] of Object.entries(config().parsed)) {
  configToReplace[`process.env.${key}`] = `'${v}'`;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally adjust the plugins option of the exported rollup config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  .
  .
  .
  plugins: [
    replace({
      include: ["src/**/*.ts", "src/**/*.svelte"],
      preventAssignment: true,
      values: configToReplace,
    }),
  .
  .
  .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to adjust the include option of the plugin and then you can joyfully write &lt;code&gt;process.env...&lt;/code&gt; to access the properties you loaded from your .env file.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>You need a manager, not a boss 🤝</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Sat, 29 Jan 2022 20:27:30 +0000</pubDate>
      <link>https://dev.to/3dayweek/you-need-a-manager-not-a-boss-2go5</link>
      <guid>https://dev.to/3dayweek/you-need-a-manager-not-a-boss-2go5</guid>
      <description>&lt;p&gt;In a conversation about how a lot of part-time workers vs a few full-time workers can affect a team, my tech friend recently asked me: “Are managers a relic of the past or are they absolutely essential?” Both, I answered.&lt;/p&gt;

&lt;p&gt;A manager as we know them is usually our boss. Someone that holds the superior power and the superior responsibility and organizes, controls, administers an organization or a group. That, I argued, is indeed unnecessary and will become less and less practiced.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In that model, a manager is not telling people what to do anymore but merely facilitates the work and is an equal unit of them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it doesn’t mean that we don’t need managers at all. On the contrary! As the structures flatten, and responsibility spreads to more nodes, more meta work (organizing, communication, planning, synchronizing, etc. – as opposed to development work) will emerge and we need people who specialize in those areas to keep our collaboration smooth and goals on target.&lt;/p&gt;

&lt;p&gt;A great example of that is the transition from traditional project management to self-organization. Scrum moves away from someone telling the team what to do and towards a doocratic model of the responsibility in an area belonging with those who actually perform the tasks in that area. In that model, a manager is not telling people what to do anymore but merely facilitates the work and is an equal unit of them.&lt;/p&gt;

&lt;p&gt;Seems obvious? It should be. But still, often I see hierarchical legacies of the structures built up within an organization – or even psychological legacies of operating within hierarchical structures – interfering with the very foundation of scrum processes limiting the flexibility of the participants and having a plethora of negative consequences for the individuals, the team, and the products.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I strongly believe in driving the change even if it doesn’t seem to be your direct responsibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what can you do as a member of a confused team? I strongly believe in driving the change even if it doesn’t seem to be your direct responsibility (the more it doesn’t, the more you should!). Don’t just focus on writing the code. Go learn a little about project management, product management, and different ways of organizing teams. Start having those conversations with your colleagues and your managers. Maybe they too can become more of facilitators than bosses. You have the power to shape your environment, use it.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Impactful Coding Communities?</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Tue, 16 Mar 2021 12:29:39 +0000</pubDate>
      <link>https://dev.to/m3h0w/impactful-coding-communities-19h4</link>
      <guid>https://dev.to/m3h0w/impactful-coding-communities-19h4</guid>
      <description>&lt;p&gt;I've been toying with the idea of creating some kind of a dev community that only wants to apply their skills to socially impactful, "good" or hippie projects. A place where programmers with shared values of improving the world around them could meet, join together into workgroups, explore ideas, etc.&lt;/p&gt;

&lt;p&gt;I personally find it difficult to know where to direct my energy whenever I decide to leave my previous job/project and would benefit a lot from having a network that I know focuses on things that I care about. I could then reach out and easily find opportunities based on the trust developed in that community.&lt;/p&gt;

&lt;p&gt;Do you know of any initiatives like that? Would you want to be a part of it?&lt;/p&gt;

&lt;p&gt;// forgive the creepy cover image -&amp;gt; that's what google thinks a hippie techie looks like&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>inclusion</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Always write at least 1 end-to-end test. You'll love it, I promise.</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Mon, 01 Mar 2021 14:56:20 +0000</pubDate>
      <link>https://dev.to/3dayweek/always-write-at-least-1-end-to-end-test-you-ll-love-it-i-promise-2kpm</link>
      <guid>https://dev.to/3dayweek/always-write-at-least-1-end-to-end-test-you-ll-love-it-i-promise-2kpm</guid>
      <description>&lt;p&gt;The cover image shows you how I felt the first time I ran an end-to-end test of a web service I was developing. You can feel like that too. If you always write at least one end-to-end test as soon as you start developing a new project or a module in your project. Why?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Because even in the early stages of development it will save you a lot of headaches and time: you won't have to check manually if things work every time you make changes to the code.&lt;/p&gt;

&lt;p&gt;I shed a tear every time I think about how much time I've spent in my early dev years having to run the code and check that things work every time I changed an env variable name or fixed a bunch of linting errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonuses
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;by being lazy like that, you'll join the high echelons of programmers who have the test framework always set up and ready to accommodate more tests when you feel fancy enough to add some&lt;/li&gt;
&lt;li&gt;if you're anything like me and you tend to postpone writing tests on hobby projects, following this principle will help you conceptualize the problem as not-a-big-deal-at-all since you only promised to add 1 test (the rest will eventually follow)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What kind of test to write?
&lt;/h2&gt;

&lt;p&gt;For a front-end, it's nice usually nice to have some kind of simple click-through with a login step (if your application consists of such) and making sure that all the views/pages are accessible and rendered. For a micro-service or an API, it's great to have it accept some data and check the response or that it saved things in the database correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remember git hooks
&lt;/h2&gt;

&lt;p&gt;You got this far in automating something that takes your time unnecessarily. Then why run the &lt;code&gt;npm test&lt;/code&gt; command manually? &lt;a href="https://typicode.github.io/husky/#/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; makes git hooks simple and fun. You just write a simple script, call it pre-push and your tests will run automatically before the code gets pushed to the remote.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remember Docker
&lt;/h2&gt;

&lt;p&gt;Synchronizing applications and services for testing can be a headache so make sure to have a nice and clean docker setup so you can easily spin up containers that depend on each other for testing purposes.&lt;/p&gt;

&lt;p&gt;And if you're not on the Docker train yet, you should definitely incorporate DevOps skills into your practice. It's a must.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>testing</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to get an accurate position estimate from the Geolocation API in JavaScript</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Mon, 08 Feb 2021 15:15:32 +0000</pubDate>
      <link>https://dev.to/3dayweek/how-to-get-an-accurate-position-estimate-from-the-geolocation-api-in-javascript-1njf</link>
      <guid>https://dev.to/3dayweek/how-to-get-an-accurate-position-estimate-from-the-geolocation-api-in-javascript-1njf</guid>
      <description>&lt;p&gt;The Geolocation API has been introduced into modern browsers many years ago and hasn't changed much since yet it still can waste many hours of your time if you don't know how to work with it. There's a lot of magic happening behind the scenes that isn't properly explained in the documentation. Here's a straightforward way to get an accurate estimate without you having to spend the 2 days I've spent figuring out why my location estimates look like out of a random number generator.&lt;/p&gt;

&lt;p&gt;There are 2 functions you can use to ask the browser for location estimates: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition" rel="noopener noreferrer"&gt;getCurrentPosition()&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition" rel="noopener noreferrer"&gt;watchPosition()&lt;/a&gt;. So far so good: the first will spit out 1 position on success, while the second will keep throwing new positions at you as they are updated. It's important to note that the &lt;code&gt;GeolocationCoordinates&lt;/code&gt; object that we get as a result of either of these 2 functions contains the estimated position and accuracy of the measurement in meters.&lt;/p&gt;

&lt;p&gt;For my application, where the user was supposed to trigger a location measurement it seemed obvious to use the &lt;code&gt;getCurrentPosition()&lt;/code&gt; since in that case, I wouldn't have to take care of storing the state of change coming from &lt;code&gt;watchPosition()&lt;/code&gt; and having to use &lt;code&gt;clearWatch()&lt;/code&gt; to stop listening at an appropriate time. It seemed perfect. And turned out to be completely useless.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getCurrentPosition()&lt;/code&gt; accepts an &lt;code&gt;options&lt;/code&gt; object where you can turn &lt;code&gt;enableHighAccuracy&lt;/code&gt; boolean to true. It comes with high hopes and an even larger disappointment. Even with the boolean, the measurements I'd get from my phone would have an accuracy of thousands of meters which rendered them virtually useless for what I needed.&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;watchPosition()&lt;/code&gt;. After reading some obscure blog I don't remember the name of that went into details of how the GPS module might work in the phone, I learned that it might take a few seconds to warm up and spit out a correct position. And that is the crucial piece of knowledge you need to solve this problem. One that should definitely be explained in more depth in some of the official sources that explain how to use this API.&lt;/p&gt;

&lt;p&gt;Knowing that I implemented my logic using &lt;code&gt;watchPosition()&lt;/code&gt; instead and it turned out that indeed, magically the accuracy again starts at thousands of meters but, after a few seconds of these bad measurements, the GPS kicks in and provides estimates with a few meters of accuracy. These, finally, make sense for my application.&lt;/p&gt;

&lt;p&gt;Here's an example of a function I use within the React's &lt;code&gt;useEffect()&lt;/code&gt; hook. Note the returned function that allows me to clear the watch by returning it from the hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;setLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ILocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setAccuracy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&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;geoId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watchPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&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;const&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&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;lng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;setLocation&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lng&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nf"&gt;setAccuracy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lng&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accuracy&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;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;showErrorSnackBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The GPS accuracy isn't good enough&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;span class="nx"&gt;e&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="nf"&gt;showErrorSnackBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enableHighAccuracy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximumAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Clear watch called&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;geoId&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;return&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;That's all you need to get accurate estimates from the Geolocation API. Let me know in the comments if this worked for you ☀️&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt;&lt;br&gt;
Here's also a React hook version of a similar functionality (still imperfect but a good starting point for your own Geolocation hook):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;accuracyThreshold&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;accuracyThresholdWaitTime&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&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;PositionOptions&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ILocation&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAccuracy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&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;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLocation&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ILocation&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;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useEffect&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAccuracy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timeout&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;geoId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;watchPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&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;const&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&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;lng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nf"&gt;setAccuracy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accuracy&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;accuracyThreshold&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;accuracyThreshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setLocation&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lng&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enableHighAccuracy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximumAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&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="nx"&gt;accuracyThreshold&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;accuracyThresholdWaitTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;accuracyThreshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to reach desired accuracy&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="nx"&gt;accuracyThresholdWaitTime&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearWatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;geoId&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;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Geolocation API not available&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// eslint-disable-next-line react-hooks/exhaustive-deps&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accuracyThresholdWaitTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accuracyThreshold&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;It lets you specify an &lt;code&gt;accuracyThresholdWaitTime&lt;/code&gt; which decides how long the &lt;code&gt;watchLocation&lt;/code&gt; will listen for before deciding that the accuracy is not good enough (for example when someone is indoors the accuracy will never get better than ~10m and you might need it to reach ~3m to serve your purpose).&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>5 unexpected advantages of working with more experienced developers</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Thu, 17 Dec 2020 21:57:35 +0000</pubDate>
      <link>https://dev.to/3dayweek/5-unexpected-advantages-of-working-with-more-experienced-developers-1gp5</link>
      <guid>https://dev.to/3dayweek/5-unexpected-advantages-of-working-with-more-experienced-developers-1gp5</guid>
      <description>&lt;p&gt;I've spent the last year and a half developing the software part of a bigger product as the only software engineer in a startup that I cofounded. It had many benefits but also made me realize these surprising benefits of having more experienced colleagues around.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. They will tell you that your linter is taking too long to recompute&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Way too often, as an inexperienced developer, I just wasn't sure what my experience in working with technology should be like. I'd choose libraries that were difficult to use and spend time with programming languages I didn't enjoy working with. &lt;/p&gt;

&lt;p&gt;Some time ago, I had the experience of using TSLint with up to a 2-second delay on changes without knowing that it shouldn't be like that and how important consequences it will have for my productivity and code quality (as I'm writing this, it sounds quite obvious but I'm sure you can think of times when obvious problems or solutions hid from you in plain sight). &lt;/p&gt;

&lt;p&gt;If there was a colleague next to me with more experience using TypeScript they would immediately point out to me, how crucial it is to fix this issue.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. You'll be reminded about taking breaks and inspired to take on different work organization methods&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It's way too often overlooked how important it is to have patterns of organizing your work as a developer. And there is no better way of realizing that you're bad at it than by observing your more senior co-workers. Even if you don't realize it yet, you'll at least be reminded to take a break when they do it instead of falling into a 5h coding frenzy and waking up unproductive and hungry on the other side (still happens to me occasionally 🙃).&lt;/p&gt;

&lt;p&gt;If you're not doing it already, experiment with the Pomodoro technique to figure out what kind of rhythm of work and breaks makes sense for your body and your mind. For Windows, I recommend this super simple app called &lt;a href="https://www.microsoft.com/en-us/p/focus-10/9nblggh5g2xh?activetab=pivot:overviewtab" rel="noopener noreferrer"&gt;Focus 10&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. They will (hopefully) teach you how to respectfully disagree&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the most important policies in life I have is direct and honest communication. And there's almost nothing else that puts it at a test as much as discussions and conflicts with more senior team members. If you don't get to practice communicating your point of view without causing too many negative emotions to your team members, you'll lack one of the most crucial skills to maintaining healthy dev-dev relationships.&lt;/p&gt;

&lt;p&gt;A quick tip that used to help a lot in a small team I was a part of: whenever you seem to be heading towards a disagreement, ask each other "how strongly do you feel about this from 1-10?". We'd often find that even though a person gets heated up in the discussion they actually don't mind letting the other one take the lead on the decision - they would answer e.g. 2 while the other person said 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. They will make you feel smart&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Coding can be a very solitary practice. Working alone you might spend weeks or months without much appreciation coming in from the outside world (heck, when you're learning to code it might feel like you've spent years just making mistakes and writing useless code - if you feel like that: hit me up, I'll have some advice of how to structure your learning process better).&lt;/p&gt;

&lt;p&gt;But there aren't many moments more rewarding in a programmer's career than the times when someone you look up to reaffirms you with a well-deserved compliment. Coders are often a tough bunch, so if you find a colleague that is a solid programmer, knows how to communicate, and is willing to guide you, sit close-by and learn to listen.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. You'll notice they changed their font in vscode and start using ligatures&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I'm almost joking. But not really. A few weeks ago in the darkness of the pandemic and the Danish winter combined my motivation to program was revived but something as silly as customizing my vscode experience. I changed my vscode font to &lt;code&gt;Fira Code&lt;/code&gt;, started using these cool coding ligatures (special characters that combine multiple other characters, e.g. &lt;code&gt;=&amp;gt;&lt;/code&gt; will become an arrow that looks like 1 character) I saw at my colleagues' screens years ago but somehow never tried myself, and I installed the &lt;code&gt;Bracket Pair Colorizer&lt;/code&gt; extension. Together it made my IDE shine and my brain feel like it's my first day of programming.&lt;/p&gt;

&lt;p&gt;Of course, I'm exaggerating a little and the excitement didn't last very long but what did stay with me is the feeling that I am in charge of my own experience. Every time I notice the colorful brackets or the ligatures it reinforces that feeling (I argue in another article for &lt;a href="https://dev.to/m3h0w/coder-s-biggest-and-most-hidden-enemy-2jp"&gt;why I think it's so important to take an active part in shaping your coding environment&lt;/a&gt;).&lt;/p&gt;




&lt;p&gt;Ok, but what if someone just started to learn to code or for other reasons doesn't have access to more experienced colleagues? Well, there are some alternatives: read blogs, attend conferences (when there happen to be no raging pandemics at that moment), watch vlogs to understand better how people with more experience structure their work and coding approach. &lt;a href="https://wesbos.com/uses" rel="noopener noreferrer"&gt;Here's a cool example&lt;/a&gt; of a blogger who put a lot of effort into creating a customized environment that suits his needs perfectly and who inspired me to customize my vscode.&lt;/p&gt;

&lt;p&gt;But in the end, I'd say programming is a little bit like music. You can do it alone but in the end, as a social creature that we happen to be, you'll regret not having people around you while on your path to becoming a great coder.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Would you use a chrome extension that makes you google SO answers faster? 🚀</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Wed, 16 Dec 2020 15:14:23 +0000</pubDate>
      <link>https://dev.to/m3h0w/would-you-use-a-chrome-extension-that-makes-you-google-so-answers-faster-1o85</link>
      <guid>https://dev.to/m3h0w/would-you-use-a-chrome-extension-that-makes-you-google-so-answers-faster-1o85</guid>
      <description>&lt;p&gt;I found lately that whenever I'm learning a new language or library or I focus on something very specific (like fixing typing errors in TypeScript) I'd lose a lot of time refocusing from vscode to Chrome, retyping a similar query, and having to select the first search result. So I made a chrome extension that does that and I wonder if you'd like to beta test it.&lt;/p&gt;

&lt;center&gt;![Brisk Logo](https://dev-to-uploads.s3.amazonaws.com/i/554brdd6eiiyhp2443lw.png)
&lt;sup&gt;*A great excuse to draw a happy squirrel. Brisk's logo.*&lt;/sup&gt;
&lt;/center&gt;

&lt;p&gt;It's all based on the assumption that Google is much better at searching SO than SO's built-in search function. The chrome extension is called Brisk and it lets you define a global shortcut (you can trigger it directly from your ide) that will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;focus chrome, &lt;/li&gt;
&lt;li&gt;open up a window automatically into which you can type in your query &lt;/li&gt;
&lt;li&gt;it will then run that (optionally with a prefix defined by you - e.g. 'python' so that you don't have to retype the beginning all the time) query into google &lt;/li&gt;
&lt;li&gt;and select the first StackOverflow answer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's still a bit experimental and even though it works for me I wonder if you'd be up for trying it out (in dev mode before I release it) so that I can adjust it to your needs ☀️ &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>help</category>
    </item>
    <item>
      <title>Coder's biggest and most hidden enemy. Creeping up on you right now</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Fri, 11 Dec 2020 13:54:55 +0000</pubDate>
      <link>https://dev.to/3dayweek/coder-s-biggest-and-most-hidden-enemy-2jp</link>
      <guid>https://dev.to/3dayweek/coder-s-biggest-and-most-hidden-enemy-2jp</guid>
      <description>&lt;p&gt;It's to a programmer like a pandemic to a society. It creeps up on you. Slowly. There are some tiny signs of it at first but... who would bother? Then it becomes more and more obvious but to an untrained eye, it still seems ignorable. I mean, it's not like it's that bad, right? Life's a bit harder: it gets harder to focus, things are getting a little bit out of control, few bugs here and there creep into the application. But for sure, that can't yet justify the effort that would have to be applied to resolving it, can it?&lt;/p&gt;

&lt;p&gt;Until - in case of a pandemic - we wake up as a society with overloaded hospitals, a badly-hit economy, and a lack of organizational structure to deal with the exponentially arising problems.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;"It creeps up on you. Slowly. There are some tiny signs of it at first but... who would bother?"&lt;/em&gt;
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;In case of clutter and disorder, a programmer wakes up with a couple of glasses, dirty plates, a few used face masks, unnecessary gadgets, a few useless cables, and an endless list of how-did-this-even-get-here items on their desk, laptop's desktop overflown with icons and files that should have never made it to the front of his workspace, code-base with hundreds of ignored linting errors, and a general feeling that it would take more energy to sit down and put a few hours into the project than to pick up a new career.&lt;/p&gt;

&lt;p&gt;If there's one thing you should do today, let it be this: unclutter. Your desk, your computer, your project. And yourself. If you can, just pause anything else you're doing right now, set a timer for 1 hour, and try to clean as much of the unnecessary mental barriers that exist between you and the joyous motivation to write code that you hopefully still can remember is possible. Your future self will thank your now-you. Trust me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;"...a general feeling that it would take more energy to sit down and put a few hours into the project than to pick up a new career"&lt;/em&gt;
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not enough time? Do the same thing tomorrow. First thing in the morning. Start your day by offering yourself the gift of a clear, uncluttered work environment that will surely translate into higher efficiency, less stress, and ultimately a happier life.&lt;/p&gt;

&lt;p&gt;If you have previous practice meditating or practicing mindfulness, I believe it is helpful to try to apply the same kind of techniques to observing when we decide to cut corners and start piling up the clutter that ultimately creates new corners - unnecessary obstacles to overcome. Try really paying attention to that feeling when you type ": any" to avoid having to come up with a type for that variable or when you sit down to work in a dirty workspace instead of decluttering and cleaning it first.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;"Start your day by offering yourself the gift of a clear, uncluttered work environment that will surely translate into higher efficiency, less stress, and ultimately a happier life"&lt;/em&gt;
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then try to observe how pleasurable it is and how positively it affects your motivation when you feel that your workspace and your code are clean. How good it feels when all your TypeScript variables explain their structure upon hovering. How calm your mind is when you sit down at a clean, spacious desk with that beloved cup of warm coffee. How good life feels when you are the one in control.&lt;/p&gt;




&lt;p&gt;Here's a quick challenge for you: post in the comments a picture of your desk or your laptop's desktop (or both) right here right now. Without cleaning or changing anything 🤨🧐😀&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Anyone else worked on a covid19-related project? 🤓</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Fri, 11 Dec 2020 13:49:55 +0000</pubDate>
      <link>https://dev.to/m3h0w/anyone-else-worked-on-a-covid19-related-project-5ehg</link>
      <guid>https://dev.to/m3h0w/anyone-else-worked-on-a-covid19-related-project-5ehg</guid>
      <description>&lt;p&gt;The moment the pandemic started I got so overwhelmed by having to compute the consequences of such an unprecedented situation that I couldn't focus on my day job and felt like I had to focus on doing something related to covid19. It helped and I learned a lot in the process.&lt;/p&gt;

&lt;p&gt;I ended up making a data visualization page in TypeScript and React that allows for comparing countries' infection trajectories and visualizes the cases and deaths on a simple map. I called it &lt;a href="https://covid19.pink/infection-trajectories" rel="noopener noreferrer"&gt;COVID19.PINK&lt;/a&gt; because the color domains were almost the only ones available for covid19 🙃&lt;/p&gt;

&lt;p&gt;It's open-source if you want to &lt;a href="https://github.com/m3h0w/covid19-coronavirus-react-visualization" rel="noopener noreferrer"&gt;check out the details&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Did you build anything related to the coronavirus? 🤓 What was your motivation? I'd love to see your projects.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>datascience</category>
      <category>covid19</category>
    </item>
    <item>
      <title>Don't struggle with extending the service worker in Create React App anymore. Upgrade to version 4!</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Mon, 07 Dec 2020 14:50:28 +0000</pubDate>
      <link>https://dev.to/3dayweek/don-t-struggle-with-extending-the-service-worker-in-create-react-app-anymore-upgrade-to-version-4-3p2n</link>
      <guid>https://dev.to/3dayweek/don-t-struggle-with-extending-the-service-worker-in-create-react-app-anymore-upgrade-to-version-4-3p2n</guid>
      <description>&lt;p&gt;No need to struggle with how to customize and extend the service worker without ejecting &lt;a href="https://create-react-app.dev/" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt; anymore. Version 4, released in October 2020, comes with a service worker file available for extension in the src folder.&lt;/p&gt;

&lt;p&gt;I wrote a post about &lt;a href="https://dev.to/m3h0w/the-easiest-way-to-extend-create-react-app-service-worker-without-ejecting-bfg"&gt;the simplest way to extend the default service worker in CRA&lt;/a&gt; to help others who were dealing with this task. A strangely easy task requiring a dreadful amount of research and trial and error. But that was before I found out that there is an even simpler way: upgrading to the new CRA version.&lt;/p&gt;

&lt;p&gt;The previous post generated some attention so I figured that I'm not the only one, who doesn't realize that one can now access the Service Worker file and edit it directly in the new CRA version.&lt;/p&gt;

&lt;p&gt;Simply initialize the project with:&lt;br&gt;
&lt;code&gt;npx create-react-app my-app --template cra-template-pwa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or:&lt;br&gt;
&lt;code&gt;npx create-react-app my-app --template cra-template-pwa-typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And the service worker will be available for extension the src folder. Check out the &lt;a href="https://create-react-app.dev/docs/making-a-progressive-web-app/" rel="noopener noreferrer"&gt;official guide&lt;/a&gt; for more information and instructions.&lt;/p&gt;

&lt;p&gt;Upgrading is quite straightforward too. I recommend creating the new project on the side, comparing the package.json files to update the old one, copying and merging the files generated in the src folder to the old project, and then fixing compile errors if any occur. It didn't take more than 20 minutes for my relatively large project.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Supporting choiceful (object and array) destructuring in JavaScript and TypeScript</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Tue, 01 Dec 2020 12:27:13 +0000</pubDate>
      <link>https://dev.to/3dayweek/supporting-choiceful-destructuring-object-and-array-in-javascript-and-typescript-22a6</link>
      <guid>https://dev.to/3dayweek/supporting-choiceful-destructuring-object-and-array-in-javascript-and-typescript-22a6</guid>
      <description>&lt;p&gt;The joy of object and array destructuring is most likely known to you (check out an example below if it's not 🙂). But what about the joy of being able to choose between them while using the same function? How exciting would that be!?&lt;/p&gt;

&lt;p&gt;Wait, but why? Well, because each has its upsides and there is usually no good enough reason to force the developer to use one of them by design. Array destructuring allows you to more succinctly rename the variables but requires remembering the order, while object destructuring forces you to remember the name but doesn't mind the order.&lt;/p&gt;

&lt;p&gt;What are object and array destructuring?&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;// object destructuring&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;firstN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Plants&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;need&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;water&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;firstN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// water&lt;/span&gt;

&lt;span class="c1"&gt;// array destructuring&lt;/span&gt;
&lt;span class="kd"&gt;const&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;Plants&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;need&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;water&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstNoun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verb&lt;/span&gt;&lt;span class="p"&gt;]&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstNoun&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Plants&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are a succinct way to retrieve variables from a more complex type. Easy to use and easy to read. If used adequately. And in order to maximize the chance that they are indeed used correctly, you might want to defer the choice for which one to use by allowing both when returning from your functions. Just like the &lt;a href="https://github.com/thebuilder/react-intersection-observer" rel="noopener noreferrer"&gt;useInView() React Hook&lt;/a&gt; did which inspired me to write this.&lt;/p&gt;

&lt;p&gt;First in pure JavaScript:&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;veryImportantSelfContainedLogic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;result&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;Plants&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;need&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;waters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;anotherWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notAWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&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;And then in TypeScript (highly recommended if you haven't made the transition yet):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;VeryImportantSelfContainedLogicResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;firstWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;anotherWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;notAWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;veryImportantSelfContainedLogic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;VeryImportantSelfContainedLogicResponse&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;const&lt;/span&gt; &lt;span class="nx"&gt;result&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;Plants&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;need&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;waters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;VeryImportantSelfContainedLogicResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;anotherWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notAWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&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 developer using your function can then choose which type of restructuring to use depending on their mood (or some other considerations if one finds them more important):&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;// decided to rename the second variable in comparison to the function author's intention&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstWord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondWord&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;veryImportantSelfContainedLogic&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;// has to follow the naming&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;firstWord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;anotherWord&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;veryImportantSelfContainedLogic&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;// or redefine it like so&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;firstWord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;anotherWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;secondWord&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;veryImportantSelfContainedLogic&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat, isn't it? ☀️&lt;/p&gt;

&lt;p&gt;Let me know in the comments if you see any downsides in supporting choiceful destructuring by default or if you're all in on the idea 🤓&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>functional</category>
    </item>
    <item>
      <title>The easiest way to extend or customize Create React App service worker without ejecting</title>
      <dc:creator>Michał Gacka</dc:creator>
      <pubDate>Sun, 06 Sep 2020 12:50:29 +0000</pubDate>
      <link>https://dev.to/3dayweek/the-easiest-way-to-extend-create-react-app-service-worker-without-ejecting-bfg</link>
      <guid>https://dev.to/3dayweek/the-easiest-way-to-extend-create-react-app-service-worker-without-ejecting-bfg</guid>
      <description>&lt;p&gt;Create React App (version before 4.0.0) by default includes a hidden Service Worker that will do some background magic for you in order for your app to be recognized as a Progressive Web Application. But if there's one pitfall of CRA, it's definitely how closed the configuration is and how difficult it is to modify / extend / customize it without ejecting (taking full control of the configuration) the application. Here, I discuss and present what I found to be the simplest way to extend the out-of-the-box service worker functionality.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;b&gt;EDIT&lt;/b&gt;: On the 23rd of October 2020 Create React App 4.0.0 has been released which simplifies the process of extending the default service worker immensely, so &lt;a href="https://dev.to/m3h0w/don-t-struggle-with-extending-the-service-worker-in-create-react-app-anymore-upgrade-to-version-4-3p2n"&gt;it might be a good idea to consider upgrading your project instead of using the workarounds I describe below&lt;/a&gt;. You can now just initialize the project by using the PWA template and it will generate the service worker file for you in the src folder which you can just add your custom code to. &lt;a href="https://create-react-app.dev/docs/making-a-progressive-web-app/" rel="noopener noreferrer"&gt;Check out the official instructions&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my case, for the purpose of adding a background process to take care of firebase messaging for push notifications but this trick should work in any other case as well.&lt;/p&gt;

&lt;p&gt;There's a multitude of articles trying to solve the problem but for some reason, most of them are overly complicated and are a pain to make them work in practice. That's because most of them overlook this wonderful utility: cra-append-sw. It lets you easily append the code you need to the existing service worker when building a production-ready app and also place a separate worker file in the public folder so you can register it yourself when running the development server.&lt;/p&gt;




&lt;p&gt;It's as simple as installing the package, creating the service worker file in your main folder ('firebase-messaging-sw.js' in my case), and modifying your package.json file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"start": "cra-append-sw --mode dev --env ./.env ./firebase-messaging-sw.js &amp;amp;&amp;amp; react-scripts start",
"build": "cra-append-sw --env ./.env ./firebase-messaging-sw.js &amp;amp;&amp;amp; react-scripts build",
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Also you need to remember to take care of registering the service worker when your application runs via a development server (CRA will only register its own service worker so in development, the separate file created in the public directory has to be registered separately). Here's a snippet out of my index.tsx file which is the entry point for my react application:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This is to make sure that when &lt;code&gt;cra-append-sw&lt;/code&gt; runs in dev mode (and thus generate the worker in the public folder instead of appending it to the react service worker) you register it manually.&lt;/p&gt;

&lt;p&gt;That should be all you need. Neat and simple in contrast to other hacky tools trying to accomplish the same.&lt;/p&gt;

&lt;p&gt;One of the hardest issues to solve with these pipelines I've found was how to use environment variables within the service worker in order to configure the firebase access key and other secret variables I had in my .env file. This solution solves it because the code is ran through the webpack pipeline before it's outputted both in the normal mode and the dev mode. Meaning you can access the &lt;code&gt;process.env&lt;/code&gt; object in your custom service worker code.&lt;/p&gt;

&lt;p&gt;I hope this saves you some pain and you live happily ever after with your new service worker functionality included in your Create React App.&lt;/p&gt;




&lt;p&gt;Additional notes &amp;amp; edits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As pointed out by &lt;a class="mentioned-user" href="https://dev.to/sjbuysse"&gt;@sjbuysse&lt;/a&gt; in the comments when &lt;code&gt;cra-append-sw&lt;/code&gt; runs in the production mode there is no reason to register the service worker manually. It is necessary though in the dev mode, thus the gist I appended from my &lt;code&gt;index.tsx&lt;/code&gt; file. I updated it now with a check for the environment to only run it in dev. Here's the relevant part from &lt;code&gt;cra-append-sw&lt;/code&gt; &lt;a href="https://www.npmjs.com/package/cra-append-sw" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev creates public/&amp;lt;file&amp;gt; instead of appending the code to build/service-worker.js
build creates build/&amp;lt;file&amp;gt; instead of appending the code to build/service-worker.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A little bit beyond the scope of the post but requested in the comments: &lt;a href="https://gist.github.com/m3h0w/b1d7b3c57d1c23c0d8d91a98a0d11b8d" rel="noopener noreferrer"&gt;the firebase-messaging-sw.js that I ended up using&lt;/a&gt;. It's a Frankenstein of some solutions I found online if I remember correctly but I can't find the sources now to credit them. Let me know in the comments if you recognize the gist ☀️&lt;/li&gt;
&lt;li&gt;As pointed out by &lt;a class="mentioned-user" href="https://dev.to/sjbuysse"&gt;@sjbuysse&lt;/a&gt; it might be necessary to pass your service worker registration object to the firebase messaging &lt;code&gt;getToken()&lt;/code&gt; options in production (when you append the firebase service worker to your CRA service worker) but for some reason it worked for me without it.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>cra</category>
      <category>javascript</category>
      <category>firebase</category>
    </item>
  </channel>
</rss>
