<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aurelio</title>
    <description>The latest articles on Forem by Aurelio (@aurelio).</description>
    <link>https://forem.com/aurelio</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%2F93284%2Fcce107c2-3ef4-4cc0-aa70-96dfc4fbeada.png</url>
      <title>Forem: Aurelio</title>
      <link>https://forem.com/aurelio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aurelio"/>
    <language>en</language>
    <item>
      <title>Lunch break talks #2: Things I wish I knew when I was younger</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Wed, 18 Nov 2020 22:16:17 +0000</pubDate>
      <link>https://forem.com/aurelio/lunch-break-talks-2-things-i-wish-i-knew-when-i-was-younger-35ji</link>
      <guid>https://forem.com/aurelio/lunch-break-talks-2-things-i-wish-i-knew-when-i-was-younger-35ji</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I like to watch talks during my lunch breaks, so I share some of the best ones I bump into, along with my notes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are at least 3 reasons why a talk from &lt;a href="https://en.wikipedia.org/wiki/Simon_Sinek" rel="noopener noreferrer"&gt;Simon Sinek&lt;/a&gt; is pretty much always worth your time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;He picks simple yet clever and entertaining topics&lt;/li&gt;
&lt;li&gt;He is a great motivator&lt;/li&gt;
&lt;li&gt;He's one of the best public speakers around. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See for yourself.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/p9gzGmyDJvc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  "See the bagel"
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Cafeteria tables, aligned next to each other and a long line of runners hoping to get a free bagel. So I said to my friend "Let's get a bagel".&lt;br&gt;
He looked at me and said "No man, the line is too long".&lt;br&gt;
And I looked at him and said: "It's a free bagel!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;2 ways you can see the world. You can see the thing you want, or you can see the thing standing in the way&lt;/li&gt;
&lt;li&gt;Focus on your goals, not on what's standing in the way&lt;/li&gt;
&lt;li&gt;If you focus on the end result, the obstacle is an opportunity for innovation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Perspective matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Interpret nerves as excitement. Same symptoms (heart beat, sweat etc), totally different mindset&lt;/li&gt;
&lt;li&gt;Being nervous (negative) vs being excited (positive)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Give yourself to your team members selflessly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The highest performing teams on the planet are not the strongest, not the strongest, not the fastest. They are the ones that &lt;strong&gt;give to each other selflessly&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;"You are here because someone took care of you and you have the responsibility to take care of others. This is the &lt;strong&gt;core of leadership&lt;/strong&gt;".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Listen first, speak last
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Be a great listener by allowing others to talk first&lt;/li&gt;
&lt;li&gt;Ensure they &lt;strong&gt;feel listened&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Great leaders don't start the conversation, they &lt;strong&gt;end it&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Practice to be the last to speak when you're part of a team&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Don't panic
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don't panic, so people around you stay calm&lt;/li&gt;
&lt;li&gt;We confuse moments of happiness with fulfilment &lt;/li&gt;
&lt;li&gt;Fulfilment is entirely different&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  "We all deserve a styrofoam cup"
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/p9gzGmyDJvc?t=1258" rel="noopener noreferrer"&gt;Hear the story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rewards and accolades are given not to you, but to the position you hold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8oxs762hzhrviwqnq3dl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8oxs762hzhrviwqnq3dl.jpg" alt="A styrofoam cup" width="640" height="431"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Bagel image is by &lt;a href="https://unsplash.com/@kreatedmedia" rel="noopener noreferrer"&gt;Kreated Media&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Cup image is by &lt;a href="https://unsplash.com/@chmarco" rel="noopener noreferrer"&gt;Marco Chilese&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>techtalks</category>
      <category>leadership</category>
      <category>motivation</category>
      <category>tips</category>
    </item>
    <item>
      <title>The #1 ingredient of a successful team</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Sun, 15 Nov 2020 22:43:07 +0000</pubDate>
      <link>https://forem.com/aurelio/the-1-ingredient-of-a-successful-team-2p31</link>
      <guid>https://forem.com/aurelio/the-1-ingredient-of-a-successful-team-2p31</guid>
      <description>&lt;p&gt;Have you ever wondered what makes a team a great one?&lt;br&gt;
I never did, until I had to create one. &lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe of a great team
&lt;/h2&gt;

&lt;p&gt;My first instinct would have been to hire just enough people and strive for a balance of various traits distributed across the members:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;good communication &lt;/li&gt;
&lt;li&gt;highly skilled&lt;/li&gt;
&lt;li&gt;drive to learn and improve&lt;/li&gt;
&lt;li&gt;positive attitude&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are certainly the traits that define a remarkable co-worker, but they are not telling me anything about the team dynamics that I should be striving for.&lt;br&gt;
So the question still stands, what makes a team a great one?&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's stand on the shoulders of giants and look for the answer
&lt;/h2&gt;

&lt;p&gt;As it often happens, it turns out I'm far from the first one to ask this question.&lt;br&gt;
In 2015 Google &lt;a href="https://apnews.com/article/8c60341cc1da47e084b8e17e62e83c98" rel="noopener noreferrer"&gt;published a research&lt;/a&gt; aimed at answering this exact same question.&lt;br&gt;
The result was in fact that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Who is on a team matters less than how the team members interact, structure their work, and view their contributions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In their research Google highlighted five dynamics that set successful teams apart from average ones, and the first of them is &lt;strong&gt;psychological safety&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Psychological Safety and why does it matter?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Psychological safety&lt;/strong&gt; was first theorised by Harvard Business School professor Amy Edmondson. &lt;br&gt;
In her book &lt;a href="https://www.amazon.com/gp/product/1119477247?ie=UTF8&amp;amp;tag=aurelio0b-20&amp;amp;camp=1789&amp;amp;linkCode=xm2&amp;amp;creativeASIN=1119477247" rel="noopener noreferrer"&gt;"The Fearless Organization: Creating Psychological Safety in the Workplace for Learning, Innovation, and Growth"&lt;/a&gt; she outlines the definition of this term and why it is the fundamental trait of successful teams.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have defined psychological safety as the belief that the work environment is safe for interpersonal risk taking&lt;/p&gt;

&lt;p&gt;-- Amy Edmonson, "The Fearless Organization: Creating Psychological Safety in the Workplace for Learning, Innovation, and Growth&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can define &lt;strong&gt;Psychological Safety&lt;/strong&gt; as the climate where anyone in the team feels &lt;strong&gt;free to speak up&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The traits of a psychologically safe environment
&lt;/h2&gt;

&lt;p&gt;How does one know if they are in a psychologically safe environment? Let's see what are the consequences we would see in such a team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's safe to ask for help&lt;/li&gt;
&lt;li&gt;Admitting mistakes is the norm&lt;/li&gt;
&lt;li&gt;Anyone can discuss existing problems&lt;/li&gt;
&lt;li&gt;New ideas are shared&lt;/li&gt;
&lt;li&gt;Learnings are shared&lt;/li&gt;
&lt;li&gt;Criticising a project is possible&lt;/li&gt;
&lt;li&gt;Raising issues with management is accepted, even when these issues come from the managers themselves&lt;/li&gt;
&lt;li&gt;Giving feedback to any other colleague is a regular occurrence&lt;/li&gt;
&lt;li&gt;Feedback is acted upon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr9y3ds1sf3pheu4a9k5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr9y3ds1sf3pheu4a9k5w.png" alt="The ingredients of Psychological Safety" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Psychological Safety is not
&lt;/h2&gt;

&lt;p&gt;Edmonson clarifies in her book and in many of her interviews what &lt;strong&gt;Psychological Safety&lt;/strong&gt; is not. I find this distinction very important to drive the idea in the right direction, as it might be easily misunderstood.&lt;br&gt;
Safety is not about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Being nice&lt;/li&gt;
&lt;li&gt;Being soft&lt;/li&gt;
&lt;li&gt;"Everything is great" attitude&lt;/li&gt;
&lt;li&gt;"Everything will work out" attitude&lt;/li&gt;
&lt;li&gt;Low ambition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And finally, safety is not a personality trait. It's a &lt;strong&gt;team trait&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Psychological Safety exist within a team?
&lt;/h2&gt;

&lt;p&gt;Psychological safety is a deliberate investment. It doesn't &lt;em&gt;happen&lt;/em&gt; by itself or by chance. It's not the result of the chemistry of the team members.&lt;/p&gt;

&lt;p&gt;It's the result of a proactive, continuous effort of the management and the team members to instil this value on a daily basis in the fibre of a team. Managers need to create an environment where making mistakes is accepted and talking about them is encouraged so much that it's the norm.&lt;/p&gt;

&lt;p&gt;A side effect of mistakes being surfaced frequently is that either new processes are created or existing ones are perfected. This constant &lt;strong&gt;rework of the status quo&lt;/strong&gt; is what sets great teams apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should invest in Psychological Safety?
&lt;/h2&gt;

&lt;p&gt;In one word: &lt;strong&gt;everyone&lt;/strong&gt;. And by everyone I mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Companies&lt;/strong&gt; as they will create a place where skilled and ambitious people want to be in and hence attract talent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managers&lt;/strong&gt; as they will build &lt;strong&gt;high performance teams&lt;/strong&gt; that deliver and are capable of overachieving&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Employees&lt;/strong&gt; as they will improve their career and discover new professional paths that would otherwise remain unknown to them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People looking for a new job&lt;/strong&gt; as they will want to understand their future team dynamics so they can find a place that match their ambitions, allow them to onboard faster and contribute quickly and effectively&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Looking back: an interesting game
&lt;/h2&gt;

&lt;p&gt;Once I learnt about Psychological Safety, I started playing a game in my head. &lt;br&gt;
Of all my past teams, can I rate how psychologically safe those places were?&lt;br&gt;
Unsurprisingly, the teams that scored higher were also the ones where I learnt the most and felt that I could make an impact.&lt;/p&gt;

&lt;p&gt;What about you? How did your past team or your current one score?&lt;/p&gt;




&lt;p&gt;Cover image by &lt;a href="https://unsplash.com/@clarephotolover" rel="noopener noreferrer"&gt;Clarissa Watson&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Should my small team really, really, really do code reviews?</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Fri, 06 Nov 2020 22:41:03 +0000</pubDate>
      <link>https://forem.com/aurelio/should-my-small-team-really-really-really-do-code-reviews-35gf</link>
      <guid>https://forem.com/aurelio/should-my-small-team-really-really-really-do-code-reviews-35gf</guid>
      <description>&lt;p&gt;While nearly everyone on paper agrees that code reviews are &lt;em&gt;"a good thing"&lt;/em&gt; and everyone should do them, the reality often tells a different story. &lt;/p&gt;

&lt;p&gt;Big teams and companies all pretty much have a code review process in place. On the other hand, small startups often skip this step, especially at the early stages of their life.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: If you're short of time feel free to skip at the last section and get a quick list of to-dos.&lt;br&gt;
(And by the way, the answer to the question in the title is &lt;strong&gt;yes&lt;/strong&gt;)&lt;/p&gt;




&lt;h2&gt;
  
  
  When you shouldn't do code reviews
&lt;/h2&gt;

&lt;p&gt;Or rather, how people justify their team skipping reviews.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code reviews slow us down&lt;/li&gt;
&lt;li&gt;We're all senior developers, we trust each other&lt;/li&gt;
&lt;li&gt;We will start code reviews as soon as it makes sense&lt;/li&gt;
&lt;li&gt;We're only 2 developers, why should we?&lt;/li&gt;
&lt;li&gt;It's a quick change, it's ok&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you recognise yourself in one or more of the above statements, I hope this post will convince you to reconsider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's talk about code quality
&lt;/h2&gt;

&lt;p&gt;Code reviews are one of the best way to favour accountability and "good quality code". If done right, they can be better than any linting tool, code style guide or automated process.&lt;/p&gt;

&lt;p&gt;Having someone proof read what we type helps us keeping our standards higher. Even a seasoned developer can slip sloppy code in the codebase when tired, be it consciously or by mistake.&lt;br&gt;
But code quality comes at a cost, and the money used to pay for it is one of the most valuable currencies for a startup: &lt;strong&gt;time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It seems commonly accepted that doing things right is slower than doing them worse.&lt;br&gt;
Martin Fowler talks about this in his article &lt;a href="https://martinfowler.com/articles/is-quality-worth-cost.html" rel="noopener noreferrer"&gt;"Is High Quality Software Worth the Cost?"&lt;/a&gt;. He mentions something interesting for us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Developers find poor quality code significantly slows them down &lt;strong&gt;within a few weeks&lt;/strong&gt; [&lt;em&gt;emphasis mine&lt;/em&gt;]. So there's not much runway where the trade-off between internal quality and cost applies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7kv3anjgcyvctoxjzhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7kv3anjgcyvctoxjzhk.png" alt="Code quality increases velocity" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this chart is taken from Fowler's &lt;a href="https://martinfowler.com/articles/is-quality-worth-cost.html" rel="noopener noreferrer"&gt;article&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If we agree on Mr Fowler's take we can see that "good code" pays off very quickly, even at very early stages.&lt;br&gt;
Higher quality means higher velocity, and this is true earlier than many seem to realise.&lt;/p&gt;

&lt;p&gt;While the first lines of a new codebase are often seen as something temporary ("it's only a prototype after all"), the reality is that those lines will influence the speed of development very early on. In a few weeks this advantage will very likely be noticeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to review
&lt;/h2&gt;

&lt;p&gt;When it comes to code reviews, sometimes the question arises about &lt;strong&gt;what exactly to review&lt;/strong&gt;. From what we've seen so far it's perhaps clear that my suggestion is that every new piece of functionality or any meaningful change should go through code review from day 1.&lt;br&gt;
But what about &lt;strong&gt;very small changes&lt;/strong&gt;? What about a quick readme update?&lt;/p&gt;

&lt;p&gt;I keep it simple, &lt;strong&gt;do code review absolutely everything&lt;/strong&gt;. Every single PR should be peer reviewed. And yes, this "unfortunately" means no pushing to straight to master, no "this is a quick one" PRs that go in unreviewed.&lt;/p&gt;

&lt;p&gt;Sounds harsh? Maybe. But it's very hard to draw a line of what exactly is a meaningful change and what is a trivial one. Is a 200 lines indentation tweak worth more or less than a 1 line change in the models of your application? Even a readme update can contain misleading information or be based off wrong assumptions. And if we allow very small changes to go through by skipping review, what's the threshold that divides what's to be reviewed from what's not? How do you explain this to the next dev joining?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If it's a quick change, it will also be very quick to review&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  But, but... this slows me down!
&lt;/h2&gt;

&lt;p&gt;I hear you. Yes. You're pushing a one-liner and I'm telling you that you need to wait 2 hours, or even a day for someone else to review it.&lt;br&gt;
I agree, this is &lt;strong&gt;unacceptable&lt;/strong&gt;. And that's why having &lt;strong&gt;prompt reviews&lt;/strong&gt; should be a top concern of your team processes.&lt;/p&gt;

&lt;p&gt;We're in a small startup and speed is everything. Well, it turns out, speed is everything at massive scales, too.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At Google, we optimize for the speed at which a team of developers can produce a product together, as opposed to optimizing for the speed at which an individual developer can write code&lt;/p&gt;

&lt;p&gt;-- From &lt;a href="https://google.github.io/eng-practices/review/reviewer/speed.html" rel="noopener noreferrer"&gt;Google Engineering Practices Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are the guidelines from Google:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are not in the middle of a focused task, you should do a code review shortly after it comes in.&lt;/li&gt;
&lt;li&gt;One business day is the maximum time it should take to respond to a code review request (i.e. first thing the next morning).&lt;/li&gt;
&lt;li&gt;Following these guidelines means that a typical PR should get multiple rounds of review (if needed) within a single day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your startup is fast, your reviewers should be too.&lt;br&gt;
If you're looking for a nifty tool to automatically track how fast your team is I suggest &lt;a href="https://codeclimate.com/velocity/act-optimize/" rel="noopener noreferrer"&gt;Velocity&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How thorough should your reviews be?
&lt;/h2&gt;

&lt;p&gt;Reviews don't mean quickly scrolling through dozens lines of code and pressing "approve", perhaps adding a thumbs up to add a human touch to it.&lt;br&gt;
It's very important to &lt;strong&gt;actually read and understand the code&lt;/strong&gt;. If we are always very permissive we will get sloppy and just let anything go in. If you - on the contrary -  make a habit of reading critically and making an effort to understand what's going on, then it will get normal to ask questions and clarifications on many PRs.&lt;/p&gt;

&lt;p&gt;This will make commenting a part of the daily routine of the company. When it'll be time to be more critical regarding an approach taken in code it will be less likely to cause a stir or be a source of litigation.&lt;/p&gt;

&lt;p&gt;Reading the code also means that &lt;strong&gt;knowledge spreads faster within the team&lt;/strong&gt;. Code reviews are not just about code quality, they are also about knowing what's happening around the codebase while you're not looking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the code, and understand it&lt;/strong&gt;. If you don't, &lt;strong&gt;ask questions&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should be assigned to reviews?
&lt;/h2&gt;

&lt;p&gt;In super small teams this is a non issue, you don't have much of a choice.&lt;br&gt;
When the team grows, the question of who should review might arise.&lt;br&gt;
In my view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many assignees are better than fewer&lt;/li&gt;
&lt;li&gt;Aim for at least 2 reviewers, if the team's size allows. Look at how you can make this a policy with Github's &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuring-protected-branches" rel="noopener noreferrer"&gt;protected branches&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Also &lt;strong&gt;have junior devs do review&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;I repeat, &lt;strong&gt;have junior devs do reviews&lt;/strong&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to make assigning people faster, you can use Github's &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-code-owners" rel="noopener noreferrer"&gt;codeowners&lt;/a&gt; that will automatically assign for you. Open a PR and you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  One extra tip: comment your own PRs
&lt;/h2&gt;

&lt;p&gt;Adding comments to a PR should not be limited to other people's PRs. You can add comments to your own ones as well.&lt;br&gt;
I'm not the only one doing this and I find it really helpful when someone does it.&lt;/p&gt;

&lt;p&gt;You can anticipate questions, explain why you've taken a certain approach, tell the reader that you already have a follow-up PR in mind.&lt;br&gt;
This, again, will make reviews faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  In short
&lt;/h2&gt;

&lt;p&gt;I hope by now I convinced you that code reviews are an investment that have short and long time benefits that even an early stage startup should consider.&lt;br&gt;
Here's a quick list of action items for the busy ones and a recap for everyone who read so far.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do code reviews from day 1&lt;/li&gt;
&lt;li&gt;Review every single change, no matter how trivial&lt;/li&gt;
&lt;li&gt;Require "Pull request reviews before merging". See how on &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuring-protected-branches" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-code-owners" rel="noopener noreferrer"&gt;codeowners&lt;/a&gt; so you don't have to waste time picking reviewers.&lt;/li&gt;
&lt;li&gt;Strive for fast code review turn arounds. Maximum waiting time should be one day, but preferably it should be quantified in minutes. Read &lt;a href="https://google.github.io/eng-practices/review/reviewer/speed.html" rel="noopener noreferrer"&gt;how Google does it&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can track your team's speed and impact of code review by using tools like &lt;a href="https://codeclimate.com/velocity/act-optimize/" rel="noopener noreferrer"&gt;Velocity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Be thorough when reviewing, understand what you're reading. Avoid giving thumbs up to absolutely everything, without reading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cover image by Thom Milkovic on &lt;a href="https://unsplash.com/photos/qGQIOLke2kE" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>startup</category>
    </item>
    <item>
      <title>How I remember everything I learn</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Sun, 01 Nov 2020 00:03:17 +0000</pubDate>
      <link>https://forem.com/aurelio/how-i-remember-everything-i-learn-19mi</link>
      <guid>https://forem.com/aurelio/how-i-remember-everything-i-learn-19mi</guid>
      <description>&lt;p&gt;Have you ever been asked this question: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt; If you could have just one superpower, which one would you choose?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's one of those questions that can either leave you frozen without any actual clue what to say or you might catch yourself with so many ideas that you're simply overwhelmed by the abundance of options.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Unrelated: the most clever answer to this question I've read is &lt;a href="https://qr.ae/pNboqr" rel="noopener noreferrer"&gt;this one&lt;/a&gt; by the way.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fczpskp44c6rp78opbgl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fczpskp44c6rp78opbgl7.png" alt="Screenshot from a Quora answer" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(not a bad idea, right?)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;There's no right or wrong of course, but if you asked me, my answer would be something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I would be able to remember &lt;strong&gt;everything&lt;/strong&gt; I learn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don't know about you, but &lt;strong&gt;knowledge retention&lt;/strong&gt; is easily one the big challenges of my life. I read blogs every day, I watch countless videos, I start (and sometimes finish) a few technical books per year and remembering everything I learnt is outright &lt;strong&gt;unrealistic&lt;/strong&gt;.&lt;br&gt;
There's just so much one can retain of what they read or hear.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I tried
&lt;/h2&gt;

&lt;p&gt;If you're like me, you've tried them all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blogging about it&lt;/li&gt;
&lt;li&gt;highlighting the most important sentences of the books you read&lt;/li&gt;
&lt;li&gt;taking physical notes&lt;/li&gt;
&lt;li&gt;taking notes online (eg Evernote)&lt;/li&gt;
&lt;li&gt;writing summaries of the books and videos you read&lt;/li&gt;
&lt;li&gt;flash cards&lt;/li&gt;
&lt;li&gt;semi-organised (or semi-random), heavy bookmarking with tools like Pocket&lt;/li&gt;
&lt;li&gt;you name it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these methods have their merits. All of them ultimately &lt;strong&gt;fall short&lt;/strong&gt; for me.&lt;br&gt;
Some worked better than others but I couldn't for the life of me stick to one.&lt;/p&gt;

&lt;h2&gt;
  
  
  An impossible balance
&lt;/h2&gt;

&lt;p&gt;I felt I was somehow looking for an &lt;strong&gt;impossible balance&lt;/strong&gt;. I wanted a solution that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;was structured...&lt;/li&gt;
&lt;li&gt;...but still loose enough so it didn't kill my creativity and the free flow of thoughts that happens when learning something new&lt;/li&gt;
&lt;li&gt;searchable&lt;/li&gt;
&lt;li&gt;low friction, as in, easy to type in, giving me a pleasant, natural experience&lt;/li&gt;
&lt;li&gt;non-existent learning curve (no "new revolutionary tools"). Sorry, I'm busy leaning something else&lt;/li&gt;
&lt;li&gt;easily retrievable, available anywhere&lt;/li&gt;
&lt;li&gt;recoverable if a disaster happens (think about forgetting your notebook on a train, or having it chewed by your dog)&lt;/li&gt;
&lt;li&gt;trackable, I wanted to be able to see my progress through the months, and possibly get some stats, if not for vanity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Turning point
&lt;/h2&gt;

&lt;p&gt;I was resigned to never find a solution for it.&lt;br&gt;
Until one day, I randomly bumped into &lt;a href="https://lobste.rs/s/ord0rg/does_anyone_else_keep_their_own_knowledge" rel="noopener noreferrer"&gt;this&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ve been extending and improving my &lt;a href="https://github.com/nikitavoloboev/knowledge" rel="noopener noreferrer"&gt;personal wiki&lt;/a&gt; for 1 year now and it has been one of the best things I’ve done. I found writing blog posts was too high friction and very often didn’t finish things because there is so much you can talk about in any given article. But a wiki is just a living document containing your notes and thoughts on things. I also use it as my public bookmark manager as I collect interesting to me links under each topic.&lt;/p&gt;

&lt;p&gt;For my wiki, I render everything to the web first with GitBook. And I have a macro I run that automatically commits any changes I’ve made with Sublime Text on the mac and Ulysses on the phone so everything is super easy to edit and publish.&lt;/p&gt;

&lt;p&gt;Does anyone else keep their own wiki here? Or you think a blog is enough for you?&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://github.com/nikitavoloboev" rel="noopener noreferrer"&gt;Nikita Volobev&lt;/a&gt; on &lt;a href="https://lobste.rs/" rel="noopener noreferrer"&gt;Lobsters&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And there it was. The sign that the "impossible balance" &lt;strong&gt;was actually possible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From that moment, around 2 years ago, I also created &lt;a href="https://github.com/nobitagit/knowledge" rel="noopener noreferrer"&gt;my own personal wiki&lt;/a&gt; and it's been my go-to tool for remembering everything I learn.&lt;/p&gt;

&lt;p&gt;It's nothing more than a repo on Github, divided in folders with a bunch of READMEs in each of them.&lt;br&gt;
Folders are the main categories, such as databases, Kubernetes, JavaScript, security, regex etc. Each README inside them subdivide the folder into specific topics. Security would have READMEs for JWT, Frontend, Cryptography etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evolution
&lt;/h2&gt;

&lt;p&gt;I initially started with only programming topics but found myself using the wiki to store notes about literally anything I learn in any domain such as music, writing, managing, speaking and writing German.&lt;/p&gt;

&lt;p&gt;The structure is not super strict, but still provide some order and thanks to Github searching is absolutely a breeze.&lt;/p&gt;

&lt;p&gt;Since everything is committed, I wrote a small Go program to calculate some stats by accessing the git history and generate an HTML page. A Github action runs the script and publishes it to a URL. The page looks - let's say - minimal (it has literally 3 lines of CSS), but it gives me an overview of what I have been learning in the past 90 days. Apparently I've been very much into career development and management as of late.&lt;/p&gt;

&lt;h2&gt;
  
  
  Giving it a try
&lt;/h2&gt;

&lt;p&gt;I strongly recommend giving this method a try if you're also struggling with knowledge retention.&lt;br&gt;
The investment to start is so low, you literally only need to create a repo and that's it, and you can even fork mine and simply delete most of the folders if you like.&lt;/p&gt;

&lt;p&gt;Nikita and I are not the only ones using this method. You can find plenty others for inspiration by going through &lt;a href="https://github.com/RichardLitt/meta-knowledge" rel="noopener noreferrer"&gt;this long list of wikis&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/@osmanrana" rel="noopener noreferrer"&gt;Osman Rana&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>learning</category>
      <category>tips</category>
    </item>
    <item>
      <title>$ considered harmful</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Sat, 04 Jul 2020 05:23:38 +0000</pubDate>
      <link>https://forem.com/aurelio/considered-harmful-2fid</link>
      <guid>https://forem.com/aurelio/considered-harmful-2fid</guid>
      <description>&lt;p&gt;One of the most satisfying feelings in life is waking up at 5am, going to the kitchen to drink a glass of water while casually scrolling through Twitter on your phone and finding someone (on the Twitter feed, not in the kitchen) that is right on the internet*:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277199020268703744-208" src="https://platform.twitter.com/embed/Tweet.html?id=1277199020268703744"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277199020268703744-208');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277199020268703744&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;em&gt;* Where right means: someone else is saying something you always thought of, but never quite found time/space/willpower/occasion to express to a wider audience or even to yourself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9hbwbe4ej5shyzw7nand.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9hbwbe4ej5shyzw7nand.jpg" alt="Morning duties" width="300" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Let's begin with a disclaimer: this is a clear case of first world problem that really has no great meaning in the grand scheme of things, and the arguments against it are still valid. I just found it amusing to see I wasn't really the only one being mildly frustrated by it.&lt;/p&gt;

&lt;p&gt;I also think that the discussion that ensued is interesting and worth reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;When setting up a project you might need some setup and most of the times this involves running a handful of shell command.  An example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
$ pyenv install 3.7.6
$ pyenv local 3.7.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now try copy pasting those 3 lines in one go... Chances are you will see as output something 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;zsh: command not found: $
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isn't this irritating?&lt;/p&gt;

&lt;h2&gt;
  
  
  What does &lt;code&gt;$&lt;/code&gt; even mean
&lt;/h2&gt;

&lt;p&gt;There are a few reasons why &lt;code&gt;$&lt;/code&gt; is prepended to every line of a shell command example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it indicates that indeed, what you are looking at is a command that is meant to be run in a shell&lt;/li&gt;
&lt;li&gt;It indicates that you need to run this command as a user, and not as root&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why you should &lt;strong&gt;not&lt;/strong&gt; remove &lt;code&gt;$&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Some valid arguments in favour of keeping the $:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should never trust commands on the internet and blindly copy paste them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277464720728035331-36" src="https://platform.twitter.com/embed/Tweet.html?id=1277464720728035331"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277464720728035331-36');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277464720728035331&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should communicate when to run a command a root (using &lt;code&gt;#&lt;/code&gt;) and when not (&lt;code&gt;$&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277201037321998338-336" src="https://platform.twitter.com/embed/Tweet.html?id=1277201037321998338"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277201037321998338-336');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277201037321998338&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  The case for removing &lt;code&gt;$&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;makes it harder to copy, especially multiline commands&lt;/li&gt;
&lt;li&gt;not everyone might be aware of # meaning "run as root"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the  thread another user makes an great point&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277990481884901376-850" src="https://platform.twitter.com/embed/Tweet.html?id=1277990481884901376"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277990481884901376-850');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277990481884901376&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  How to remove &lt;code&gt;$&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If you have read so far and sort of agree that we might be better off not including the &lt;code&gt;$&lt;/code&gt; in shell samples, here's a few ways to make it happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  The easy way
&lt;/h3&gt;

&lt;p&gt;Just don't type it! This applies to Github and pretty much all places where you have no control over how code samples are rendered. A post on Dev.to is one example.&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 shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.7.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.7.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if a command is meant to be run as root prepend it with sudo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ubuntu-desktop  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The stylish way
&lt;/h3&gt;

&lt;p&gt;If you have control over the rendering and you still like you readers to see the &lt;code&gt;$&lt;/code&gt;, consider using CSS to remove it from the text that ends up in the clipboard when copying. In the thread, Twitter user &lt;a href="%C2%A0%20https://twitter.com/beccadottex"&gt;@beccadottex&lt;/a&gt; shares a &lt;a href="https://codepen.io/rebeccajae/pen/PoZJwav" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt; of how this can be done. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/theconfigurator" rel="noopener noreferrer"&gt;@theconfigurator&lt;/a&gt; shares another one here &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277279975654281216-111" src="https://platform.twitter.com/embed/Tweet.html?id=1277279975654281216"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277279975654281216-111');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277279975654281216&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you really stop using $?
&lt;/h2&gt;

&lt;p&gt;As any other opinion based topic, there seems to be far from an agreement on the best practice around this, as the long thread on Twitter shows. &lt;/p&gt;

&lt;p&gt;As for myself, I always found it redundant and pointless but funnily enough &lt;a href="https://dev.to/aurelio/up-your-lodash-game-by-going-functional-from-chaining-to-piping-3li8"&gt;I found myself using it out of habit&lt;/a&gt;. From now on, I will purposefully keep the &lt;code&gt;$&lt;/code&gt; out of my docs.&lt;/p&gt;

&lt;p&gt;/rant&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;em&gt;comic at the beginning is a ripoff of Xkcd's &lt;a href="https://xkcd.com/386/" rel="noopener noreferrer"&gt;Duty Calls&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;cover image is by &lt;a href="https://unsplash.com/@ryanquintal" rel="noopener noreferrer"&gt;Ryan Quintal&lt;/a&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>shell</category>
    </item>
    <item>
      <title>D3: a JS library for the next 10 years?</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Wed, 29 Apr 2020 07:18:56 +0000</pubDate>
      <link>https://forem.com/aurelio/d3-a-js-library-for-the-next-10-years-4pd8</link>
      <guid>https://forem.com/aurelio/d3-a-js-library-for-the-next-10-years-4pd8</guid>
      <description>&lt;p&gt;D3 has been the go-to library for in browser data visualisation for many years by now.&lt;br&gt;
While JavaScript libraries are notorious for being extremely transient and easily replaced by newer, shinier alternatives, for some reason this does not seem to apply to D3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some history
&lt;/h2&gt;

&lt;p&gt;The first published version I can trace by searching between npm and Github releases is &lt;a href="https://github.com/d3/d3/releases?after=v1.29.2" rel="noopener noreferrer"&gt;1.24.1&lt;/a&gt; which is dated 2nd July 2011, although the first version ever seems to be from February that year, i.e. &lt;strong&gt;over 9 years ago&lt;/strong&gt; at the time of writing. This means we're closing in to the first decade of d3.&lt;br&gt;
In the JavaScript world this is probably the human equivalent of a century ago.&lt;/p&gt;

&lt;p&gt;To give a bit of perspective, Backbone was created around that time, and so was AngularJS version 1.x (remember &lt;code&gt;$scope.apply()&lt;/code&gt;?)&lt;br&gt;
The JavaScript ecosystem has completely changed during this time, in terms of libraries, best practices and even language features.&lt;/p&gt;

&lt;p&gt;Nevertheless, D3 is still here. And &lt;strong&gt;it's more popular than ever&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Present
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7unk9yroenasuwizbw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7unk9yroenasuwizbw9.png" alt="D3 on Npmtrends" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This chart is taken from &lt;a href="https://www.npmtrends.com/d3-vs-chart.js-vs-highcharts" rel="noopener noreferrer"&gt;Npmtrends&lt;/a&gt; and shows the last 5 years of npm downloads of D3 compared to Chart.js and Highcharts.&lt;br&gt;
D3 emerges as a clear winner, and this is not even considering the fact that many users are not downloading the full library (the entire d3 package), but only some of its modules, such as d3-array, or d3-scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  6 reasons for the long-lasting success of D3
&lt;/h2&gt;

&lt;p&gt;I can think of a few reasons why D3 is yet to be replaced by an alternative. In my view, they actually make it unlikely to be replaced any time soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stable
&lt;/h3&gt;

&lt;p&gt;The biggest API change in D3 happened during the major upgrade from 3 to 4 as far as I know. From there on, the api has been pretty much the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thoroughly tested
&lt;/h3&gt;

&lt;p&gt;D3 has an excellent test coverage and has been used in production for years now by thousands of developers. In fact D3 is almost...&lt;/p&gt;

&lt;h3&gt;
  
  
  Bug free
&lt;/h3&gt;

&lt;p&gt;Ok, this is an exaggeration. There's no such thing as a program with no bugs, and D3 is no exception.&lt;br&gt;
Still, the number of issues is very limited, especially compared to competing charting libraries that have hundreds of open/unresolved issues.&lt;/p&gt;

&lt;p&gt;This is a screenshot of the D3's main repo on Github, with a whopping 3 open issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxwgzql7n81wabf3c0lt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxwgzql7n81wabf3c0lt.png" alt="Issues on D3's main repo" width="800" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Actively maintained
&lt;/h3&gt;

&lt;p&gt;You can look at the latest version publish, or the &lt;a href="https://github.com/d3/d3/commit/7244e45e68af39c519f76667a03039d5b24dd453" rel="noopener noreferrer"&gt;latest commit on Github&lt;/a&gt;, or the planned features in the roadmaps. This makes it clear that the idea is to go on and keep D3 up to date and in line with modern JS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modular build
&lt;/h3&gt;

&lt;p&gt;One of the biggest criticisms towards D3 has historically been its staggering size. For years, including D3 on a page meant adding a great amount of kBs to your page. Since version 4 the library has been split into several standalone, dedicated modules. This means that you can include in your bundle only those part of the library that you actually leverage in your code.&lt;/p&gt;

&lt;p&gt;The improvement in terms of size is remarkable. Let's visualise what this means. Here's the &lt;a href="https://bundlephobia.com/result?p=d3@3.5.17" rel="noopener noreferrer"&gt;composition of d3 version 3.5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhnfe28kvdf5p0x3qc9j3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhnfe28kvdf5p0x3qc9j3.png" alt="composition of d3 version 3.5" width="800" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case adding D3 for a simple bar chart meant including totally unrelated stuff like functions to draw map projects (d3-geo), parsers and formatters for dates in a variety of locale-specific implementations, force layout helpers... In short, a lot of potentially useless code was added to the bundle.&lt;/p&gt;

&lt;p&gt;Let's compare it to &lt;a href="https://bundlephobia.com/result?p=d3@5.16.0" rel="noopener noreferrer"&gt;the 5.x version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6w8zmhic9wtubzbljqh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6w8zmhic9wtubzbljqh1.png" alt="d3 5.x version composition" width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that nowadays we can install only what's needed for the specific visualisation and leave the rest of D3 out of the bundle.&lt;/p&gt;




&lt;p&gt;All these are valid points but wouldn't suffice to explain why D3 is still a relevant, desirable choice for anyone making visualisation. The missing one is...&lt;/p&gt;

&lt;h3&gt;
  
  
  Philosophy
&lt;/h3&gt;

&lt;p&gt;This is in my opinion the single most important reason of the list, and it's where all of the points above really come together in shaping a great library that will - in my opinion - stand the test of time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;D3 is not a Data Visualization Library&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://medium.com/@Elijah_Meeks/d3-is-not-a-data-visualization-library-67ba549e8520" rel="noopener noreferrer"&gt;Elijah Meeks&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;D3 is not really a charting library&lt;/strong&gt;, it doesn't even have the concept of a chart. Rather, its goal is to provide the most common primitives to perform any type of mapping, mathematical operation or analysis on data. Like Lodash is the de-facto standard when it comes to data manipulation, D3 is the obvious choice when dealing with data analysis.&lt;/p&gt;

&lt;p&gt;In short, no matter how JS will evolve, you'll still need to do the same computations to draw charts and to map raw data to x and y coordinates, or to easily map a range of values to a range of colours.&lt;/p&gt;

&lt;p&gt;The basics of data visualisation and how to perform mathematical calculations are not going to change any time soon.&lt;br&gt;
Since D3 operates at that low level, and in such a modular way, the reasons to find or even write an alternative library are very limited and not compelling enough.&lt;/p&gt;

&lt;p&gt;For me, this fundamental approach is what sets D3 apart from any other solution out there, and the key reason for the long-lasting success of the library.&lt;/p&gt;

&lt;p&gt;A lot of people seem not to be big fans of how D3 handles updating DOM (look at d3-selection) and it certainly can be quite intimidating. I am not going to discuss here about the D3 DOM api, or give any personal opinion, but again, the modularity of D3 means that you can always swap its selection methods with view libraries like React or Vue, and use D3 for calculation.&lt;/p&gt;

&lt;p&gt;Some library authors have decided to do just that. Two examples of this approach are &lt;a href="https://github.com/FormidableLabs/victory/blob/b137e4aa3285c6646c83c507673842b545b26df4/packages/victory-core/package.json#L22-L26" rel="noopener noreferrer"&gt;Victory&lt;/a&gt; and &lt;a href="https://github.com/hshoff/vx/blob/master/packages/vx-hierarchy/package.json#L82" rel="noopener noreferrer"&gt;VX&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In conclusion, I think D3 is unlikely to be superseded by an alternative and, by the looks of it, it will remain the de-facto standard for the foreseeable future.&lt;br&gt;
This does not mean it's perfect and that it comes with no disadvantages (one for all, the steep learning curve) but it's certainly still very much relevant, if not more than it ever was.&lt;/p&gt;

&lt;p&gt;It also does not mean that every one that needs to draw a chart on a page need to learn it. But if you're serious about data visualisation and want to have full freedom when it comes to plotting data in a browser then &lt;strong&gt;D3 is arguably going to be your best bet&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Cover Image: &lt;a href="https://unsplash.com/@qrenep" rel="noopener noreferrer"&gt;Rene Bohmer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>d3</category>
      <category>dataviz</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Lunch break talks #1: Simplicity is complicated</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Wed, 27 Nov 2019 13:59:41 +0000</pubDate>
      <link>https://forem.com/aurelio/lunch-break-talks-1-simplicity-is-complicated-43nd</link>
      <guid>https://forem.com/aurelio/lunch-break-talks-1-simplicity-is-complicated-43nd</guid>
      <description>&lt;p&gt;I sometimes like to watch a talk during my lunch breaks, so I decided to share some of the best ones I bump into, along with my notes.&lt;br&gt;
I try to keep the topics fairly language agnostic (after all it's a lunch break). &lt;/p&gt;

&lt;p&gt;In this case the talk is from &lt;a href="https://en.wikipedia.org/wiki/Rob_Pike" rel="noopener noreferrer"&gt;Rob Pike&lt;/a&gt;, one of the creators of &lt;strong&gt;Go&lt;/strong&gt;. It still resonates with me, even if I am writing JavaScript pretty much all day. Simplicity is a goal at any level you're writing (not just when writing a language!) and it is a hard thing to achieve.&lt;/p&gt;

&lt;p&gt;I really like that Rob Pike makes everyone think about how hard it is to architect the grammar of a language, and how hard it is to take decisions and make tradeoffs when designing a new one. Funny how just a few days ago I was wondering why Go was not providing a filter or map method for arrays or slices, and he actually answers it during this talk.&lt;/p&gt;

&lt;p&gt;Such an inspiring video that I think every programmer should see, even if not interested in Go! &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rFejpH_tAHM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;My key key take aways:&lt;/p&gt;

&lt;h2&gt;
  
  
  New features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;a lot of languages are adding new features (coff... coff.. JavaScript...)&lt;/li&gt;
&lt;li&gt;a lot of this new features are the same ones across languages&lt;/li&gt;
&lt;li&gt;these languages are starting to look very similar one another&lt;/li&gt;
&lt;li&gt;if programmers use very similar languages, they will start to all think the same way&lt;/li&gt;
&lt;li&gt;in reality, what you ideally want, is a language that is &lt;strong&gt;very good at solving domain specific problems&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Complexity
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;more features equals more complexity &lt;/li&gt;
&lt;li&gt;Go has added a very small set of features&lt;/li&gt;
&lt;li&gt;how to pick the right feature to add? By &lt;a href="https://youtu.be/rFejpH_tAHM?t=263" rel="noopener noreferrer"&gt;picking only the right ones&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Readability
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;more features means more time spent thinking about &lt;strong&gt;how&lt;/strong&gt; to write something&lt;/li&gt;
&lt;li&gt;ideally you want a language to allow for &lt;a href="https://youtu.be/rFejpH_tAHM?t=371" rel="noopener noreferrer"&gt;one way - or at least not many ways - of writing a thing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;a smaller feature set makes it more maintainable in the long run&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Simplicity
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;a lot of thinking has to be put to achieve simplicity&lt;/li&gt;
&lt;li&gt;GC is one example of it in Go. A very difficult feature to implement that is 100% hidden from the end user, or even from the spec&lt;/li&gt;
&lt;li&gt;the interface to the user might be simple, even the implementation in the language might be simple, but the design of a feature is very likely to be a long, difficult process&lt;/li&gt;
&lt;li&gt;a lot of complexity might lie behind very simple code. He makes a fantastic walkthrough of a simple server written in Go and what's happening behind the scenes &lt;a href="https://youtu.be/rFejpH_tAHM?t=1266" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bottom line is, &lt;strong&gt;simplicity is hard to get&lt;/strong&gt;, but - if you get it right - makes doing complicated things easy to achieve for your users.&lt;/p&gt;

</description>
      <category>techtalks</category>
      <category>computerscience</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Working with environments in Postman</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Wed, 30 Oct 2019 13:27:44 +0000</pubDate>
      <link>https://forem.com/aurelio/working-with-environments-in-postman-4bcm</link>
      <guid>https://forem.com/aurelio/working-with-environments-in-postman-4bcm</guid>
      <description>&lt;p&gt;Postman is one my favourite tools at work to test APIs.&lt;br&gt;
Even at a simple level Postman easily becomes invaluable. At the same time, devoting a little effort in learning some of its best features can quickly boost our productivity and development speed.&lt;/p&gt;

&lt;p&gt;One of my favourite aspects of working with Postman is its &lt;strong&gt;environments&lt;/strong&gt; feature.&lt;/p&gt;
&lt;h2&gt;
  
  
  Life without Postman environments
&lt;/h2&gt;

&lt;p&gt;Before explaining what an &lt;strong&gt;environment&lt;/strong&gt; is in the context of Postman, I'd like to list a couple of the most common scenarios I face when working with an API.&lt;br&gt;
This will make it easier to understand &lt;em&gt;why&lt;/em&gt; and &lt;em&gt;when&lt;/em&gt; environments are useful.&lt;/p&gt;

&lt;p&gt;One of the most common cases is having to hit an endpoint that requires some sort of authentication.&lt;br&gt;
Say, for example, that we are hitting &lt;code&gt;http://localhost:3000/users&lt;/code&gt; to retrieve a list of users that are registered on our platform.&lt;br&gt;
The server expects the user that performs the call to be authenticated to make this call. To accomplish this a client may expect to pass a token as part of the request, say as an entry in the headers in the form of a JWT token.&lt;/p&gt;

&lt;p&gt;The easiest way to do that is to first hit our authentication endpoint (for instance &lt;code&gt;http://localhost/auth&lt;/code&gt;), passing a username and password, inspect the response on the Postman UI and manually copy this token. We would then be able to paste this token as a header for future requests, such as the above example to request the list of users.&lt;/p&gt;

&lt;p&gt;While this works, it becomes tedious quickly as we will need to paste the token in every new tab we create on Postman. Moreover, every time our token expires, we will have to repeat the process of hitting the auth endpoint, and copying our new token.&lt;/p&gt;

&lt;p&gt;Let's see how we can avoid this manual setup thanks to Postman.&lt;/p&gt;
&lt;h2&gt;
  
  
  Learn how to work with environments
&lt;/h2&gt;

&lt;p&gt;As you will see, environments are a very powerful feature to stay organised in Postman and to make our workflow much faster and portable.&lt;br&gt;
If you want to follow along and try all the steps below you can clone &lt;a href="https://github.com/nobitagit/postman-tester" rel="noopener noreferrer"&gt;this repo&lt;/a&gt;, follow the instructions in the readme to install and test every command against this test api.&lt;/p&gt;

&lt;p&gt;Open Postman and click on the cog on the top right section of the UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-0.png" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-1.png" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose a unique name for your project, and fill in 2 &lt;strong&gt;variables&lt;/strong&gt;, URL and Authorization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-2.png" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the picture I added an initial value of &lt;code&gt;localhost:3000&lt;/code&gt; for URL, since I am running my server locally at first, while I left the auth field blank.&lt;br&gt;
With this setup we can start hitting the auth endpoint and make use of our first variable in Postman.&lt;/p&gt;

&lt;p&gt;Save the values and select the newly created environment from the "Environments" dropdown on the top right of the UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-3.png" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new request by typing the endpoint we want to hit into the main input field.&lt;br&gt;
We want to hit &lt;code&gt;localhost:3000/auth&lt;/code&gt;, but instead of hardcoding the host we will use the environment variable we just created, by replacing &lt;code&gt;localhost:3000&lt;/code&gt; with &lt;code&gt;{{URL}}&lt;/code&gt;.&lt;br&gt;
This means that &lt;code&gt;localhost:3000/auth&lt;/code&gt; will become &lt;code&gt;{{URL}}/auth&lt;/code&gt;. Postman will confirm &lt;code&gt;URL&lt;/code&gt; is defined while we type via and autocomplete popup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-4.png" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the url is typed we send the request and sure enough, we have our token back. This is of course the least secure of the APIs since we're not even passing an email password combination, but that's ok for a test server!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-5.png" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now want to extract this token from the response and assign it to our other env variable, &lt;code&gt;Authorization&lt;/code&gt;.&lt;br&gt;
To do so, select the "Tests" tab and type 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;// read response&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// set Authorization to the jwt token&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-6.png" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This easy 2 liner gets the response and sets it to our env variable. We can confirm it works by running the request again and then clicking on the top right eye icon (Quick look environment variables).&lt;br&gt;
We will see the value being populated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-7.png" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is great, as now we'll be able to make request without manually pasting the token.&lt;br&gt;
To do so we just need to open a new tab in Postman, paste the full URL of one of our authenticated endpoints, such as &lt;code&gt;{{URL}}/users&lt;/code&gt; and, in the request headers make use of our newly set variable. Click on "Authorization" and select "Bearer token" under the Type dropdown. Paste our variable in the one field available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-8.png" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done we are ready to send a request to an endpoint that requires authentication, such as &lt;code&gt;/users&lt;/code&gt; and see the results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-10-27-postman%2F2019-10-27-postman-9.png" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting more out of Postman environments
&lt;/h2&gt;

&lt;p&gt;This simple workflow is just the tip of the iceberg of the many advantages of Postman variables and environments.&lt;br&gt;
The configuration we just created can be saved and shared to other devices or to other colleagues that are working on the same project.&lt;br&gt;
More examples and suggestions can be found on the excellent &lt;a href="https://learning.getpostman.com/docs/postman/environments_and_globals/intro_to_environments_and_globals" rel="noopener noreferrer"&gt;docs of Postman&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why I stopped spreading props on React Components</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Mon, 19 Aug 2019 23:34:41 +0000</pubDate>
      <link>https://forem.com/aurelio/why-i-stopped-spreading-props-on-react-components-o3f</link>
      <guid>https://forem.com/aurelio/why-i-stopped-spreading-props-on-react-components-o3f</guid>
      <description>&lt;p&gt;Spreading props on a React Component is a very common pattern that I picked up very easily and loved from day 1.&lt;br&gt;
With time though I learnt to understand the implications of using the spread operator in different contexts and came to the conclusion that most of the time spreading props in React is best avoided. Let's see why.&lt;/p&gt;
&lt;h2&gt;
  
  
  I stopped spreading props... but not quite
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Use spread props &lt;strong&gt;sparingly&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First of all I want to start with a clarification. The title of this post is misleading on purpose (read: clickbaity). Props spreading has &lt;strong&gt;its share of good use cases&lt;/strong&gt; and is an expressive and concise pattern that can be used effectively.&lt;/p&gt;

&lt;p&gt;A good scenario to demonstrate how props spreading can really shine is &lt;a href="https://reactjs.org/docs/higher-order-components.html" rel="noopener noreferrer"&gt;HOCs&lt;/a&gt;. Let's look at this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withDouble&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Comp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="c1"&gt;// We could wrap any type of Component here so we just pass all props down as they are&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comp&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&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;SomeInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onChange&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&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;Doubled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withDouble&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SomeInput&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;MyCal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setVal&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="nf"&gt;useState&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeInput&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setVal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Doubled&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can try the above code &lt;a href="https://jsfiddle.net/npsgLhf1/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MyCal&lt;/code&gt; is a bare-bones, extremely limited calculator that only doubles the input we type on a field.&lt;br&gt;
In this case we use &lt;code&gt;withDouble&lt;/code&gt; as a generic wrapper that can wrap and enhance any component.&lt;br&gt;
As such it must remain unaware of the props that it will forward down the tree.&lt;/p&gt;

&lt;p&gt;Being able to spread props like so &lt;code&gt;&amp;lt;Comp {...props} /&amp;gt;&lt;/code&gt; is really powerful because we are free to enhance any component we might have. In the example above we can see that passing 'disabled' later on will actually work exactly for that reason.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Doubled&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// this prop will be forwarded to `SomeInput` that will render a read only field&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Beautiful is better than ugly.
&lt;/h2&gt;

&lt;p&gt;Let's look at how &lt;code&gt;SomeInput&lt;/code&gt; is implemented.&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;SomeInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onChange&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;Now that we're in love with our new skill of spreading props, we might be tempted to do 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SomeInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onChange&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;This looks much more appealing at first glance - at least to me - and I won't deny a part of me is pleased with how succinct this looks like.&lt;/p&gt;

&lt;p&gt;If we try that the component will work just the same. The problem we just introduced may not be apparent for now, but we have lost control over which prop our underlying &lt;code&gt;input&lt;/code&gt; will receive. Try this and you will see that &lt;code&gt;randomProp&lt;/code&gt; will be happily forwarded to &lt;code&gt;&amp;lt;input /&amp;gt;&lt;/code&gt; itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeInput&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;randomProp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Had we kept our original implementation the stray property would just have been ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SomeInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onChange&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeInput&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// known props, it will be passed down&lt;/span&gt;
  &lt;span class="na"&gt;randomProp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// unknown one, ignored&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this might seem simplistic, problems like these become more and more common as the size and complexity of the codebase grow. Applying layers and layers of Components that just pass down props without any sort of check will make it very hard to follow where data flows, and which attributes are applied where. &lt;/p&gt;

&lt;h2&gt;
  
  
  In the face of ambiguity, refuse the temptation to guess.
&lt;/h2&gt;

&lt;p&gt;The latest example makes the case for using a type checker, to help flag non-existing props.&lt;br&gt;
Actually introducing type definitions on an existing codebase with spreads all over the place is not the most pleasing experience either.&lt;br&gt;
If you're into TypeScript or Flow try writing a type def this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&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;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&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;Btn--round&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;Btn&lt;/span&gt;&lt;span class="dl"&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Actionable&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Actionable&lt;/span&gt;&lt;span class="p"&gt;&amp;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;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;value&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="nx"&gt;Node&lt;/span&gt;
  &lt;span class="c1"&gt;// and??&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guessing &lt;code&gt;value&lt;/code&gt; and &lt;code&gt;type&lt;/code&gt; is quite straightforward. What about the &lt;code&gt;...rest&lt;/code&gt; though? How should the shape look like?&lt;br&gt;
We either become sloppy and allow &lt;code&gt;any&lt;/code&gt;, which makes me question why we're even trying to type this thing, or we have to open the 'Actionable' implementation, check how props are handled there and hope that there's not another spread there (which is highly possible) otherwise we'll have open yet another file.&lt;/p&gt;

&lt;p&gt;Once done that I would also check all instances of 'MyComp' to make sure random or outdated props are not passed by mistake. If this sounds tedious it's because it is.&lt;/p&gt;

&lt;p&gt;Let's compare it to this other implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onHover&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&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;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&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;Btn--round&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;Btn&lt;/span&gt;&lt;span class="dl"&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Actionable&lt;/span&gt;
    &lt;span class="na"&gt;onHover&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onHover&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;colour&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Actionable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While we can't be 100% sure about every single type in this list of props we can do a lot without looking any further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;value&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="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;colour&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="na"&gt;size&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onHover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this is not perfect, it's miles better than what we have above. I would even say this next lousy effort is better than the first! At least we're listing out all the acceptable props!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onHover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concept might seem specific to typings, but I think it represents very well the difference in terms of cognitive effort required when reading code written in one way or the other.&lt;/p&gt;

&lt;p&gt;By listing our props we stay away from pitfalls and ensure clarity for the readers of our code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicit is better than implicit.
&lt;/h2&gt;

&lt;p&gt;In conclusion, while spreading props is a powerful pattern we must be aware of its drawbacks and conscious that this technique has its place and merits, but is certainly not a silver bullet.&lt;/p&gt;

&lt;p&gt;Having props listed out clearly helps us communicate intent and capabilities of our functions. Spreading them can be used to serve a purpose, but should never come at the cost of readability or safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;With time I saw that the pitfalls of spreading props are actually documented in more than one official piece of documentation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spread attributes can be useful but they also make it easy to pass unnecessary props to components that don’t care about them or to pass invalid HTML attributes to the DOM. We recommend using this syntax sparingly.&lt;br&gt;
&lt;a href="https://reactjs.org/docs/jsx-in-depth.html#spread-attributes" rel="noopener noreferrer"&gt;React docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The first quote at the beginning of the article is from &lt;a href="http://airbnb.io/javascript/react/" rel="noopener noreferrer"&gt;Airbnb's JavaScript Style Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, you might be interested to know that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There's more than one reference in this article that comes from the &lt;a href="https://www.python.org/dev/peps/pep-0020/" rel="noopener noreferrer"&gt;Zen of Python&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cover image is by &lt;a href="https://unsplash.com/@lachlanjdempsey" rel="noopener noreferrer"&gt;Lachlan Dempsey&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published on my &lt;a href="https://nobitagit.github.io/blog/Why-I-stopped-spreading-props-react/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Compound scales in D3.js</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Fri, 09 Aug 2019 15:14:14 +0000</pubDate>
      <link>https://forem.com/aurelio/compound-scales-in-d3-js-5fkj</link>
      <guid>https://forem.com/aurelio/compound-scales-in-d3-js-5fkj</guid>
      <description>&lt;p&gt;Scales are an extremely flexible feature of D3.js.&lt;br&gt;
Even though in many cases our need is just to have a function that maps one value in the &lt;code&gt;domain&lt;/code&gt; to one value in the &lt;code&gt;range&lt;/code&gt;, sometimes it can be handy to have a mapping from one to many values.&lt;/p&gt;

&lt;p&gt;Suppose for example that we need to map one input to a set of values such as color and radius to build a simple scatterplot where the dots have radius and color depending on the input value from the dataset.&lt;/p&gt;

&lt;p&gt;In these case being able to have a compound scale is what we need, and thankfully D3 provides this feature out of the box. Just pass two (or more) objects to the range function and d3 will do the rest.&lt;/p&gt;

&lt;p&gt;Here’s a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myScale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scaleLinear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;domain&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="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#4c0080&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15px&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="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#43a1ad&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;150px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will return a function that will convert our values (in this case from 0 to 100) to an object with all the values appropriately interpolated.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;myScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; {color: 'rgb(72, 66, 146)', radius: '70.35px'}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple yet super-handy feature, especially considering that we don’t need to specify the interpolator because the library will figure it out for us. On top of that we are not tied to single level objects, but deep objects will work just the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Image is by &lt;a href="https://unsplash.com/@markusspiske" rel="noopener noreferrer"&gt;Markus Spiske&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://nobitagit.github.io/blog/d3-compound-scales/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>d3</category>
      <category>javascript</category>
      <category>dataviz</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Array methods in D3.js</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Sun, 04 Aug 2019 22:09:24 +0000</pubDate>
      <link>https://forem.com/aurelio/array-methods-in-d3-js-11kg</link>
      <guid>https://forem.com/aurelio/array-methods-in-d3-js-11kg</guid>
      <description>&lt;p&gt;Arrays are the natural data structure for looping over data in JavaScript. While the native methods such as map, reduce, filter etc will provide a good base for pretty much any operation on arrays, many libraries and frameworks enrich the native set of functions with domain specific utilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://d3js.org/" rel="noopener noreferrer"&gt;D3.js&lt;/a&gt;, the de facto standard library for data visualisation in Js, is no exception. D3 actually provides &lt;a href="https://github.com/d3/d3-array" rel="noopener noreferrer"&gt;&lt;code&gt;d3-array&lt;/code&gt;&lt;/a&gt;, an entire module of utility functions that covers many of the most common operations when dealing with data and visualisation.&lt;/p&gt;

&lt;p&gt;Let’s see how we can leverage some of them, starting from the most commonly used ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing and using the module the right way
&lt;/h2&gt;

&lt;p&gt;First of all lets point out that it is strongly suggested installing and importing the &lt;code&gt;d3-array&lt;/code&gt; module only, rather than the whole d3 module.&lt;/p&gt;

&lt;p&gt;This means that rather 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;// npm i -s d3&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;d3&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;d3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&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="mi"&gt;2&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will want to do 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;// npm i -s d3-array&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d3-array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&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="mi"&gt;2&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids downloading and bundling the whole d3 library. D3 has in fact moved to a fully modularised build since v3. This means we can install only the pieces we need, without incurring in a hefty penalty in terms of bundle size.&lt;/p&gt;

&lt;p&gt;If you're curious to see which modules d3 exports, you can see them nicely listed in the &lt;a href="https://github.com/d3/d3/blob/master/index.js#L2" rel="noopener noreferrer"&gt;index.js&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;To illustrate some of d3's array manipulation features let’s start with two dummy datasets, a sparse, unsorted array of random numbers, &lt;code&gt;data&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.33&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="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;..and an array of objects containing some songs along with my rating of each of them, &lt;code&gt;nestedData&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nestedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
  &lt;span class="na"&gt;rating&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="na"&gt;song&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Song 2&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="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Top Man&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="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Clover Over Dover&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="na"&gt;rating&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pressure On Julian&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="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yuko And Hiro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;d3.min()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use it to find the lowest value inside an array.&lt;br&gt;
Js provides a &lt;code&gt;Math.min()&lt;/code&gt; operator but &lt;code&gt;d3.min()&lt;/code&gt; will prove more flexible and forgiving, for example when our dataset is an array with holes (some positions have null or undefined value, just like our data array). In our case, here are the results:&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;dataMin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nestedMin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s compare the Js, no-lib version of the same code:&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;dataMin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; NaN :(&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nestedMin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;nestedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first case we are bitten by the sparse array, in the second we go through a certain degree of verbosity. The d3 versions are certainly safer, terser and more compact. Of course, we can cater for this particular case and fix the nasty NaN returned by the first 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataMin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation of &lt;code&gt;d3.min&lt;/code&gt; can be found &lt;a href="https://github.com/d3/d3-array/blob/master/src/min.js" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Read the next method for some common considerations about its usage in D3.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;d3.max()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use it to find the highest value inside an array.&lt;br&gt;
Quite unsurprisingly max is the opposite of the min method. The very same apply, so using it with our two arrays is just as easy as 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataMax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 22&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nestedMax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation of &lt;code&gt;d3.max&lt;/code&gt; can be found &lt;a href="https://github.com/d3/d3-array/blob/master/src/max.js" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Again, this method does not count &lt;code&gt;undefined&lt;/code&gt; and &lt;code&gt;null&lt;/code&gt; values, and it will safely skip over them. It will compute strings though, as we’ll see in a short while.&lt;/p&gt;

&lt;p&gt;Just for fun I tried throwing a bit of everything to 'd3.max' and its diminutive counterpart 'd3.min'. Some (pointless?) tests include:&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;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// TypeError :(&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&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;// undefined, make sure you pass an array!&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined, make sure you pass an array!&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; '' &amp;lt;= watch out for this one&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 2&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hey ho!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// hey ho!&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hey ho!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// hey ho!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The biggest thing here — apart from the suggestion to make sensible datasets (i.e. do not copy the ones above) — is to be wary of empty values stored as empty strings as they are picked up and compared. Not that it’s that frequent, but anyway it’s good to know.&lt;br&gt;
Comparing strings can actually be way more useful, though. We can for example find the darkest colour within a set.&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;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#15234C&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;#5a5f6d&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;#183b9e&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;#3d9e18&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// "#15234C"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A practical example for this could be having a palette of colours and deciding to plot our data using the darkest colour as upper bound and the lightest as lowest bound. This will allow us to very easily create ranges of colours for our data visualisations.&lt;/p&gt;

&lt;p&gt;This is a very powerful feature, and if you're interested in a practical use of it, do check out my post on &lt;a href="https://dev.to/aurelio/interpolating-colours-within-a-range-in-d3-js-5f61"&gt;Interpolating colours within a range in d3.js&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;d3.extent()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use it to find the lowest and the highest values in one function call. Returns an array.&lt;br&gt;
Finding min and max values in an array is such a common operation in D3 that such functionality is grouped into one convenience method, &lt;code&gt;extent&lt;/code&gt;.&lt;br&gt;
Let's try it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 22]&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [3, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is exactly the same as the following code, but more concise:&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;dataExt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt; &lt;span class="c1"&gt;// [1, 22]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;extent&lt;/code&gt; we are calling only one method rather than two. I thought that under the hood, &lt;code&gt;extent&lt;/code&gt; was just a wrapper around &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;. It’s &lt;a href="https://github.com/d3/d3-array/blob/master/src/extent.js" rel="noopener noreferrer"&gt;not&lt;/a&gt;.&lt;br&gt;
Arguably the most natural usage for extent is when calculating ranges and domain of our datasets, where we normally have to provide a minimum and a maximum number for computing a scale.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;d3.sum()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use it to get a sum of all the elements of an array;&lt;/p&gt;

&lt;p&gt;Again, as expected, it skips over null and undefined elements.&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;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 59.53&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 20.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be achieved quite easily with vanilla Js and reduce, but failing to check for null or undefined elements will spoil the party.&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&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="c1"&gt;// =&amp;gt; NaN :(&lt;/span&gt;
&lt;span class="nx"&gt;nestedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&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;rating&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="c1"&gt;// 20.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;d3.mean()&lt;/code&gt; and &lt;code&gt;d3.median()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use them to find the mean and median values of an array.&lt;/p&gt;

&lt;p&gt;We close today's overview with two very related methods, &lt;code&gt;mean&lt;/code&gt; and &lt;code&gt;median&lt;/code&gt;.&lt;br&gt;
The meaning of mean and median can be easily mixed up, so I put these methods together in order to start with an explanation of their differences. Both concepts represent the average of a dataset, or better, the central tendency of a set of statistical scores.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;mean&lt;/strong&gt; is the most widely understood and common expression of an average. It is calculated through the sum of all elements in the dataset divided by the number of them, or - translating this to Js - t*he sum of the items of the array, divided by its length*.&lt;/p&gt;

&lt;p&gt;To give an example let’s create a new array for this purpose.&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&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="mi"&gt;4&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&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;sum&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="c1"&gt;// 4.714285714285714&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;median&lt;/strong&gt; is instead that number that sits in the middle of our dataset. Our median will be the value where half of the items will be sitting before it, and the other half of the values will come after it.&lt;/p&gt;

&lt;p&gt;There’s no easy mathematical formula for calculating the median. Hence, calculating its value for a dataset without any library is going to be a tougher challenge, more so because we have to account for different behaviours when our dataset length is even and when our dataset length is odd.&lt;/p&gt;

&lt;p&gt;Given this sorted array:&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;data1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&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="mi"&gt;4&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;// ----------------^&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our median will be 3, as that is the value that sits in the middle “splitting” the array in two halves.&lt;/p&gt;

&lt;p&gt;In this case though:&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;data2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&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="mi"&gt;4&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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// -----------------^ uhm... 3 or 4?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s &lt;strong&gt;not&lt;/strong&gt; a single value splitting the array, so we can say that both 3 and 4 sit in the middle. To find the median in this case we have to sum these 2 values and divide by 2 (that is, we will apply the formula we used to find the mean). Our median in this case is 3.5.&lt;br&gt;
Luckily D3 has this functionality built in, and we can leave the library do the math for us.&lt;/p&gt;

&lt;p&gt;So, going back to our original datasets we can find mean and median very quickly.&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;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 7.44125&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3.5&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4.1&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results above highlight a very interesting case. While the difference between mean and median of our set of songs is negligible (4.1 and 4), we can’t say the same when doing the same computations for our list of numbers. Why is that?&lt;/p&gt;

&lt;p&gt;The reason is that the mean is easily influenced by spikes in the dataset. One single very low or very high value can easily skew our result by a significant amount. The median, instead, will not follow the same destiny, giving us an arguably more accurate idea of where the mid point is and what the central tendency actually looks like.&lt;/p&gt;

&lt;p&gt;To illustrate this, let’s add one value to our previous array and test it out again with the help of d3:&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;data3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&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="mi"&gt;4&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="mi"&gt;1500000&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 250002.5&lt;/span&gt;
&lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it’s very clear how a subtle difference between the two concepts may actually translate to striking differences in real world scenarios.&lt;br&gt;
This means that when we need to represent the average of a dataset we first of all have to understand “which average” we want our users to see, or which one is more meaningful when telling our story through a visualisation.&lt;/p&gt;

&lt;p&gt;There’s no single answer to this question and that’s a very good reason to have well clear in mind what exactly are the purposes of these two apparently similar methods that D3 provides.&lt;/p&gt;




&lt;p&gt;This is just a small part of methods that d3 provides to act on arrays and maps, and certainly the ones I use the most. Many more are exported though, as you can see from the &lt;a href="https://github.com/d3/d3-array/blob/master/src/index.js" rel="noopener noreferrer"&gt;source code&lt;/a&gt;, and it's good to know that there might be a function in there that is tailored to our needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;p&gt;Cover picture is by &lt;a href="https://unsplash.com/@sharegrid" rel="noopener noreferrer"&gt;ShareGrid&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on my &lt;a href="https://nobitagit.github.io/blog/D3js-array-methods/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>d3</category>
      <category>javascript</category>
      <category>dataviz</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Vs Code one tip a week: splitting panes</title>
      <dc:creator>Aurelio</dc:creator>
      <pubDate>Thu, 01 Aug 2019 09:22:23 +0000</pubDate>
      <link>https://forem.com/aurelio/vs-code-one-tip-a-week-splitting-panes-4k9m</link>
      <guid>https://forem.com/aurelio/vs-code-one-tip-a-week-splitting-panes-4k9m</guid>
      <description>&lt;p&gt;It's quite common when coding to have the need to view multiple files at once on the screen. At times, we might even want to view two different parts of the same long file. Other times again we just want to make the most of a widescreen monitor.&lt;/p&gt;

&lt;p&gt;For all those case splitting our editor is the solution, and today we'll see how to do it without the help of a mouse.&lt;/p&gt;

&lt;p&gt;Split editor to the right (vertically):&lt;/p&gt;

&lt;p&gt;Mac - &lt;code&gt;⌘ + \&lt;/code&gt; &lt;br&gt;&lt;br&gt;
Win - &lt;code&gt;Ctrl + \&lt;/code&gt; &lt;br&gt;&lt;br&gt;
Linux - &lt;code&gt;Ctrl + \&lt;/code&gt; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;I try to commit to memory this shortcut by associating the (back)slash with the idea of cutting/splitting something in a half. Not sure it makes sense, but it does work for me!&lt;/p&gt;

&lt;p&gt;An editor can also be split horizontally (or, as in VsCode lingo, orthogonally). I don't use this shortcut but in case you have different habits here it is:&lt;/p&gt;

&lt;p&gt;Mac - &lt;code&gt;⌘ + K + \&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Win - &lt;code&gt;Ctrl + K + \&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Linux - &lt;code&gt;Ctrl + K + \&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.githubusercontent.com%2Fmedia%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-8-1-vscode-tip-split-panes.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.githubusercontent.com%2Fmedia%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-8-1-vscode-tip-split-panes.gif" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Even more ways to split the screen
&lt;/h2&gt;

&lt;p&gt;If you pull up the command palette (&lt;code&gt;⌘ + SHIFT + P&lt;/code&gt; on a Mac, &lt;code&gt;Ctrl + SHIFT + P&lt;/code&gt; elsewhere) you will see some other options to split the screen, such as Split Editor Down, Split Editor Left etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-8-1-vscode-tip-split-panes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnobitagit%2Fblog%2Fgh-pages%2Fimages%2F2019-8-1-vscode-tip-split-panes.png" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These have no associated default key binding and can be accessed via the palette. If you feel you want to have them available as a shortcut, you can use &lt;a href="https://code.visualstudio.com/docs/getstarted/keybindings" rel="noopener noreferrer"&gt;VsCode key shortcut editor&lt;/a&gt; to add your custom key combination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cover image is by Drew Beamer. Check out his work &lt;a href="https://unsplash.com/photos/5DD7-L4A4Uw" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This is an effort to learn how to get the best out of Vs Code keyboard shortcuts without feeling overwhelmed.&lt;/p&gt;

&lt;p&gt;Learning how to use our favourite IDE without a mouse can make a big difference.&lt;br&gt;
Since an extension like the amazing &lt;a href="https://plugins.jetbrains.com/plugin/4455-key-promoter" rel="noopener noreferrer"&gt;Key Promoter for Jetbrains&lt;/a&gt; seems to be &lt;a href="https://github.com/Microsoft/vscode/issues/26729" rel="noopener noreferrer"&gt;far from being a reality for now at least&lt;/a&gt;, I started collecting my favourite keyboard tricks in bite sized chunks.&lt;/p&gt;

&lt;p&gt;The idea is simple: find one tip you like, practice it the whole week until you've really mastered it and made it part of your workflow and then move to the next one. Follow me and improve together!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://nobitagit.github.io/blog/vscode-tip-split-panes/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>webdev</category>
      <category>tips</category>
    </item>
  </channel>
</rss>
