<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ruairidh W McHardy</title>
    <description>The latest articles on DEV Community by Ruairidh W McHardy (@ruairidhwm).</description>
    <link>https://dev.to/ruairidhwm</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%2F208510%2F0a7c0b93-12f2-4b45-a203-73babd9af105.jpg</url>
      <title>DEV Community: Ruairidh W McHardy</title>
      <link>https://dev.to/ruairidhwm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ruairidhwm"/>
    <language>en</language>
    <item>
      <title>Partial Application and Functional Programming in JavaScript</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Tue, 19 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/partial-application-and-functional-programming-in-javascript-18bb</link>
      <guid>https://dev.to/ruairidhwm/partial-application-and-functional-programming-in-javascript-18bb</guid>
      <description>&lt;p&gt;How many times have you heard about making your code 'functional'? You know it makes things more composable, more efficient, and easy to reason with, but what's a &lt;strong&gt;practical&lt;/strong&gt; example of this in action? Something you could use at work?&lt;/p&gt;

&lt;p&gt;One technique I like to use in my daily coding is &lt;em&gt;partial application&lt;/em&gt;. Wikipedia defines this as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In computer science, partial application (or partial function application) refers to the process of fixing a &amp;gt;number of arguments to a function, producing another function of smaller arity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;...what?&lt;/p&gt;

&lt;p&gt;Put simply, we take a function which could accept multiple inputs, but make it more flexible by splitting it into smaller functions to allow for better reusability. But, it's going to be easier to explain this with some code.&lt;/p&gt;

&lt;p&gt;Imagine we have an API call we want to make. We could do 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;const getData = async (url: string) =&amp;gt; {

  try {

  const response = await fetch(URL);



  const result = await response.json();

  } catch (error) {

  console.error(error);

  }

 };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So it works, but if we wanted to then amend our &lt;code&gt;getData&lt;/code&gt; function to use another endpoint on the API, we'd need to pass in a whole new URL. It's also not very descriptive. We can do better!&lt;/p&gt;

&lt;p&gt;This is where partial application comes in. We can split our function into its constituent parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getAPIData = (baseUrl: string) =&amp;gt; (endpoint: string) =&amp;gt; async (callback) =&amp;gt; {

 try {

  const response = await fetch(`${baseUrl}/${endpoint}`);

  const result = await response.json();

  callback(result);

  } catch (error) {
  console.error(error);
  }
 };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what's different? Here we are using currying to allow us to reuse certain elements of the function, making it more efficient. Check out the usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetchInternalData = getAPIData("https://internal.myco.io");

// Now we want to fetch employees and clients
const fetchEmployees = fetchInternalData("employees");

const fetchClients = fetchInternalData("clients");

const callback = (data) =&amp;gt; console.log(data); // This could do anything you want. It's just a callback.

// So putting it all together

fetchEmployees(callback);
fetchClients(callback);

// We can then use the same function for an external API

const fetchExternalData = getAPIData("https://api.github.com");

const fetchUsers = fetchExternalData("/users");

// We want to get the login names here

fetchUsers((data) =&amp;gt; {
  console.log(data.map((user) =&amp;gt; user.login));
});

// And the avatars here

fetchUsers((data) =&amp;gt; {
  console.log(data.map((user) =&amp;gt; user.avatar_url));
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, that's it! Just a simple way of splitting up a rigid function and making it more composable, saving you and your team from needing to reinvent the wheel. It also is easier to reason with which makes code reviews a more pleasant experience for everyone involved!&lt;/p&gt;

&lt;p&gt;P.S. Want to sound clever when you talk about this stuff? You could mention that it reduces the &lt;em&gt;arity&lt;/em&gt; of your functions. Put simply, arity is just a fancy way of talking about the number of parameters your function takes. If you've coded for a while, then you'll actually have used this already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A function that takes one parameter is &lt;strong&gt;unary&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A function which takes two parameters is &lt;strong&gt;binary&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A function which takes three parameters is &lt;strong&gt;ternary&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...and so on.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://egghead.io/q/resources-by-kyle-shevlin"&gt;Kyle Shevin&lt;/a&gt; who I learned this from on Egghead, and &lt;a href="https://www.markbarry.dev/currying-and-partial-application-with-async-await-optional-parameters/"&gt;Mark Barry&lt;/a&gt; for a neat async refactoring which saved me some time when putting this quick post together.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
    </item>
    <item>
      <title>An introduction to micro-frontends</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Sat, 28 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/an-introduction-to-micro-frontends-2fji</link>
      <guid>https://dev.to/ruairidhwm/an-introduction-to-micro-frontends-2fji</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;If you work on an application which involves multiple engineers, you'll have noticed that it's hard to approach working on a frontend simultaneously. This can lead to a lot of frustration and delay across teams, and the recent trend of splitting up monolithic frontends into smaller pieces has become popular.&lt;/p&gt;

&lt;p&gt;This is known as a micro-frontend, and this article will look at how they work, why they're effective, and how you can leverage this architecture in your own team.&lt;/p&gt;

&lt;p&gt;Additionally, we'll look at the benefits and costs so that you can establish whether you should be using a micro-frontend, rather than just chasing the latest craze.&lt;/p&gt;

&lt;p&gt;By the end of this post, you should understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The pros of micro-frontends&lt;/li&gt;
&lt;li&gt;The cons of micro-frontends&lt;/li&gt;
&lt;li&gt;The differences in integration approaches of micro-frontends&lt;/li&gt;
&lt;li&gt;How to implement a client-side integration of a micro-frontend&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a micro-frontend?
&lt;/h2&gt;

&lt;p&gt;A micro-frontend is an architecture where independent frontend codebases are combined into a larger application. You could create applications using different libraries such as React, or Vue, and also allow teams to work on applications independently, before bringing them together.&lt;/p&gt;

&lt;p&gt;There are numerous advantages to this approach, namely that multiple teams can work on the frontend simultaneously without blocking one another, and you can easily version or customise components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration of micro-frontends
&lt;/h2&gt;

&lt;p&gt;If you can make a frontend application, congratulations! You can make a micro-frontend. There are a few approaches to implementing a micro-frontend though. The key difference lies in client-side integration, vs build-time integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build-time integration
&lt;/h3&gt;

&lt;p&gt;This integration strategy involves giving the container access to the dependency applications' source code before it is all loaded in the browser.&lt;/p&gt;

&lt;p&gt;The steps involved are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work on application&lt;/li&gt;
&lt;li&gt;Deploy it as an NPM package (in a private registry if you wish)&lt;/li&gt;
&lt;li&gt;Install the package as a dependency in the container application&lt;/li&gt;
&lt;li&gt;Output a bundle which contains all the code for our application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This has a few disadvantages as the container must be re-deployed every time a dependency application is updated, and it can be very tempting to tightly couple dependent applications which defeats the purpose of a micro-frontend architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-side integration
&lt;/h3&gt;

&lt;p&gt;This integration strategy involves loading the dependency application source code after the container application is loaded in the browser. We simply expose an entry point and render the output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work on application&lt;/li&gt;
&lt;li&gt;Deploy application to a static JS file such as &lt;a href="https://remote.foo.com/widget.js" rel="noopener noreferrer"&gt;https://remote.foo.com/widget.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;User navigates to &lt;a href="https://container.foo.co" rel="noopener noreferrer"&gt;https://container.foo.co&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Container fetches widget.js and executes it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is advantageous as the widget.js dependency application can be deployed independently at any time, and different versions of it can be deployed, deferring to the container as to which version should be used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which should I use?
&lt;/h3&gt;

&lt;p&gt;It's up to you! In this article we will discuss using a client-side integration. This a slightly trickier thing to achieve than simply combining the constituent applications at build time, but it allows us greater flexibility as you don't need to re-deploy every time you change a dependency application, and you avoid tightly coupling applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-side micro-frontends
&lt;/h3&gt;

&lt;p&gt;We're using client-side integration via Webpack Module Federation. This is a flexible and performant solution which will give us a scalable architecture.&lt;/p&gt;

&lt;p&gt;This works by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designating our container as the host application, and our dependency applications as remote.&lt;/li&gt;
&lt;li&gt;In the remote applications, we decide which modules we want to make available to other projects.&lt;/li&gt;
&lt;li&gt;We expose those files via module federation.&lt;/li&gt;
&lt;li&gt;In the host we decide what we want to fetch from the remotes.&lt;/li&gt;
&lt;li&gt;We load the host's entry point asynchronously.&lt;/li&gt;
&lt;li&gt;We load whatever we want from the remotes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see in the example repo, we have added a Module Federation Plugin into our webpack config. There is a sample remote application added there called 'widget'. We can see this calls a localhost url. This works as follows:&lt;/p&gt;

&lt;p&gt;Our remote application goes through its normal webpack bundling process, but additionally is processed by the Module Federation Plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fruairidh.dev%2Fstatic%2F84a800eeb1cb7c9282f091666ac7076f%2Fb9054%2Fbundling.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fruairidh.dev%2Fstatic%2F84a800eeb1cb7c9282f091666ac7076f%2Fb9054%2Fbundling.png" title="'Demonstration image of the bundling process'" alt="'Demonstration image of the bundling process'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The remoteEntry.js file acts as a manifest and tells the container application how to load the files for the 'widget' application.&lt;/p&gt;

&lt;p&gt;This means we can run the 'widget' application in isolation, but by adding the module federation plugin, we are able to include the 'widget' application in other applications.&lt;/p&gt;

&lt;p&gt;On the container application side, we process our code with the Module Federation Plugin, and we generate the contents of 'index.js'. This way, Webpack knows that it needs to fetch something from the remote applications.&lt;/p&gt;

&lt;p&gt;As a flow, this looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;main.js (generated by Webpack) is loaded and executed&lt;/li&gt;
&lt;li&gt;Webpack sees we need to load and executes bootstrap.js&lt;/li&gt;
&lt;li&gt;Bootstrap tells Webpack it needs a file from widgets'. It fetches remoteEntry.js to figure out what.&lt;/li&gt;
&lt;li&gt;It fetches the dependencies.&lt;/li&gt;
&lt;li&gt;Once fetched, bootstrap.js is executed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sharing dependencies
&lt;/h2&gt;

&lt;p&gt;As many remote applications may need the same dependencies, it doesn't make sense to install these multiple times. Instead, look at the &lt;code&gt;shared&lt;/code&gt; property of the Module Federation Plugin. If you set this in common across both remote applications, the dependency will be shared between them.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;shared: { react: {singleton: true}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We load our dependencies asynchronously to prevent an eager consumption error. An example is contained in bootstrap.ts. This follows the same asynchronous loading pattern we see above in the container.&lt;/p&gt;

&lt;p&gt;Versioning is handled automatically. If you specify a different version of a package in one application, than exists in the other, and they're attempting to share, then both versions will be loaded and the correct one is used in the respective applications.&lt;/p&gt;

&lt;p&gt;The Module Federation Plugin looks at the shared dependencies, and reconciles them with what is contained in &lt;code&gt;package.json&lt;/code&gt; . If the versions diverge, then both are loaded.&lt;/p&gt;

&lt;p&gt;We can prevent this from occurring for packages such as react which rely on there being only one instance running, by passing a singleton property which ensure that only one copy is ever loaded.&lt;/p&gt;

&lt;p&gt;Shared module selection can also be delegated by importing &lt;code&gt;package.json&lt;/code&gt; and adding our dependencies. This is purely optional however.&lt;/p&gt;

&lt;p&gt;You can see an example of this &lt;a href="https://github.com/ruairidhwm/micro-frontends/blob/main/packages/container/config/webpack.prod.js" rel="noopener noreferrer"&gt;in the repo&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;packageJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What about the execution?
&lt;/h2&gt;

&lt;p&gt;We want to be able to run our code in isolation, and as part of a container. So how do we handle the assumption of where it will be rendered?&lt;/p&gt;

&lt;p&gt;When developing in isolation we can assume that the element with &lt;code&gt;id='foo'&lt;/code&gt; is present. But when running it as part of a container application, how do we know what the id of the element rendering our code will be?&lt;/p&gt;

&lt;p&gt;The best pattern for handling this is to wrap our application in a 'mount' function which accepts an HTML element or React Element as an argument. This will then allow us to render the code in the correct place.&lt;/p&gt;

&lt;p&gt;As you can see in the &lt;a href="https://github.com/ruairidhwm/micro-frontends" rel="noopener noreferrer"&gt;repo&lt;/a&gt; we achieve this in the &lt;a href="https://github.com/ruairidhwm/micro-frontends/blob/main/packages/widget/src/bootstrap.tsx" rel="noopener noreferrer"&gt;&lt;code&gt;bootstrap&lt;/code&gt; file&lt;/a&gt;:&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;mount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nx"&gt;el&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;
  
  
  Pattern for importing remote applications
&lt;/h2&gt;

&lt;p&gt;If you look in &lt;a href="https://github.com/ruairidhwm/micro-frontends/blob/main/packages/container/src/App.tsx" rel="noopener noreferrer"&gt;&lt;code&gt;App.tsx&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/ruairidhwm/micro-frontends/blob/main/packages/container/src/components/WidgetApp.tsx" rel="noopener noreferrer"&gt;&lt;code&gt;components/WidgetApp.tsx&lt;/code&gt;&lt;/a&gt; then you will see an example of how to include remote applications in the container. We use the &lt;code&gt;useRef&lt;/code&gt; hook to create an element which the app will be injected into, and a &lt;code&gt;useEffect&lt;/code&gt; hook to ensure that we only load it in once:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&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;mount&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="s2"&gt;widget/WidgetApp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &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;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;// Pass in our ref and render it once.&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What about communicating between apps?
&lt;/h3&gt;

&lt;p&gt;Ideally, you don't want your apps to be aware of each other, as that can create issues, but there will be times you need to pass data between them.&lt;/p&gt;

&lt;p&gt;There are a few ways of achieving this, but my preferred pattern is to follow react's example and pass callbacks and state downwards from the container application to the remote applications.&lt;/p&gt;

&lt;p&gt;This has the advantage of being explicit in how data flows through the application.&lt;/p&gt;

&lt;p&gt;It's important to avoid your micro-frontend applications sharing state. This then couples them and makes maintenance extremely difficult. At that point, you may as well just have a monolithic frontend, which may be the more appropriate solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the downsides of micro-frontends?
&lt;/h2&gt;

&lt;p&gt;It's important to understand when to use, and &lt;strong&gt;not&lt;/strong&gt; to use a micro-frontend. They have tradeoffs and you shouldn't be tempted to use this pattern just because you can.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bundle size
&lt;/h3&gt;

&lt;p&gt;The first downside is obvious. We end up shipping more code to the client. It's very important to be sensitive to this, and I've tried to include best practices in my example repo.&lt;/p&gt;

&lt;p&gt;As a quick guide, you should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share dependencies wherever possible&lt;/li&gt;
&lt;li&gt;Lazy load components to prevent unecessary code download&lt;/li&gt;
&lt;li&gt;Avoid bundling enormous packages such as moment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these things should come as a surprise. Try to keep your dependencies lean, and keep an eye on your bundle size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Organisation
&lt;/h3&gt;

&lt;p&gt;The next downside is organisational. Whilst it's great that you can split up code across teams and release autonomously, you can end up with a lack of communication about features, schedules, and code practices.&lt;/p&gt;

&lt;p&gt;This can be avoided by good communication and documentation, but it's worth bearing in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexity
&lt;/h3&gt;

&lt;p&gt;Micro-services can appear intimidating if you're used to dealing exclusively with monolithic architectures. Questions such as how the applications communicate, where state lives, how to develop a good release pipeline, and test components are all common.&lt;/p&gt;

&lt;p&gt;Before rushing to implement micro-frontends, you should take the time to fully understand how they work, and try to communicate this with your team. Once everyone is at a similar level of understanding, it's easier to move ahead.&lt;/p&gt;

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

&lt;p&gt;Frontend software engineering has become vastly more complex over recent years, and that trend is likely to continue.&lt;/p&gt;

&lt;p&gt;We are pushing more and more functionality to the client side, with incredibly sophisticated applications. Understanding how to separate your code into modules and splitting their development can deliver real benefits.&lt;/p&gt;

&lt;p&gt;Hopefully by the end of this tutorial you now understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The pros of micro-frontends&lt;/li&gt;
&lt;li&gt;The cons of micro-frontends&lt;/li&gt;
&lt;li&gt;The differences in integration approaches of micro-frontends&lt;/li&gt;
&lt;li&gt;How to implement a client-side integration of a micro-frontend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Found this useful? Let me know on &lt;a href="https://twitter.com/ruairidhwm" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>microfrontends</category>
      <category>frontend</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Build your own programming language</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Sat, 16 May 2020 19:52:20 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/build-your-own-programming-language-4koa</link>
      <guid>https://dev.to/ruairidhwm/build-your-own-programming-language-4koa</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fnlikdFl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ruairidh.dev/static/143a84465b810751b0541aeccf0bc4ed/b9e4f/featured.png%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fnlikdFl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ruairidh.dev/static/143a84465b810751b0541aeccf0bc4ed/b9e4f/featured.png%2522" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I write JavaScript nearly every day just now and love it, but I don’t really know what happens to my code once I run it. Normally I run it through node, or the browser, and sometimes it works.&lt;/p&gt;

&lt;p&gt;But I want to know what’s actually happening beneath the surface. How does my syntax become a working program? I’m no computer scientist, so I’m not going super deep into this, but I want to at least have a superficial understanding of my tools.&lt;/p&gt;

&lt;p&gt;As part of this, I thought it would be a fun exercise to try and create a very, &lt;em&gt;very&lt;/em&gt; basic programming language in JavaScript. I’m more or less following &lt;a href="https://github.com/stevekinney"&gt;Steve Kinney’s&lt;/a&gt; path in this, so I’ve got a good example.&lt;/p&gt;

&lt;h1&gt;
  
  
  What does a programming language consist of?
&lt;/h1&gt;

&lt;p&gt;So a programming language needs a way to understand the syntax it has been provided, and a way to interpret or compile these instructions into machine-readable code. Effectively we are turning our high level code into slightly lower level code.&lt;/p&gt;

&lt;p&gt;I’m keeping this very simple and building a basic lexical analysis tool or &lt;code&gt;lexer&lt;/code&gt; and a simple syntactic analysis tool, or &lt;code&gt;AST&lt;/code&gt; (Abstract Syntax Tree).&lt;/p&gt;

&lt;p&gt;This will accept my string of syntax, tokenize it, and then run the logic.&lt;/p&gt;

&lt;p&gt;The current post will focus on building our lexer, and a subsequent post will handle our AST and related tooling.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building a lexer in JavaScript
&lt;/h1&gt;

&lt;p&gt;So a lexer basically takes a string of code and splits it into individual elements, or ‘tokens’. A token is just a small unit of the language. For example, look at this string in JavaScript:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sum(2, 1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A lexer will split it into individual elements like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sum&lt;/code&gt; + &lt;code&gt;(&lt;/code&gt; + &lt;code&gt;2&lt;/code&gt; + &lt;code&gt;,&lt;/code&gt; + &lt;code&gt;1&lt;/code&gt; + &lt;code&gt;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We effectively accept a string of code, iterate through each character, and check each character to see if it matches a pre-defined set of tokens. If so, we add it to our tokens collection and return them at the end to be interpreted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Now we have a rough idea of how a lexer works, let’s get started building one! Firstly, we’ll make some helper functions to determine character types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const LETTER = /[a-zA-Z]/
const WHITESPACE = /\s+/
const NUMBER = /^[0-9]+$/
const OPERATORS = ["+", "-", "*", "/", "%"]

const isLetter = character =&amp;gt; LETTER.test(character)
const isWhitespace = character =&amp;gt; WHITESPACE.test(character)
const isNumber = character =&amp;gt; NUMBER.test(character)
const isOpeneningParenthesis = character =&amp;gt; character === "("
const isClosingParenthesis = character =&amp;gt; character === ")"
const isParenthesis = character =&amp;gt;
  isOpeneningParenthesis(character) || isClosingParenthesis(character)
const isQuote = character =&amp;gt; character === '"'
const isOperator = character =&amp;gt; OPERATORS.includes(character)

const helpers = {
  isLetter,
  isWhitespace,
  isNumber,
  isOpeneningParenthesis,
  isClosingParenthesis,
  isParenthesis,
  isQuote,
  isOperator,
}

export default helpers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we can see here, we have a number of methods which accept a character and run a simple RegEx (regular expression) on it to determine whether it matches a pre-determined type which we have created as a constant at the top of the file. In particular, we are looking for letters, whitespace, numbers, and operators.&lt;/p&gt;

&lt;p&gt;Because the language we are building is inspired by &lt;a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)"&gt;Lisp&lt;/a&gt;, we will definitely need to know about parentheses, so we create specific helpers for these.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building our token parser
&lt;/h2&gt;

&lt;p&gt;Now we have some helpers to determine the characters we are working with, we want to put them to use! So let’s build a simple tokeniser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import helpers from './helpers';

const tokenize = (input) =&amp;gt; {
  const tokens = [];

  let cursor = 0;

  while (cursor &amp;lt; input.length) {
    const character = input[cursor];

    if (helpers.isParenthesis(character)) {
      tokens.push({
        type: 'Parenthesis',
        value: character,
      });
      cursor++;
      continue;
    }

      cursor++;
      continue;
    }

    throw new Error(`${character} is not valid.`);
  }
  return tokens;
};

export default tokenize;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s walk through this. Firstly we define our &lt;code&gt;tokenize&lt;/code&gt; function and accept an input.&lt;/p&gt;

&lt;p&gt;Next, we create an empty array for our tokens which we’ll fill later. We also create a cursor variable which we’ll use to track our position in the input.&lt;/p&gt;

&lt;p&gt;With that initial setup done, let’s walk through the input. We’re using a while loop here since it’s fast and allows us a good deal of control over our cursor position. We could also use something like &lt;code&gt;reduce&lt;/code&gt; but we could work with some very big inputs in theory and this can give us performance issues along with making it harder to control exactly where the cursor is (but please &lt;a href="https://twitter.com/ruairidhwm"&gt;get in touch&lt;/a&gt; if you have a cool way of doing this).&lt;/p&gt;

&lt;p&gt;So we traverse the length of our input which is the code, and we assign the current position to our &lt;code&gt;character&lt;/code&gt; variable for the sake of legibility.&lt;/p&gt;

&lt;p&gt;Time to run our first check! We want to see if it is an opening or closing parenthesis. To do this, we use our &lt;code&gt;isParenthesis&lt;/code&gt; helper and if so, we push an object to our &lt;code&gt;tokens&lt;/code&gt; array providing the type and value. So we could express this in a test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it("should tokenize a pair of parentheses", () =&amp;gt; {
  const input = "()"

  const result = [
    { type: "Parenthesis", value: "(" },
    { type: "Parenthesis", value: ")" },
  ]

  expect(tokenize(input)).toEqual(result)
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So now we’re capturing parentheses, we want to figure out the rest of our tokens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    if (helpers.isWhitespace(character)) {
      cursor++;
      continue;
    }

    if (helpers.isNumber(character)) {
      let number = character;

      /**
       * We want to account for multi-digit numbers, so we
       * look ahead in our string to see if the next character
       * is a number. We assume white space is the end of a number.
       */
      while (helpers.isNumber(input[++cursor])) {
        number += input[cursor];
      }

      tokens.push({
        type: 'Number',
        value: parseInt(number, 10),
      });

      continue;
    }

    if (helpers.isLetter(character)) {
      let symbol = character;

      /**
       * We want to account for words, so we look ahead in our
       * string to see if the next character is a letter.
       *
       * We assume white space is the end of a word.
       */
      while (helpers.isLetter(input[++cursor])) {
        symbol += input[cursor];
      }

      tokens.push({
        type: 'Name',
        value: symbol,
      });

      continue;
    }

    if (helpers.isQuote(character)) {
      let string = '';

      while (!helpers.isQuote(input[++cursor])) {
        string += input[cursor];
      }
      tokens.push({
        type: 'String',
        value: string,
      });

      cursor++;
      continue;
    }
    ```




&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Some of these are simple such as a check for whitespace, but others are more complex, so we’ll dig into these.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tokenizing Digits
&lt;/h3&gt;

&lt;p&gt;Tokenizing a single digit is pretty straightforward, but it becomes more complex with multi-digit numbers. If we didn’t take this into account, we could have &lt;code&gt;101&lt;/code&gt; as an input but it would be split into &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;. This could be pretty disastrous for our tiny language!&lt;/p&gt;

&lt;p&gt;So instead we need to look ahead of our current character and see if the next item is a number as well. If so, we can assume that it is a continuous number. So we introduce a &lt;code&gt;while&lt;/code&gt; loop and increment our cursor to see that the next character is a number. If so, we append it to our current &lt;code&gt;number&lt;/code&gt; variable, until we reach the end of the number.&lt;/p&gt;

&lt;p&gt;As some example tests, we can do this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

it("should tokenize a single digit", () =&amp;gt; {
  const input = "3"
  const result = [{ type: "Number", value: 3 }]

  expect(tokenize(input)).toEqual(result)
})

it("should tokenize a continuous number", () =&amp;gt; {
  const input = "33"
  const result = [{ type: "Number", value: 33 }]

  expect(tokenize(input)).toEqual(result)
})


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Tokenizing Words
&lt;/h2&gt;

&lt;p&gt;The logic for tokenizing a word is more or less the same here so you can refer to the same logic, but for an example test:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

it("should tokenize a continuous Name", () =&amp;gt; {
  const input = "abc"
  const result = [{ type: "Name", value: "abc" }]

  expect(tokenize(input)).toEqual(result)
})


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Tokenizing Quotes
&lt;/h2&gt;

&lt;p&gt;Finally, we want to be able to handle strings inside quotes. There are a few gotchas here which haven’t been implemented, like parsing single and double quotes and escaping strings, but for our purposes it works fine.&lt;/p&gt;

&lt;p&gt;In this case we don’t really care about the quotation marks other than the fact they operate as boundaries for the beginning and end of a quoted string. To account for this, we inverse the logic and for every item which is &lt;em&gt;not&lt;/em&gt; a quote mark, we add it to our &lt;code&gt;string&lt;/code&gt; variable. When we hit our closing quotation, the loop breaks and we continue to iterate the tokenizer.&lt;/p&gt;

&lt;p&gt;As a simple test, we could run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

it("should handle a quoted string", () =&amp;gt; {
  const input = '"hello"'

  const result = [{ type: "String", value: "hello" }]

  expect(tokenize(input)).toEqual(result)
})


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Finished Result
&lt;/h3&gt;

&lt;p&gt;All in, your code should look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import helpers from "./helpers"

const tokenize = input =&amp;gt; {
  const tokens = []

  let cursor = 0

  while (cursor &amp;lt; input.length) {
    const character = input[cursor]

    if (helpers.isParenthesis(character)) {
      tokens.push({
        type: "Parenthesis",
        value: character,
      })
      cursor++
      continue
    }

    if (helpers.isWhitespace(character)) {
      cursor++
      continue
    }

    if (helpers.isNumber(character)) {
      let number = character

      /**
       * We want to account for multi-digit numbers, so we
       * look ahead in our string to see if the next character
       * is a number. We assume white space is the end of a number.
       */
      while (helpers.isNumber(input[++cursor])) {
        number += input[cursor]
      }

      tokens.push({
        type: "Number",
        value: parseInt(number, 10),
      })

      continue
    }

    if (helpers.isLetter(character)) {
      let symbol = character

      /**
       * We want to account for words, so we look ahead in our
       * string to see if the next character is a letter.
       *
       * We assume white space is the end of a word.
       */
      while (helpers.isLetter(input[++cursor])) {
        symbol += input[cursor]
      }

      tokens.push({
        type: "Name",
        value: symbol,
      })

      continue
    }

    if (helpers.isQuote(character)) {
      let string = ""

      while (!helpers.isQuote(input[++cursor])) {
        string += input[cursor]
      }
      tokens.push({
        type: "String",
        value: string,
      })

      cursor++
      continue
    }

    throw new Error(`${character} is not valid.`)
  }
  return tokens
}

export default tokenize


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;And…that’s pretty much it! Although a &lt;em&gt;lexical analysis tool&lt;/em&gt; sounds pretty tricky, the basic version is actually quite simple to make.&lt;/p&gt;

&lt;p&gt;Don’t be fooled though, to build an actually useful one would take a lot of time and effort. Yes, JavaScript was famously written in ten days, but that’s more a testament to Brendan Eich’s skill than the complexity of the task. This stuff really is hard!&lt;/p&gt;

&lt;p&gt;With that said, we’ve done a good job today. Going from zero to a functional lexer is no mean feat and we got there!&lt;/p&gt;

&lt;p&gt;Next step is to write an AST to break the code into a more meaningful structure so that we can see what our tokens want to achieve, and then transpile this into JavaScript, and we will do precisely that in another post.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>compsci</category>
    </item>
    <item>
      <title>Building a Jest Clone</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Wed, 13 May 2020 14:52:20 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/building-a-jest-clone-1ohb</link>
      <guid>https://dev.to/ruairidhwm/building-a-jest-clone-1ohb</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I use Jest nearly every day when working, and it’s a fantastic tool. It lets me ship my code with confidence, knowing that I have produced something which works as intended.&lt;/p&gt;

&lt;p&gt;More often than not, when I write tests for my code, I end up catching something I hadn’t considered and go back to take that into account. It saves me from getting getting called in the evening to fix something in production. For me, that’s a big deal.&lt;/p&gt;

&lt;p&gt;With that said, I didn’t really know how jest &lt;em&gt;worked&lt;/em&gt;. I used it all the time, but had no real clue what was going on under the hood.&lt;/p&gt;

&lt;p&gt;Recently, I bought Kent C Dodd’s excellent &lt;a href="https://testingjavascript.com/"&gt;Testing JavaScript&lt;/a&gt; course which has been incredible for increasing my knowledge.&lt;/p&gt;

&lt;p&gt;As part of that, he digs into how jest works under the hood, and this encouraged me to try building my own tiny version. So I want to pass on that knowledge to you!&lt;/p&gt;

&lt;p&gt;This will be a small series of posts on each part, but you can skip ahead and see the full repo &lt;a href="https://github.com/ruairidhwm/quip"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building our test runner
&lt;/h1&gt;

&lt;p&gt;Today’s focus will be building the actual test runner. This simply accepts a &lt;code&gt;test&lt;/code&gt; with a title, and a callback. We run the callback and if there are no errors, the test passes!&lt;/p&gt;

&lt;p&gt;If an error is thrown, then we deem the test to have failed.&lt;/p&gt;

&lt;p&gt;Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const test = async (title: string, callback: Function) =&amp;gt; {
  try {
    await callback();

    console.log(chalk.green(`\u2713 ${title}`));
  } catch (error) {
    console.error(chalk.red(`✕ ${title}`));

    console.error(error);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So as you can see, we have our &lt;code&gt;test&lt;/code&gt; function which accepts a &lt;code&gt;title&lt;/code&gt; which is a string, and a &lt;code&gt;callback&lt;/code&gt; which is the function which we want to test.&lt;/p&gt;

&lt;p&gt;We then run our callback function in a &lt;code&gt;try/catch&lt;/code&gt; block, and assuming that nothing is caught, we say the test has passed.&lt;/p&gt;

&lt;p&gt;This allows us to run 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;test("sum adds numbers", () =&amp;gt; {
  const sum = (a, b) =&amp;gt; a + b

  const result = sum(3, 7)

  const expected = 10

  expect(result).toBe(expected)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So as you can see, we pass a title, and a function where we sum two numbers: &lt;code&gt;3&lt;/code&gt; and &lt;code&gt;7&lt;/code&gt;. But on our final line, we see something new: &lt;code&gt;expect&lt;/code&gt; and &lt;code&gt;toBe&lt;/code&gt;. These are our assertions and we have nothing to handle them yet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building our assertions
&lt;/h1&gt;

&lt;p&gt;Fundamentally, an assertion is a very simple concept of whether two inputs match. Does &lt;code&gt;sum(3,7)&lt;/code&gt; result in &lt;code&gt;10&lt;/code&gt;? We don’t want to have to write logic like this for everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (sum(3, 7) !== 10) {
  throw new Error("Sums do not match")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, we want to extract this out to a helper utility we will call &lt;code&gt;expect&lt;/code&gt;, much like as you see in jest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const expect = (actual: Function) =&amp;gt; {
  return {
    toBe(expected: String | Object | Array) {
      if (actual !== expected) {
        throw new Error(`${actual} is not equal to ${expected}`)
      }
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we take in a function which is what we are running our assertion on. We then have a series of methods on a returned object allowing us to expand our test matchers later.&lt;/p&gt;

&lt;p&gt;In this case we are wanting a simple &lt;code&gt;toBe&lt;/code&gt; test for an exact match. So we accept a variable called &lt;code&gt;expected&lt;/code&gt; on &lt;code&gt;toBe&lt;/code&gt; and compare that to the result of our function that we passed in earlier.&lt;/p&gt;

&lt;p&gt;Going back to our previous example where we add &lt;code&gt;3&lt;/code&gt;, and &lt;code&gt;7&lt;/code&gt;, we can do 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;expect(sum(3, 7)).toBe(10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple right? Although jest itself is a far more complex tool, this is more or less how it works. We can extend our matchers as well. For example, if we wanted to check for a falsy value, we could do 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;  toBeFalsy() {
      if (actual) {
        throw new Error(`${actual} is not falsy.`);
      }
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, our &lt;code&gt;expect&lt;/code&gt; function can easily be extended to cater for whatever assertions you need to make.&lt;/p&gt;

&lt;p&gt;Putting it together, you can access it within our test runner and the above code will return:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;✅ sum adds numbers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that’s it! You’ve just made a very, very simple test runner with some assertions. In the next post in this series, I’ll be showing you how to write your own test mocks which allow you to simulate function calls so that you don’t run them in reality. It’s a very useful technique.&lt;/p&gt;

&lt;p&gt;If you want to see the full code, just take a look at the &lt;a href="https://github.com/ruairidhwm/quip"&gt;repo&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>jest</category>
      <category>tdd</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Create a COVID-19 tracker in React</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Tue, 21 Apr 2020 14:52:20 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/create-a-covid-19-tracker-in-react-1d8l</link>
      <guid>https://dev.to/ruairidhwm/create-a-covid-19-tracker-in-react-1d8l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At the time of writing, there are 2,494,915 confirmed COVID-19 cases worldwide. Many more are expected, and a huge number of people are confined to their homes. It’s grim news, and it’ll take time to get better.&lt;/p&gt;

&lt;p&gt;With that said, it’s not a bad time to try and improve your skills if you’re in the right headspace to do so. It’s completely understandable if not though, these are stressful times and there is no expectation that you should be doing anything than getting through this.&lt;/p&gt;

&lt;p&gt;If you’d like to learn how to make a cool COVID-19 heatmap in React, read below! If you want to skip directly to the full code, click &lt;a href="https://github.com/ruairidhwm/covid-visualiser"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project setup
&lt;/h2&gt;

&lt;p&gt;To keep this simple, we’re going to use &lt;code&gt;create-react-app&lt;/code&gt; to get started. Run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app covid-tracker &amp;amp;&amp;amp; cd covid-tracker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will allow you to use &lt;code&gt;create-react-app&lt;/code&gt; without having to install it to your system, create a project called &lt;code&gt;covid-tracker&lt;/code&gt; and enter the directory.&lt;/p&gt;

&lt;p&gt;You’ll see plenty of boilerplate code which you can ignore for now. Go to &lt;code&gt;src/App.js&lt;/code&gt; and clear the code in the &lt;code&gt;return ()&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;First let’s get hold of some data. To do this, we’ll use the free &lt;a href="https://corona.lmao.ninja"&gt;Corona API&lt;/a&gt;. I’m specifically using the &lt;code&gt;/v2/countries&lt;/code&gt; endpoint. This shows the latitude and longitude of each country where a COVID-19 case is present, and some statistics.&lt;/p&gt;

&lt;p&gt;To pull this data into our component, we want to load it on the first render so that we have access to the data in our map. To do so, we take advantage of the &lt;a href="https://reactjs.org/docs/hooks-effect.html"&gt;&lt;code&gt;useEffect&lt;/code&gt;&lt;/a&gt; hook. This is pretty close to the lifecycle methods we previously had such as &lt;code&gt;ComponentWillMount&lt;/code&gt; and &lt;code&gt;ComponentDidMount&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our effect will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [getCases, setCases] = useState(undefined)
const [loading, setLoading] = useState(true)
/**
 * Get our data on the first render, and prevent from
 * fetching on subsequent renders. If our request fails
 * or takes too long, then clean up.
 */
useEffect(() =&amp;gt; {
  let isCancelled = false
  let source = axios.CancelToken.source()
  function getFetchUrl() {
    return "https://corona.lmao.ninja/v2/countries"
  }
  async function fetchData() {
    let result
    if (!isCancelled) {
      result = await axios(getFetchUrl())
    }
    setCases(result.data)
    setLoading(false)
  }

  fetchData()

  return () =&amp;gt; {
    isCancelled = true
    source.cancel("Cancelling in cleanup")
  }
}, [])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s break this down. So firstly we declare that we’re using a hook, &lt;code&gt;useEffect&lt;/code&gt;. Then we create a variable &lt;code&gt;isCancelled&lt;/code&gt;. This will become useful down the line for cleaning up our operation.&lt;/p&gt;

&lt;p&gt;If the operation isn’t cancelled, we then use &lt;code&gt;axios&lt;/code&gt; (a popular data-fetching library) to asynchronously fetch our endpoint. We have to declare this as its own function inside the &lt;code&gt;useEffect&lt;/code&gt; hook as asynchronous functions return a promise, which the hook doesn’t expect. Instead, the hook expects that either nothing is returned, or a function is returned.&lt;/p&gt;

&lt;p&gt;In the future, using React Suspense will remove this issue but for now, this is the workaround.&lt;/p&gt;

&lt;p&gt;Once the resource is fetched, we update our state with the data returned, and set loading to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We also have a function below this which acts as our cleanup. This effectively acts as &lt;code&gt;ComponentWillUnmount&lt;/code&gt; and we use this to cancel our axios request mid-flight.&lt;/p&gt;

&lt;p&gt;Finally, we pass an empty array as an optional argument to &lt;code&gt;useEffect&lt;/code&gt; which prevents it from triggering each time the component renders.&lt;/p&gt;

&lt;p&gt;Ok, so now we have some data. We now need to convert it to GeoJSON to be displayed in &lt;code&gt;react-map-gl&lt;/code&gt;. To do this, we’re going to write a quick utility function to transform our current data into the appropriate format.&lt;/p&gt;

&lt;p&gt;Create a folder called &lt;code&gt;utils&lt;/code&gt; and add &lt;code&gt;makeGeoJSON.js&lt;/code&gt; to it. The code is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const makeGeoJSON = data =&amp;gt; {
  return {
    type: "FeatureCollection",
    features: data.map(feature =&amp;gt; {
      return {
        type: "Feature",
        properties: {
          id: feature.countryInfo?._id,
          value: feature.cases,
        },
        geometry: {
          type: "Point",
          coordinates: [feature.countryInfo.long, feature.countryInfo.lat],
        },
      }
    }),
  }
}

export default makeGeoJSON
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This takes in our data as a variable, and we map over each item in the array to add its coordinates. We now have valid GeoJSON!&lt;/p&gt;

&lt;p&gt;In our main script, we want to pass our data to our new utility function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Convert our JSON to GeoJSON
let data
if (!loading) {
  data = makeGeoJSON(getCases)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, we want to add this to the map! First, add the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-map-gl axios
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Firstly, we need to set some default parameters for our map on its initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Set our initial map variables
const [viewport, setViewport] = useState({
  latitude: 55.8609825,
  longitude: -4.2488787,
  zoom: 4,
  width: "100vw",
  height: "100vh",
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This simply sets the initial latitude and longitude to Glasgow, Scotland (where I live) but you can make it whatever you want. Then we set a zoom level (smaller being further our, larger being closer in).&lt;/p&gt;

&lt;p&gt;Finally we set the default height and width which I’ve just made the whole page.&lt;/p&gt;

&lt;p&gt;Now we have our map, we can render it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  return (
  &amp;lt;div className="App"&amp;gt;
    {loading &amp;amp;&amp;amp; &amp;lt;h1&amp;gt;Loading&amp;lt;/h1&amp;gt;}
    {!loading &amp;amp;&amp;amp; (
      &amp;lt;ReactMapGL
        {...viewport}
        mapboxApiAccessToken={process.env.REACT_APP_MAPBOX_TOKEN}
        onViewportChange={(viewport) =&amp;gt; setViewport(viewport)}
        mapStyle="mapbox://styles/mapbox/dark-v9"
      &amp;gt;
        &amp;lt;Source type="geojson" data={data}&amp;gt;
            &amp;lt;Layer {...heatMapLayer} /&amp;gt;
        &amp;lt;/Source&amp;gt;
      &amp;lt;/ReactMapGL&amp;gt;
    )}
  &amp;lt;/div&amp;gt;
);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is fairly self-explanatory but as you can see:&lt;/p&gt;

&lt;p&gt;We check the loading state, and display an appropriate holding message while we load our data.&lt;/p&gt;

&lt;p&gt;If we are not loading the data, then we render the map with the default map variables, and pass it our token (which you can create for free on &lt;a href="https://mapbox.com"&gt;Mapbox&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We then add a method &lt;code&gt;onViewportChange&lt;/code&gt; which is provided by &lt;code&gt;react-map-gl&lt;/code&gt; and allows us to make the map interactive. It provides us with the &lt;code&gt;viewport&lt;/code&gt; variable which contains the lat/lng/zoom etc and we simply update our state with that data.&lt;/p&gt;

&lt;p&gt;Finally we add a mapStyle. There are many online but I just went with a simple dark theme from mapbox.&lt;/p&gt;

&lt;p&gt;Once we have rendered the map, we then pass it a custom layer. This uses &lt;code&gt;heatMapLayer&lt;/code&gt; which we will now create in our &lt;code&gt;utils&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MAX_ZOOM_LEVEL = 9

const heatMapLayer = {
  maxzoom: MAX_ZOOM_LEVEL,
  type: "heatmap",
  threshold: 0.03,
  radiusPixels: 30,
  paint: {
    // Increase the heatmap weight based on frequency and property magnitude
    "heatmap-weight": ["interpolate", ["linear"], ["get", "mag"], 0, 0, 6, 1],
    // Increase the heatmap color weight weight by zoom level
    // heatmap-intensity is a multiplier on top of heatmap-weight
    "heatmap-intensity": [
      "interpolate",
      ["linear"],
      ["zoom"],
      0,
      1,
      MAX_ZOOM_LEVEL,
      80,
    ],
    // Color ramp for heatmap. Domain is 0 (low) to 1 (high).
    // Begin color ramp at 0-stop with a 0-transparancy color
    // to create a blur-like effect.
    "heatmap-color": [
      "interpolate",
      ["linear"],
      ["heatmap-density"],
      0,
      "rgba(10,0,0,0)",
      0.2,
      "rgb(100,0,0)",
      0.4,
      "rgb(120,0,0)",
      0.6,
      "rgb(1300,0,0)",
      0.8,
      "rgb(140,0,0)",
      2.1,
      "rgb(255,0, 0)",
    ],
    // Adjust the heatmap radius by zoom level
    "heatmap-radius": [
      "interpolate",
      ["linear"],
      ["zoom"],
      0,
      2,
      MAX_ZOOM_LEVEL,
      30,
    ],
    // Transition from heatmap to circle layer by zoom level
    "heatmap-opacity": ["interpolate", ["linear"], ["zoom"], 7, 1, 9, 0],
  },
}

export default heatMapLayer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is from &lt;a href="https://github.com/visgl/react-map-gl/blob/master/examples/heatmap/src/map-style.js"&gt;Uber’s example&lt;/a&gt;. I just customised it a bit for sizing and to have a red colour. You can easily customise this to your needs.&lt;/p&gt;

&lt;p&gt;Your full code in &lt;code&gt;App.js&lt;/code&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "axios"
import React, { useEffect, useState } from "react"
import ReactMapGL, { Layer, Source } from "react-map-gl"
import { heatMapLayer, makeGeoJSON } from "./utils"

function App() {
  const [getCases, setCases] = useState(undefined)
  const [loading, setLoading] = useState(true)

  // Set our initial map variables
  const [viewport, setViewport] = useState({
    latitude: 55.8609825,
    longitude: -4.2488787,
    zoom: 4,
    width: "100vw",
    height: "100vh",
  })

  /**
   * Get our data on the first render, and prevent from
   * fetching on subsequent renders. If our request fails
   * or takes too long, then clean up.
   */
  useEffect(() =&amp;gt; {
    let isCancelled = false
    let source = axios.CancelToken.source()
    function getFetchUrl() {
      return "https://corona.lmao.ninja/v2/countries"
    }
    async function fetchData() {
      let result
      if (!isCancelled) {
        result = await axios(getFetchUrl())
      }
      setCases(result.data)
      setLoading(false)
    }

    fetchData()

    return () =&amp;gt; {
      isCancelled = true
      source.cancel("Cancelling in cleanup")
    }
  }, [])

  // Convert our JSON to GeoJSON
  let data
  if (!loading) {
    data = makeGeoJSON(getCases)
  }

  return (
    &amp;lt;div className="App"&amp;gt;
      {loading &amp;amp;&amp;amp; &amp;lt;h1&amp;gt;Loading&amp;lt;/h1&amp;gt;}
      {!loading &amp;amp;&amp;amp; (
        &amp;lt;ReactMapGL
          {...viewport}
          mapboxApiAccessToken={process.env.REACT_APP_MAPBOX_TOKEN}
          onViewportChange={viewport =&amp;gt; setViewport(viewport)}
          mapStyle="mapbox://styles/mapbox/dark-v9"
        &amp;gt;
          &amp;lt;Source type="geojson" data={data}&amp;gt;
            &amp;lt;Layer {...heatMapLayer} /&amp;gt;
          &amp;lt;/Source&amp;gt;
        &amp;lt;/ReactMapGL&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now this is completed, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And you will see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/dcc08f1892e28e93c5091041b659b3fc/0775d/covid.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gl_0QiGU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ruairidh.dev/static/dcc08f1892e28e93c5091041b659b3fc/b9e4f/covid.png" alt="'Screenshot of COVID tracker'" title="'Screenshot of COVID tracker'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, you can easily add more context to the heatmap, further data such as US county data, or change the styling.&lt;/p&gt;

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

&lt;p&gt;As you can see, it’s very easy to get up and running with &lt;code&gt;react-map-gl&lt;/code&gt; and a basic dataset. There are so many excellent data sources, and being able to see them visually is a very powerful technique.&lt;/p&gt;

&lt;p&gt;If you want a to see the full code, click &lt;a href="https://github.com/ruairidhwm/covid-visualiser"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Made something cool by following this guide? Tweet me &lt;a href="https://twitter.com/ruairidhwm"&gt;@ruairidhwm&lt;/a&gt; and let me know!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>dataviz</category>
    </item>
    <item>
      <title>How to understand a new codebase</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Sat, 18 Jan 2020 16:00:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/how-to-understand-a-new-codebase-1lk6</link>
      <guid>https://dev.to/ruairidhwm/how-to-understand-a-new-codebase-1lk6</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;We’ve all been there. You’ve started a new job, or been assigned to a new project. All of a sudden, you’re looking at an existing codebase which has been worked on by many people. Not all of them are still working at the company. There are thousands of files, hundreds of thousands of lines of code, and you understand precisely none of it.&lt;/p&gt;

&lt;p&gt;Sound familiar?&lt;/p&gt;

&lt;p&gt;This is a particularly daunting situation when you’re a junior software engineer, or you’re wanting to make a good first impression in a new job. You want to feel like you’re competent, and that you’re making a valuable contribution to your team. But where to start?&lt;/p&gt;

&lt;p&gt;This post is a collection of tips I’ve used in various roles and projects. This is my personal approach to reviewing a new codebase, but I’d love to hear about anything you’d suggest though, so reach out via &lt;a href="https://twitter.com/ruairidhwm"&gt;Twitter&lt;/a&gt;, or subscribe to my mailing list below!&lt;/p&gt;

&lt;h1&gt;
  
  
  Understanding a new codebase
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Why are you writing this code?
&lt;/h2&gt;

&lt;p&gt;First things first, understand what the code actually does. Not on the level of what a function returns, or how the data moves around the system, but actually what it is designed to do. Perhaps you’re working for an online marketplace, so you understand that the code is to make it easy for people to buy and sell something online. Or you’re building a notification system, so a message needs sent from one entity to another.When you understand &lt;em&gt;why&lt;/em&gt; you’re making something, then it becomes a lot easier to figure out what the code is doing, and you know what comes next. This is essential domain knowledge.&lt;/p&gt;

&lt;p&gt;A lot of companies are terrible at providing this to software engineers during on-boarding as the assumption is that you only ‘write code’. You need to know why you’re writing code, so don’t hesitate to ask about how the company works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the busiest part of the code?
&lt;/h2&gt;

&lt;p&gt;This might be a little controversial, but I think that you can learn a lot from a codebase by seeing which parts of it are the busiest. Some files don’t get touched much once created, like small utility functions, whereas areas that deal with business logic, data, and routing are far more likely to be altered on a frequent basis. These often form the ‘meat’ of the application and I like to review them first.&lt;/p&gt;

&lt;p&gt;A handy way to find out which areas of the code change the most is through the &lt;code&gt;git effort&lt;/code&gt; command in &lt;a href="https://github.com/tj/git-extras"&gt;Git Extras&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This shows you the number of commits per file which shows where the most activity is. You quickly get a visual overview of the codebase’s activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What has come before?
&lt;/h2&gt;

&lt;p&gt;Now that you’ve had a look around some of the busier parts of the codebase, it’s time to see what activity there has been in the repo. If your team is disciplined then you should have informative commit messages, pull requests, and a strong code review culture.&lt;/p&gt;

&lt;p&gt;I start with the pull requests to see how features have taken shape, and the comments provide a lot of context in terms of &lt;em&gt;why&lt;/em&gt; some code has come to be there. How often have you looked at some lines of code and wondered what drove an engineer to write it that way?&lt;/p&gt;

&lt;p&gt;Before you criticise either internally or externally (something I have been guilty of in the past), take the time to try to understand why it ended up that way. Yeah, the author might have been incompetent, or, more likely, there was a particular reason for the code ending up like that.&lt;/p&gt;

&lt;p&gt;I try to look at the last few months of activity to see what has been prioritised, and what hasn’t. Hopefully there’s discussion in the repo about the approach, tradeoffs, and what is left to do. Even better if your team uses an issue tracker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;This is a great place to see the logic in action. Depending on the size of your codebase, there may be thousands of tests, so I’m not saying check them all. It’s worthwhile however to see how the tests have been written and what the coverage looks like.&lt;/p&gt;

&lt;p&gt;Also, tests are a brilliant way to get involved with the codebase in a non-blocking way. You can improve test coverage which forces you to start working within the application’s logic and ensure that you get it right in order to have your test pass.&lt;/p&gt;

&lt;p&gt;By writing some tests, you expose yourself to many different parts of the codebase and get to follow the logic around through various files which increases familiarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database structure
&lt;/h2&gt;

&lt;p&gt;I find it helpful to have a look at how the database is structured in order to give more context to the way the application is written. Are we using a relational or non-relational structure? Are we using something like a graph database?&lt;/p&gt;

&lt;p&gt;Understanding how data is structured and stored gives you more confidence when it comes to processing and transforming the data within your application. You can anticipate how it will be handled down the line, and allow you to write more performant code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talk to your colleagues
&lt;/h2&gt;

&lt;p&gt;Now that you have a pretty reasonable overview of the codebase, no doubt you’ll have more specific questions. If so, now is the time to ask! If you can take a colleague out to lunch and let them know that you’d like to pick their brains on the code that’s great.&lt;/p&gt;

&lt;p&gt;If you feel that you want a less direct approach, then I find a quick email / DM asking if they could make some time to run through something with you is great.&lt;/p&gt;

&lt;p&gt;Finally, when submitting a pull request, that’s a great time to add clarifying questions or comments. It has the added benefit of preserving knowledge for the next person to come along and read the commits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write documentation
&lt;/h2&gt;

&lt;p&gt;Be the change you want to see in the world. If you felt there was information missing when you started, add it for the next person! Nobody is going to complain about having improved documentation and it is a valuable contribution to your team. It also has the added benefit of reducing the &lt;a href="https://en.wikipedia.org/wiki/Bus_factor"&gt;Bus Factor&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There are just a small collection of tips I have for people getting used to a new codebase that I’ve used in the past. There are obviously so many ways of doing this, and different things work for different people.&lt;/p&gt;

&lt;p&gt;If you have any suggestions then let me know! I’d love to hear what approaches other people take.&lt;/p&gt;

</description>
      <category>code</category>
      <category>juniordeveloper</category>
      <category>career</category>
      <category>codebase</category>
    </item>
    <item>
      <title>Stop using offset pagination</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Thu, 05 Dec 2019 18:37:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/stop-using-offset-pagination-5f9m</link>
      <guid>https://dev.to/ruairidhwm/stop-using-offset-pagination-5f9m</guid>
      <description>&lt;h2&gt;
  
  
  What is offset pagination?
&lt;/h2&gt;

&lt;p&gt;If you’ve been working with software for any length of time, you’ll be very used to consuming results from APIs. Typically you’ll make a request, and end up with a list of information which is quite long. People are usually bad at reading very long lists, so as developers, it’s good practice to shorten them to something more manageable.&lt;/p&gt;

&lt;p&gt;If you’ve used Google, you’ve seen this in action. You may have 9000 results, but you get 10 per page by default. People can handle 10. But 9000 in one go is just far too much.&lt;/p&gt;

&lt;p&gt;We achieve this result via pagination. We split all our results into a series of pages. A common (and easy) way to do this is to say to the API - “Give me the first ten results”. Then when we click on our ‘next’ button, we say, “Skip the first ten results, and serve up the next ten”. In essence, we are &lt;em&gt;offsetting&lt;/em&gt; our results by an amount of our choosing.&lt;/p&gt;

&lt;p&gt;This is particularly easy when you’re working on the frontend, but it’s actually not very efficient at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the problem with offset pagination?
&lt;/h2&gt;

&lt;p&gt;When you are working with an offset, you make your request as detailed above and receive the expected results. But from the database’s perspective it looks a bit more like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select every single row that has been requested.&lt;/li&gt;
&lt;li&gt;Now order them.&lt;/li&gt;
&lt;li&gt;Finally, drop the number of rows specified in the offset parameter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Offset only cares about how many rows you want to drop. It doesn’t care about optimising a query, so it fetches everything, then drops what has been requested. This applies across both SQL and NoSQL databases, and creates a heavy workload for the database.&lt;/p&gt;

&lt;p&gt;Ok, so we’ve seen that’s an issue, but it’s also problematic because you probably don’t work with one request at a time. What happens if a new row is created whilst you’re fetching? It turns out that offset tries to be clever and counter this by inserting duplicates in case something else was inserted during the fetch. This is a weird quirk and obviously frustrating to deal with.&lt;/p&gt;

&lt;p&gt;So when you’re coding a pagination function, you’re unlikely to be giving the database enough context to efficiently and accurately provide you with the information that you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to paginate data properly
&lt;/h2&gt;

&lt;p&gt;Ok, that’s a bold title. This is a potential way to achieve your desired result though. It’s actually simple - you can use a &lt;code&gt;WHERE&lt;/code&gt; clause to return the information that you haven’t retrieved. As shown in the &lt;a href="https://use-the-index-luke.com/no-offset"&gt;incredible article&lt;/a&gt; by Use The Index Luke on which this is based, you can achieve your desired result with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT someCol, anotherCol
  FROM someTable
 WHERE 'some_condition' &amp;gt; 1
   AND id &amp;lt; ?last_seen_id
 ORDER BY id DESC
 FETCH FIRST 10 ROWS ONLY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is called &lt;code&gt;keyset_pagination&lt;/code&gt; and it offers the advantages of being faster than &lt;code&gt;offset&lt;/code&gt; and also prevents the strange duplication of resuls, or other frustrating anomalies.&lt;/p&gt;

&lt;p&gt;There are some downsides however. You can’t go to an arbitrary page for example, so it’s a method better suited to things like infinite scrolling in a way similar to Instagram, than it is to clicking on page numbers. It’s a judgment call as to what will fit your use-case the best.&lt;/p&gt;

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

&lt;p&gt;We’ve now understood the difference between offset and keyset pagination, and the advantages and disadvantages of both. I feel that while offset pagination is convenient, there are some tradeoffs when it comes to speed and predictability. I’d be very curious to know how Google achieves this.&lt;/p&gt;

&lt;p&gt;Overall, my advice would be to use code similar to the snippet above, and avoid a simplistic offset where possible if you are concerned about performance in your application.&lt;/p&gt;

&lt;p&gt;Want to know more about this kind of stuff? Sign up to my newsletter below!&lt;/p&gt;

</description>
      <category>pagination</category>
      <category>sql</category>
      <category>database</category>
      <category>data</category>
    </item>
    <item>
      <title>React Suspense - A first look</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Wed, 06 Nov 2019 18:15:13 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/react-suspense-a-first-look-37lk</link>
      <guid>https://dev.to/ruairidhwm/react-suspense-a-first-look-37lk</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve been following the React community, then you’ll know about a hotly-anticipated feature called ‘Suspense’. This is still an experimental feature, but essentially it allows you to ‘wait’ for some code to load and specify a loading state such as a spinner whilst we’re waiting.&lt;/p&gt;

&lt;p&gt;Here’s the example that the &lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html"&gt;React documentation&lt;/a&gt; gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ProfilePage = React.lazy(() =&amp;gt; import("./ProfilePage")) // Lazy-loaded

// Show a spinner while the profile is loading
;&amp;lt;Suspense fallback={&amp;lt;Spinner /&amp;gt;}&amp;gt;
  &amp;lt;ProfilePage /&amp;gt;
&amp;lt;/Suspense&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In simple terms, this allows your components to wait for a condition to be true until they render. Most people imagine this in the context of fetching data, but it equally applies to things like images, scripts, or anything asynchronous.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the point?
&lt;/h2&gt;

&lt;p&gt;Currently, we fetch data in a number of ways - such as fetching on render. This is typically achieved through &lt;code&gt;useEffect()&lt;/code&gt; and performing our fetch operation within the effect.&lt;/p&gt;

&lt;p&gt;This means that our component renders, and the fetch operation doesn’t start till that render completes. If other components on your page depend on data being present, then this cascades down your application. The code sample that React provides is a great illustration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ProfilePage() {
  const [user, setUser] = useState(null)

  useEffect(() =&amp;gt; {
    fetchUser().then(u =&amp;gt; setUser(u))
  }, [])

  if (user === null) {
    return &amp;lt;p&amp;gt;Loading profile...&amp;lt;/p&amp;gt;
  }
  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;{user.name}&amp;lt;/h1&amp;gt;
      &amp;lt;ProfileTimeline /&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

function ProfileTimeline() {
  const [posts, setPosts] = useState(null)

  useEffect(() =&amp;gt; {
    fetchPosts().then(p =&amp;gt; setPosts(p))
  }, [])

  if (posts === null) {
    return &amp;lt;h2&amp;gt;Loading posts...&amp;lt;/h2&amp;gt;
  }
  return (
    &amp;lt;ul&amp;gt;
      {posts.map(post =&amp;gt; (
        &amp;lt;li key={post.id}&amp;gt;{post.text}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we are waiting for our user details to be fetched, then we start fetching the posts only &lt;em&gt;after&lt;/em&gt; we have fetched the user details. Each of these takes time and the user is left waiting.&lt;/p&gt;

&lt;p&gt;Or we could be clever and use something like GraphQL and fetch our data in a single step, but the user is still left waiting for this operation to complete. In the first example, we rendered, then fetched. With GraphQL, we start fetching, finish fetching, and then render.&lt;/p&gt;

&lt;p&gt;With Suspense, we make a subtle change and instead we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start fetching&lt;/li&gt;
&lt;li&gt;Start rendering&lt;/li&gt;
&lt;li&gt;Finish fetching&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This speeds everything up as the user gets a response before we’ve finished grabbing all of our data.&lt;/p&gt;

&lt;p&gt;The effect is to &lt;em&gt;stream&lt;/em&gt; the response as data becomes available and make content available sooner, rather than waiting for all data to become available before displaying it.&lt;/p&gt;

&lt;p&gt;Data that hasn’t been fetched yet simply falls back to a loading indicator. This has the added advantage that we can remove &lt;code&gt;if(loading)&lt;/code&gt; checks from our code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I use React Suspense?
&lt;/h2&gt;

&lt;p&gt;The feature is currently &lt;em&gt;experimental&lt;/em&gt; and shouldn’t be used on production systems. If you want to play around with it however, you can easily install it via&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react@experimental react-dom@experimental
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This introduces Concurrent Mode which Suspense is a part of. There are some pretty big changes involved, including the way that you render your React application.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ReactDOM from "react-dom"

ReactDOM.render(&amp;lt;App /&amp;gt;, document.getElementById("root"))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;you would now have this for your entry point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ReactDOM from "react-dom"

ReactDOM.createRoot(document.getElementById("root")).render(&amp;lt;App /&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The reason for this change is that Concurrent Mode is a pretty big change to how React works, and so you have to opt-in to it wholesale, rather than the ‘drop-in’ features of Fragments, or Context.&lt;/p&gt;

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

&lt;p&gt;Concurrent Mode and React Suspense look amazing! It’s a big paradigm shift in how we think about data and our code, and I think that it will really change the way that we perceive the responsiveness of applications. From a DX perspective, this will lead to clearer code, and encourage us to load data closer to where it’s actually being used.&lt;/p&gt;

&lt;p&gt;It’s going to be a little while until Concurrent Mode and Suspense are ready for production, but they’re already showing a lot of potential.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Building an AI-powered security camera</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Tue, 08 Oct 2019 19:45:13 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/building-an-ai-powered-security-camera-4h5f</link>
      <guid>https://dev.to/ruairidhwm/building-an-ai-powered-security-camera-4h5f</guid>
      <description>&lt;h2&gt;
  
  
  Building an AI-powered security camera
&lt;/h2&gt;

&lt;p&gt;In my spare time, I have been experimenting with the potential of facial recognition using Python. Facial recognition and computer vision are becoming much simpler thanks to high level libraries such as &lt;a href="https://github.com/ageitgey/face_recognition"&gt;Face Recognition&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My goal with this script was to see if I could make something which recognised that somebody was present, then would recognise whether it was me or not. If it was, then nothing happens - otherwise I use the computer’s text-to-speech utility to tell the intruder to ‘Go away!‘.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NzPf7dz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/ruairidhwm/facial-recognition/raw/master/facial-recognition.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NzPf7dz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/ruairidhwm/facial-recognition/raw/master/facial-recognition.gif" alt="Computer vision example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The code, and how it works
&lt;/h2&gt;

&lt;p&gt;You can see the &lt;a href="https://github.com/ruairidhwm/facial-recognition"&gt;repo&lt;/a&gt;, otherwise the script is below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;face_recognition&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cv2&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;glob&lt;/span&gt;

&lt;span class="c1"&gt;# Get a reference to webcam #0 (the default one)
&lt;/span&gt;&lt;span class="n"&gt;video_capture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VideoCapture&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;# make array of sample pictures with encodings
&lt;/span&gt;&lt;span class="n"&gt;known_face_encodings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;known_face_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;dirname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;__file__&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'people/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# make an array of all the saved jpg files' paths
&lt;/span&gt;&lt;span class="n"&gt;list_of_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'*.jpg'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="c1"&gt;# find number of known faces
&lt;/span&gt;&lt;span class="n"&gt;number_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list_of_files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list_of_files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number_files&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;'image_{}'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_image_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;list_of_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;'image_encoding_{}'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_encodings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;'image_{}'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)])[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;known_face_encodings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s"&gt;'image_encoding_{}'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;

    &lt;span class="c1"&gt;# Create array of known names
&lt;/span&gt;    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"people/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;known_face_names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize some variables
&lt;/span&gt;&lt;span class="n"&gt;face_locations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;face_encodings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;face_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Ruairidh'&lt;/span&gt;
&lt;span class="n"&gt;process_this_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Grab a single frame of video
&lt;/span&gt;    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;video_capture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Resize frame of video to 1/4 size for faster face recognition processing
&lt;/span&gt;    &lt;span class="n"&gt;small_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
&lt;/span&gt;    &lt;span class="n"&gt;rgb_small_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;small_frame&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Only process every other frame of video to save time
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;process_this_frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Find all the faces and face encodings in the current frame of video
&lt;/span&gt;        &lt;span class="n"&gt;face_locations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_locations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rgb_small_frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;face_encodings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_encodings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;rgb_small_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;face_locations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;face_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;face_encoding&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;face_encodings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# See if the face is a match for the known face(s)
&lt;/span&gt;            &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compare_faces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;known_face_encodings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;face_encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Unknown'&lt;/span&gt;

            &lt;span class="n"&gt;face_distances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face_recognition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;face_distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;known_face_encodings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;face_encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;best_match_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;face_distances&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;best_match_index&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;known_face_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;best_match_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="n"&gt;face_names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rsplit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;face_names&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="s"&gt;'Unknown'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'say Go away!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;process_this_frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;process_this_frame&lt;/span&gt;

    &lt;span class="c1"&gt;# Display the results
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;face_locations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;face_names&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Scale back up face locations since the frame we detected in was scaled to 1/4 size
&lt;/span&gt;        &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

        &lt;span class="c1"&gt;# Draw a box around the face
&lt;/span&gt;        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&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;# Draw a label with a name below the face
&lt;/span&gt;        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FILLED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;font&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FONT_HERSHEY_DUPLEX&lt;/span&gt;
        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;putText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&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;# Display the resulting image
&lt;/span&gt;    &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Video'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Hit 'q' on the keyboard to quit!
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;waitKey&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="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mh"&gt;0xFF&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'q'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="c1"&gt;# Release handle to the webcam
&lt;/span&gt;&lt;span class="n"&gt;video_capture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;destroyAllWindows&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, it’s a pretty short script! To achieve the desired goal however, it needs to do four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Establish whether there are any faces present.&lt;/li&gt;
&lt;li&gt;Create a ‘map’ of the face and transform it to centre it as much as possible.&lt;/li&gt;
&lt;li&gt;Encode the face through an embedding (more on this later).&lt;/li&gt;
&lt;li&gt;Compare the embedding to that of a previously recognised face.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you save a photo of yourself in ‘people’ and run this, the script will draw a boundary box over your face, labelled with your name. Otherwise, it will tell anyone else to go away!&lt;/p&gt;

&lt;h2&gt;
  
  
  How face detection works
&lt;/h2&gt;

&lt;p&gt;Face detection is &lt;em&gt;everywhere&lt;/em&gt;. It’s on your phone’s camera to help with focusing, it’s used by Snapchat for all those fun filters, and when Facebook suggests who is in a photo, it’s all face detection.&lt;/p&gt;

&lt;p&gt;So how does it work? A typical process is to convert the image to black and white since we don’t need colours to recognise a face. Then we can look at every single pixel of the image and note the surrounding pixels. We figure out in which direction the image becomes darker, and then draw an arrow in that direction, this arrow is known as a &lt;em&gt;gradient&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This allows us to make meaningful comparisons of faces, even with light differences. Since the direction of the gradient will remain the same in different conditions, we end up with the same representation of the face.&lt;/p&gt;

&lt;p&gt;Ok, but isn’t that a bit computationally heavy? Instead we can split the image into segments and set a gradient for the direction in which we have the most incidences.&lt;/p&gt;

&lt;p&gt;This is known as a &lt;a href="https://en.wikipedia.org/wiki/Histogram_of_oriented_gradients"&gt;Histogram of oriented gradients&lt;/a&gt;, or HOG for short.&lt;/p&gt;

&lt;h2&gt;
  
  
  How face mapping works
&lt;/h2&gt;

&lt;p&gt;So we can now detect there is a face present somewhere. But how do we handle the fact that different photos contain a multitude of poses, and it’s not like a series of passport photos where you get the same predictable pose and expression.&lt;/p&gt;

&lt;p&gt;Well, we can adjust the positioning of the face itself so that it’s roughly in the same place. It’s kind of creating that passport standard, but with any photo.&lt;/p&gt;

&lt;p&gt;To achieve this, a technique called face landmark estimation is used which creates a series of data points, or ‘landmarks’ that exist on nearly every face. Things like the space between eyes, the end of your chin, the edges of your brow, etc. Then our machine learning algorithm will look for those datapoints in order to make comparisons between faces and make predictions.&lt;/p&gt;

&lt;p&gt;Now we can find out where the features are, we edit the image to place them as close to the centre as possible. It’s important to note that no 3d transforms happen to the image as that would warp it and ruin our comparisons. Instead we use things like rotation and scaling.&lt;/p&gt;

&lt;h2&gt;
  
  
  How encoding a face works
&lt;/h2&gt;

&lt;p&gt;Now that we have our face positioned nicely, we want to extract a few basic measurements so that we can then find the face with the closest measurements, and so be most likely to be our match. People do this intuitively since we have evolved to do so.&lt;/p&gt;

&lt;p&gt;Computers are less able to do this, and so we rely on deep learning to allow the computer to come up with its own way of recognising a face. This approach was previously used by &lt;a href="https://www.cv-foundation.org/openaccess/content_cvpr_2015/app/1A_089.pdf"&gt;Google researchers&lt;/a&gt;. For those that don’t want to spend a ton of time doing this themselves, there’s a handy dataset called &lt;a href="https://cmusatyalab.github.io/openface/"&gt;OpenFace&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How facial recognition works
&lt;/h2&gt;

&lt;p&gt;Now that we have our detected and embedded photos, we want to check if there’s a match! This is one of the easiest parts as it’s a simple classification problem. We provide the embedding of our new face and see if we can categorise it with one of our previously known faces. The closest match is then returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  In practice
&lt;/h2&gt;

&lt;p&gt;If you’re really into this, then you could implement it yourself, otherwise you could use the excellent &lt;a href="https://github.com/ageitgey/face_recognition#face-recognition"&gt;Face Recognition&lt;/a&gt; python library. The creator of the library has written an &lt;a href="https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78"&gt;excellent article&lt;/a&gt; on the process which inspired this one to solidify my own learning.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>computervision</category>
      <category>python</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Cleaner error handling in Javascript</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Tue, 08 Oct 2019 17:00:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/cleaner-error-handling-in-javascript-2igd</link>
      <guid>https://dev.to/ruairidhwm/cleaner-error-handling-in-javascript-2igd</guid>
      <description>&lt;h2&gt;
  
  
  Providing clearer error messages in Javascript
&lt;/h2&gt;

&lt;p&gt;As developers, we come across errors every single day. We don’t want to see errors, and we definitely don’t want to introduce them - but sadly it’s an everyday part of the job. So why is it that so many errors lack proper context, and look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uncaught Error: Cannot read property 'foo' in Bar at &amp;lt;anonymous&amp;gt;:1:7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ugh. So now we have a vague idea that maybe we’re calling an undefined property on an object, but we’re relying on our developer to have provided sensible variable names, and using our own domain knowledge of the application to infer exactly where the error is coming from. It’s not ideal.&lt;/p&gt;

&lt;p&gt;When we’re creating our own applications, a good developer is conscious of what information they return to the end user (which may be another developer) at all times. This is something done well by some of the best API providers out there, such as Stripe or Twilio. In the &lt;a href="https://stripe.com/docs/api/errors"&gt;Stripe API documentation&lt;/a&gt;, you have a clear expectation of exactly what an error is going to look like, and have a good idea of how to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to write better error messages
&lt;/h2&gt;

&lt;p&gt;Firstly, consider exactly what happened, and where. Let’s say that you are trying to let a user reset their password, and want to check whether their token has expired yet. Your code might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (isExpired(new Date(user.passwordTokenExpiry))) {
  throw new Error("invalid token")
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is no context as to what the token is. A JWT? Password reset token? Maybe something else. The developer (and by extension, the user) consuming this error is none the wiser. Separately, the developer who needs to look at this later, won’t know where the error is coming from. It provides a poor developer experience.&lt;/p&gt;

&lt;p&gt;So how to fix this? Well, custom error classes to the rescue! As seen in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error"&gt;mdn documentation&lt;/a&gt; you can extend the Error object provided by javascript to create your own ones with far more context. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PasswordTokenError extends Error {
  constructor(message) {
    super(message)
    this.name = "PasswordTokenError"
    this.message = message
  }
  toJSON() {
    return {
      error: {
        name: this.name,
        message: this.message,
      },
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When we call this in our code, we can now provide a great deal more context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (isExpired(new Date(user.passwordTokenExpiry))) {
  throw new PasswordTokenError("Password reset token has expired")
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So an error is thrown as before, but a developer can now check what type of error has been thrown, and take action accordingly. The error returns JSON like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "error": {
    "name": "PasswordTokenError",
    "message": "Password reset token has expired"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;Although conceptually very simple, this is a really easy way to clean up your errors and make debugging a lot easier for you and other developers. It provides context and a uniform way to catch errors relating to your application.&lt;/p&gt;

&lt;p&gt;I’ve just introduced this to my code at work and am confident that it will make life a lot easier when it comes to debugging!&lt;/p&gt;

&lt;p&gt;With thanks to &lt;a href="https://medium.com/@iaincollins/error-handling-in-javascript-a6172ccdf9af"&gt;Iain Collins&lt;/a&gt; for his excellent article on this topic.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My Experience with GraphQL</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Tue, 30 Jul 2019 18:42:13 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/my-experience-with-graphql-1d44</link>
      <guid>https://dev.to/ruairidhwm/my-experience-with-graphql-1d44</guid>
      <description>&lt;h1&gt;
  
  
  What is GraphQL?
&lt;/h1&gt;

&lt;p&gt;GraphQL is described as ‘a query language for your API’. It was created by Facebook back in 2012 for use in their mobile applications, but was made open source in 2015 and has grown in popularity ever since.&lt;/p&gt;

&lt;p&gt;GraphQL is an alternative to REST architecture and allows users to specify the data they would like to receive, rather than a REST endpoint simply returning everything.&lt;/p&gt;

&lt;p&gt;An endpoint returning unnecessary data is known as ‘overfetching’ and results in requests which are larger than they need to be, the frontend needing to parse data it won’t use, and potentially a client having to perform multiple network requests until it has all the information it needs.&lt;/p&gt;

&lt;p&gt;For example, compare these two queries:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;REST Query&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /users/1
{
  name: "John Doe",
  email: "john@test.com"
  // ...more user information
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now if we also wanted to retrieve the comments of this user, we may need to perform &lt;em&gt;another&lt;/em&gt; query before we can get all the information we need. Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /users/1/comments
{
    {
        title: "I really don't like too many requests"
        body: "REST is great but sometimes makes me have to fetch a lot of data"
    },
    {
        title: "I wonder if there's another way of doing this?"
        body: "Surely this is a problem people have encountered before?"
    }
  // ...more user comments
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;GraphQL Query&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In GraphQL, things are much simpler. We can just do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  User(id: "1") {
    name
    email
    comments {
      title
      body
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above would return a single object containing all the information in just one request. It’s far more efficient and we don’t have to receive all the fields that we would otherwise need to discard had we queried a REST endpoint.&lt;/p&gt;

&lt;p&gt;Conversely, we don’t &lt;em&gt;underfetch&lt;/em&gt; either. This is when an endpoint doesn’t give us enough information so we have to make &lt;em&gt;n&lt;/em&gt; additional requests to get hold of everything that we need. For example, we may retrieve a list of 100,000 users but then need to separately request their comments.&lt;/p&gt;

&lt;p&gt;This would be an expensive operation (and probably bad design regardless of whether you’re using REST or GraphQL).&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL is a specification
&lt;/h2&gt;

&lt;p&gt;Many people imagine GraphQL to be like an ORM or a replacement database. This is not the case. It’s merely a specification that can be implemented in any language and describes a way to relate to your data. The spec is easy to read and can be checked out &lt;a href="https://graphql.org/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pros of using GraphQL
&lt;/h1&gt;

&lt;h3&gt;
  
  
  No Overfetching
&lt;/h3&gt;

&lt;p&gt;As described above, the client does not receive data that it won’t use. Instead we simply request what we need and GraphQL returns the appropriate data. This means that we have smaller payloads, more efficient use of resources, and more flexibility on the frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern
&lt;/h3&gt;

&lt;p&gt;This matters more to some people than others, but it’s undeniable that GraphQL is on the ‘cooler’ end of the developer spectrum. It is an interesting technology that has a lot of potential.&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;State of Javascript 2018&lt;/em&gt; survey, GraphQL won the ‘Highest Interest’ category with a staggering &lt;a href="https://2018.stateofjs.com/awards/#highest_interest"&gt;&lt;em&gt;87.7%&lt;/em&gt;&lt;/a&gt; of developers who have heard about GraphQL wanting to learn it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Strongly Typed
&lt;/h3&gt;

&lt;p&gt;GraphQL uses a strong type system which maps the API. Everything exposed in the API is contained in the GraphQL schema using a schema definition language. Once the schema is created, there is a single souce of truth for both the backend and the frontend and no need for translation between the two.&lt;/p&gt;

&lt;p&gt;This allows for fewer errors, validation at compile-time, and you can be certain of what you are passing to the API and receiving from it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexible
&lt;/h3&gt;

&lt;p&gt;By allowing the client to dictate the data it requires, your frontend can move a lot faster without tying up a great deal of backend resources. This is significantly better than a 1:1 matching of endpoint to request where the frontend needs to normalize a great deal of data in order to present the correct values to the end user.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cons of GraphQL
&lt;/h1&gt;

&lt;h3&gt;
  
  
  It’s New
&lt;/h3&gt;

&lt;p&gt;This isn’t necessarily a bad thing, but the ecosystem is - while growing - less mature than what is available should you choose to go with a standard REST setup.&lt;/p&gt;

&lt;p&gt;For many companies choosing the ‘boring’ option makes far more sense. There’s nothing wrong with that! For others, then GraphQL is an exciting new way to do things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complex Queries
&lt;/h3&gt;

&lt;p&gt;This is something of a ‘solved’ problem in GraphQL but it can trip people up. For example, what happens if a user (perhaps maliciously) makes a request like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  User(id: "1") {
    name
    email
    about
    address
    city
    zip
    country
    comments {
      title
      body
    }
    pictures {
      url
      order
    }
    likes {
      website {
        title
        url
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a bit of a trivial example, but you get the idea. A query can rapidly bloat and consume a lot of server resources. In a REST API you could potentially tweak each endpoint to retrieve its specific data in the most specific way.&lt;/p&gt;

&lt;p&gt;In GraphQL you can use tools like &lt;a href="https://github.com/graphql/dataloader"&gt;DataLoader&lt;/a&gt; to handle your requests via batching and caching to reduce the load on your server.&lt;/p&gt;

&lt;p&gt;Additionally you can limit the complexity of queries through Query Cost Analysis. There are a few packages which make this easier such as &lt;a href="https://github.com/pa-bru/graphql-cost-analysis"&gt;GraphQL-Cost-Analysis&lt;/a&gt; which computes the cost of the query and optionally blocks it if over a certain threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning Curve
&lt;/h3&gt;

&lt;p&gt;As GraphQL is quite new, it may take you time to get up to speed with it and figure out if its a good fit for you. Also, there are a few ‘gotchas’ that you may be unfamiliar with compared to REST. There are many resources covering these however.&lt;/p&gt;

&lt;h1&gt;
  
  
  My experience with GraphQL
&lt;/h1&gt;

&lt;p&gt;At &lt;a href="https://beatgig.com"&gt;BeatGig&lt;/a&gt; we’re using GraphQL to power our new API and my experience has been largely very positive. Although it presented a bit of a learning curve, it has allowed for very rapid development and a much quicker integration between the backend and the frontend.&lt;/p&gt;

&lt;p&gt;It’s not a silver bullet but when it comes to needing a very flexible way to query and subscribe to our data, it works well for us. There were some initial pains in the setup and understanding exactly how to map our existing functionality to GraphQL but this has gone fairly smoothly so far.&lt;/p&gt;

&lt;p&gt;Something that has benefitted us hugely however, is using &lt;a href="https://github.com/prisma/graphql-yoga"&gt;GraphQL-Yoga&lt;/a&gt;, and &lt;a href="https://prisma.io"&gt;Prisma&lt;/a&gt; which gives us a lot of the CRUD features out of the box, and has pre-configured an express server with Apollo in the case of GraphQL-Yoga.&lt;/p&gt;

&lt;p&gt;This allowed us to get up and running very quickly and development has been a very enjoyable experience since!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;GraphQL isn’t going to be for everyone, but it’s a very interesting technology that reduces some of the frustrations you may feel (particularly on the frontend) when you’re using REST endpoints.&lt;/p&gt;

&lt;p&gt;It has an intial learning curve but allows for rapid development and flexible access to your underlying data. The ecosystem is growing very quickly and a large number of developers are interested in learning it, so that ecosystem should continue to grow.&lt;/p&gt;

&lt;p&gt;Overall it’s a useful tool in any developer’s arsenal and definitely worth trying out!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>javascript</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Javascript Event Loop</title>
      <dc:creator>Ruairidh W McHardy</dc:creator>
      <pubDate>Wed, 27 Mar 2019 11:03:00 +0000</pubDate>
      <link>https://dev.to/ruairidhwm/the-javascript-event-loop-2fgk</link>
      <guid>https://dev.to/ruairidhwm/the-javascript-event-loop-2fgk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Understanding how the Event Loop Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you ever heard somebody saying that slow code is ‘blocking’? Or perhaps you’ve seen &lt;code&gt;Call Stack Limit Exceeded&lt;/code&gt; errors when you’ve been coding? What does it all mean?&lt;/p&gt;

&lt;p&gt;Well, it comes down to something called the Event Loop which is how your code is handled by the Javascript Runtime and its environment. It actually makes a lot of sense, and is useful to know - so I’ve tried to document my own learning here.&lt;/p&gt;

&lt;p&gt;I recommend checking out Philip Roberts’ &lt;a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ"&gt;excellent talk&lt;/a&gt; if you’d like more detail. It provided the inspiration for this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do things fit together?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we look at the Javascript Runtime itself (V8 in Chrome for example), you see a heap (where memory allocation happens), and the call stack.&lt;/p&gt;

&lt;p&gt;You also have Web APIs which the browser provides - things like the DOM, fetch, setTimeout etc. Then you also have the callback queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the stack?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Javascript has a single-threaded runtime which means it has a single call stack. That means technically it can only run one thing at a time.&lt;/p&gt;

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

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hi &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, how are you today?`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;greetMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;greetMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ruairidh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What does this code do? Well you can see multiple functions, which call each other.&lt;/p&gt;

&lt;p&gt;Our stack looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;greetMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ruairidh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Blocking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What happens when things are slow? Things which are slow (image processing, network requests, etc) and are on the stack can be referred to as blocking.&lt;/p&gt;

&lt;p&gt;If you had three synchronous requests in a row then you would need to wait for them to complete before anything else on the stack happens. This is a problem in browsers, as you can’t do anything else until those requests are complete. This would create a horrible user experience.&lt;/p&gt;

&lt;p&gt;So what’s the solution? Well, asynchronous callbacks. They allow you to run code and give it a callback (or function) which we can execute later. But what happens to them? This is where the event loop comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Event Loop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Javascript as a runtime can only do one thing at a time, but we can do things concurrently thanks to APIs we can access in places such as the browser. Node does effectively the same thing.&lt;/p&gt;

&lt;p&gt;When you call an asynchronous function, the relevant API picks it up and the function is popped off the stack. It’s being handled elsewhere, and the stack moves on to the next item.&lt;/p&gt;

&lt;p&gt;When your asynchronous function is completed, it pushes your code onto the task queue. The event loop then checks the stack and the task queue. If the stack is empty, then it goes to the task queue and pushes the first item there onto the stack.&lt;/p&gt;

&lt;p&gt;The Javascript Runtime then executes the code on the stack, and you receive the output.&lt;/p&gt;

&lt;p&gt;This is why the hack of using &lt;code&gt;setTimeout&lt;/code&gt; and setting the value to 0 existed. It was a way of deferring something until the stack is clear. You can now use Promises to achieve the same result but in a more efficient way.&lt;/p&gt;

&lt;p&gt;Promises have higher priority in the event loop stack as they create a ‘micro task’ and a &lt;code&gt;setTimeout&lt;/code&gt; creates a ‘macro task’ which also has a minimum delay of 4ms. Also, &lt;code&gt;setTimeout&lt;/code&gt; doesn’t provide a guaranteed time of execution, it provides a minimum time to execution. There’s a great post &lt;a href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/"&gt;here&lt;/a&gt; if you’d like to learn more.&lt;/p&gt;

&lt;p&gt;If you’d like a way of visualising this process, check out Philip Roberts’ &lt;a href="http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D"&gt;Loupe tool&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Javascript Event Loop is actually one of the simplest parts of a more complex process. It allows you to write non-blocking code in a single-threaded language and defer slower tasks to the queue while the rest of your code runs.&lt;/p&gt;

&lt;p&gt;This means that you can develop more responsive and more efficient code and not have to wait on larger operations.&lt;/p&gt;

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