<?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: Sam Jones</title>
    <description>The latest articles on DEV Community by Sam Jones (@samueldjones).</description>
    <link>https://dev.to/samueldjones</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%2F446514%2Fdd1ebe15-b504-40d6-a357-44b1f0c8c013.jpg</url>
      <title>DEV Community: Sam Jones</title>
      <link>https://dev.to/samueldjones</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samueldjones"/>
    <language>en</language>
    <item>
      <title>Run a TypeScript type check in your pre-commit hook using lint-staged + husky</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Fri, 30 Jul 2021 15:34:51 +0000</pubDate>
      <link>https://dev.to/samueldjones/run-a-typescript-type-check-in-your-pre-commit-hook-using-lint-staged-husky-30id</link>
      <guid>https://dev.to/samueldjones/run-a-typescript-type-check-in-your-pre-commit-hook-using-lint-staged-husky-30id</guid>
      <description>&lt;p&gt;A great way to prevent TypeScript compilation errors from bringing down your CI pipelines is to introduce a type check &lt;em&gt;before&lt;/em&gt; you commit your &lt;code&gt;.ts&lt;/code&gt; file changes. &lt;/p&gt;

&lt;p&gt;If you've worked with Git Hooks before, you'll probably know that one of the best combinations for running pre-commit checks is &lt;a href="https://typicode.github.io/husky/#/"&gt;husky&lt;/a&gt; and &lt;a href="https://github.com/okonet/lint-staged"&gt;lint-staged&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Together, these two packages allow you to tap into the relevant Git hook and run commands such as linting on &lt;em&gt;staged files only&lt;/em&gt;. It saves a bunch of debugging time by fixing preventable errors sooner in the development process.&lt;/p&gt;

&lt;p&gt;As a separate step, if you want to check for TypeScript type errors (note: this is different to syntax errors which ESLint picks up and fixes for you), you would typically run a command in the CLI such as &lt;code&gt;npx tsc --noEmit&lt;/code&gt; to compile the TypeScript and highlight any type errors to address.&lt;/p&gt;

&lt;p&gt;Now, the best case scenario here is that you simply pop the above TypeScript command into your lint-staged config along with anything else e.g. ESLint, and you're good to go! &lt;/p&gt;

&lt;p&gt;Oh no, it doesn't quite work as expected. The error message that you may come across looks 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;Option 'project' cannot be mixed with source files on a command line.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issue I found - and at the time of writing, &lt;a href="https://github.com/microsoft/TypeScript/issues/27379#issuecomment-425245572"&gt;it is still being discussed&lt;/a&gt; - is that lint-staged would pass each staged file to the &lt;code&gt;npx tsc&lt;/code&gt; command like &lt;code&gt;npx tsc --noEmit file1.ts file2.ts&lt;/code&gt; and that causes TypeScript to simply ignore your &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Super frustrating!&lt;/p&gt;

&lt;p&gt;Fear not however, as there is an extremely helpful tool that runs &lt;code&gt;tsc&lt;/code&gt; on specific files &lt;em&gt;without&lt;/em&gt; ignoring tsconfig.json and it's called &lt;a href="https://www.npmjs.com/package/tsc-files"&gt;tsc-files&lt;/a&gt;. As the tool's author points out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I wanted to type-check only the staged files with lint-staged.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Perfect for my use case. So, after a quick look at the docs, it was as simple as updating the lint-staged config in my &lt;code&gt;package.json&lt;/code&gt; file to use the &lt;code&gt;tsc-files&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "husky": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "**/*.ts": "tsc-files --noEmit"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Now I am able to run a TypeScript type check on all my staged files using a pre-commit hook.&lt;/p&gt;

&lt;p&gt;Tip: use the &lt;code&gt;--pretty&lt;/code&gt; flag in the &lt;code&gt;tsc&lt;/code&gt; command to add some formatting and colour to your type errors.&lt;/p&gt;

&lt;p&gt;If you have any questions on this setup or have tried different approaches, feel free to comment below or start up a convo over on &lt;a href="https://twitter.com/samueldjones"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading 👋 &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>git</category>
    </item>
    <item>
      <title>Create simple and stylish notifications in React using react-toastify</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Mon, 29 Mar 2021 15:52:26 +0000</pubDate>
      <link>https://dev.to/samueldjones/how-to-create-simple-and-stylish-notifications-using-react-toastify-3hgm</link>
      <guid>https://dev.to/samueldjones/how-to-create-simple-and-stylish-notifications-using-react-toastify-3hgm</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;While working on my latest side project, &lt;a href="https://code-anagrams.netlify.app"&gt;Code Anagrams&lt;/a&gt;, I wanted to display a notification whenever a user correctly answered an anagram as well as to display error messages a little more elegantly. At my current job, we use &lt;a href="https://www.npmjs.com/package/react-toastify"&gt;react-toastify&lt;/a&gt; for notifications and alerts, so I decided to reach for this package again and document my journey of configuring and implementing this particular solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;Let's get started then. &lt;/p&gt;

&lt;p&gt;More often than not, we need to implement notifications/alerts in multiple places within our codebase, so this is a perfect use case to create a util - let's call it "toast" - that we can simply import and use in various components.&lt;/p&gt;

&lt;p&gt;In a &lt;code&gt;utils&lt;/code&gt; folder, create a folder called &lt;code&gt;toast&lt;/code&gt; and add an &lt;code&gt;index.js&lt;/code&gt; file. For our first step, we will need to install our npm package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i react-toastify --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and import it (along with associated CSS) to our &lt;code&gt;index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

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

&lt;/div&gt;



&lt;p&gt;Fortunately, react-toastify provides you with a ton of versatility and you can configure your notifications in various ways, which is great. But for the purposes of this tutorial, I'll just set a couple of defaults for &lt;code&gt;autoClose&lt;/code&gt; and &lt;code&gt;position&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

toast.configure({ autoClose: 2000, position: toast.POSITION.BOTTOM_CENTER });

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

&lt;/div&gt;



&lt;p&gt;Next, let's create our functions that render a successful notification (green) and an error alert (red):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

toast.configure({ autoClose: 2000, position: toast.POSITION.BOTTOM_CENTER });

// add more config via the options object
const successToast = (message, options = {}) =&amp;gt;
  toast.success(message, {
    ...options,
  });

const errorToast = (message, options = {}) =&amp;gt;
  toast.error(message, {
    ...options,
  });

export { successToast, errorToast };

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

&lt;/div&gt;



&lt;p&gt;And there we have it! You can now import this util into your component 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;import { successAlert, errorAlert } from "./utils/toast";

successAlert("Hey there!");
errorAlert("Oops, something went wrong!");

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

&lt;/div&gt;



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

&lt;p&gt;In this post, we created a simple, stylish and shareable toast util that should help with implementing notifications and alerts in our web applications. &lt;/p&gt;

&lt;p&gt;If you feel like using &lt;code&gt;react-toastify&lt;/code&gt; in your app after reading this post, I strongly recommend heading over to the &lt;a href="https://fkhadra.github.io/react-toastify/introduction/"&gt;demo page&lt;/a&gt; and playing around with the different configurations. &lt;/p&gt;

&lt;p&gt;Thanks for reading! 👋&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>5 ways to help the environment as a software developer</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Thu, 28 Jan 2021 13:40:56 +0000</pubDate>
      <link>https://dev.to/samueldjones/5-ways-to-help-the-environment-as-a-software-developer-4bf3</link>
      <guid>https://dev.to/samueldjones/5-ways-to-help-the-environment-as-a-software-developer-4bf3</guid>
      <description>&lt;p&gt;During these strange and self-isolating times, as a software developer, it is hard to think of ways to help the environment while programming away at our laptops in the home office or, in my case, at the dining room table. In the pre-Covid days, there were significant decisions to make such as cycling to work or taking public transport instead of driving; only choosing vegetarian/vegan options when eating out; or deciding to go flight-free. &lt;/p&gt;

&lt;p&gt;In a global pandemic, these choices have now been taken out of our hands. However, as people who spend the majority of our working day (and possibly free time) in front of the computer, I still think that there are certain habits that we could change in order to make a little impact on the environment from our terminals.&lt;/p&gt;




&lt;p&gt;Here are my 5 ways to make that small impact:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Ecosia
&lt;/h4&gt;

&lt;p&gt;An alternative search engine that plants a tree for every 45 searches (on average) that you make. &lt;/p&gt;

&lt;p&gt;Their servers run on 100% renewable energy and they recently passed 100 million trees planted! &lt;/p&gt;

&lt;p&gt;Personally, I tend to use Google when searching for specific coding-related issues and Ecosia for pretty much everything else (via their &lt;a href="https://chrome.google.com/webstore/detail/ecosia-the-search-engine/eedlgdlajadkbbjoobobefphmfkcchfk"&gt;Chrome extension&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Find out more here 👉 &lt;a href="https://info.ecosia.org/about"&gt;https://info.ecosia.org/about&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Kualo
&lt;/h4&gt;

&lt;p&gt;Web-hosting company whose entire global operations are powered by renewable energy. In 2020, they also committed to becoming a &lt;a href="https://www.kualo.co.uk/blog/becoming-a-climate-positive-business"&gt;climate positive business&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've not had the chance to use Kualo yet, but will definitely be buying a domain/hosting my next website with them. &lt;/p&gt;

&lt;p&gt;Find out more 👉 &lt;a href="https://www.kualo.co.uk/webhosting/green-web-hosting"&gt;https://www.kualo.co.uk/webhosting/green-web-hosting&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Buy refurbished
&lt;/h4&gt;

&lt;p&gt;Did you know that you can help the environment by buying refurbished computers?&lt;/p&gt;

&lt;p&gt;The world's e-waste is a huge problem. Buying your next laptop, server, monitor or even headphones refurbished will massively reduce your impact on the environment.&lt;/p&gt;

&lt;p&gt;I bought my MacBook Pro 13" refurbished around 4 years and it still runs amazingly well. Although I could still do better with buying refurbished computer accessories.&lt;/p&gt;

&lt;p&gt;Find out more 👉 &lt;a href="https://www.recompute.com.au/blog/top-5-environmental-benefits-of-buying-refurbished-computers/"&gt;https://www.recompute.com.au/blog/top-5-environmental-benefits-of-buying-refurbished-computers/&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Sustainability apps
&lt;/h4&gt;

&lt;p&gt;There are so many great sustainability apps out there developed by talented engineering teams who share the same environmentally-conscious determination to change.&lt;/p&gt;

&lt;p&gt;Here are a few that I've used before or currently use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TooGoodToGo&lt;/strong&gt; - connects people to leftover food from supermarkets, restaurants and cafes &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HappyCow&lt;/strong&gt; - find local vegan/vegetarian restaurants and health food shops&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refill&lt;/strong&gt; - top up your re-usable water bottle at the nearest Refill water station &lt;/p&gt;

&lt;h4&gt;
  
  
  5. Contribute to OSS
&lt;/h4&gt;

&lt;p&gt;Away from work, another option could be to research and contribute to projects dedicated to improving our environment. &lt;/p&gt;

&lt;p&gt;This is on my todo list for 2021 and would love to get involved in a software project that increases general engagement with our environmental challenges.&lt;/p&gt;

&lt;p&gt;Check out these &lt;a href="https://opensource.com/article/19/4/environment-projects"&gt;8 projects&lt;/a&gt; for some inspiration. &lt;/p&gt;




&lt;p&gt;While I understand that everyone's circumstances are different in terms of technologies that can be used at work (e.g. browser extensions) or amount of spare time to contribute to open source, I have tried to offer some starting points in this post to encourage people working in the software development industry to help support the environment during these unprecedented times. &lt;/p&gt;

&lt;p&gt;If you have any other tips or habits that you practice to help the planet from a tech perspective, please let me know in the comments below or over on &lt;a href="https://www.twitter.com/samueldjones"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>10 Git aliases that will save time and boost productivity</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Mon, 11 Jan 2021 11:06:03 +0000</pubDate>
      <link>https://dev.to/samueldjones/10-git-aliases-that-will-save-time-and-boost-productivity-13fe</link>
      <guid>https://dev.to/samueldjones/10-git-aliases-that-will-save-time-and-boost-productivity-13fe</guid>
      <description>&lt;p&gt;Like most software developers, I spend a lot of my time in the terminal writing Git commands such as &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt; (you know the drill), but when you actually add up all those keystrokes and realise how many seconds/minutes/hours you spend on writing them, that is exactly what it becomes - a lot of time. &lt;/p&gt;

&lt;p&gt;It was pretty early on in my career that I started looking for ways to reduce the time I spent writing Git commands as it was a simple, repetitive task that was ripe for automation. I was then told about aliases and set about creating my own.&lt;/p&gt;

&lt;p&gt;Note: My terminal setup is currently iTerm2 + zsh + Oh My Zsh. Here's a &lt;a href="https://www.freecodecamp.org/news/how-to-configure-your-macos-terminal-with-zsh-like-a-pro-c0ab3f3c1156/"&gt;helpful guide&lt;/a&gt; to install this setup on your machine. &lt;/p&gt;

&lt;p&gt;All of my aliases live in the &lt;code&gt;./zshrc&lt;/code&gt; file at &lt;code&gt;root&lt;/code&gt; and they follow this syntax:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias myalias='echo hello new alias'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is the complete list of all 10 Git aliases that I use on a daily basis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias gs='git status'
alias gc='git commit -m'
alias ga='git add'
alias gr='git reset HEAD'
alias m='git checkout master'
alias gd='git diff'
alias greb='git pull --rebase'
alias gp='git push'
alias gch='git checkout'
alias gm='git merge'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These aliases save me a ton of time and allow me to focus more on &lt;del&gt;copying/pasting&lt;/del&gt; writing code. Shaving off a few seconds from every command really adds up and has definitely boosted my productivity as a whole. &lt;/p&gt;

&lt;p&gt;PS. you can use aliases for any commands in the terminal. For example, another one of my favourites is &lt;code&gt;alias cl='clear'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aliases are super useful and if you can get into the habit of using them, you will soon feel the benefits!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>github</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>5 things I've learnt as the first tech hire at a startup</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Fri, 08 Jan 2021 11:31:57 +0000</pubDate>
      <link>https://dev.to/samueldjones/5-things-i-ve-learnt-as-the-first-tech-hire-at-a-startup-j8p</link>
      <guid>https://dev.to/samueldjones/5-things-i-ve-learnt-as-the-first-tech-hire-at-a-startup-j8p</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Before we get into the nitty gritty, I'd like to share a little about my professional background before getting into software development. I studied French and Spanish at university, taught English abroad for a few years and then used these language skills to work in industries such as customer service and translation back in the UK. However, during my late twenties, I started feeling slightly disillusioned and uninspired with my career choices and had pretty much hit a ceiling at my previous company. With the birth of my amazing daughter and the inherent drive to make her proud, I decided to put myself through a part-time coding bootcamp and change career to software development. Time for a new challenge.&lt;/p&gt;

&lt;p&gt;Fast forward 6 months and I graduated from &lt;a href="https://www.manchestercodes.com/"&gt;Manchester Codes&lt;/a&gt; with some exciting skills and a deep sense of achievement. Towards the end of the bootcamp, after putting in countless hours of theory and practice while always trying to lend a helping hand in class, one of the bootcamp tutors kindly offered me a software developer role at his eCommerce fulfilment startup, &lt;a href="https://www.justfulfil.com"&gt;JustFulfil&lt;/a&gt;. I accepted without hesitation and took my first step on the tech career ladder!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I've learnt
&lt;/h2&gt;

&lt;p&gt;That was 14 months ago. I've learnt so much in that time from working on small UX tickets to building full stack features that I thought I'd share some key thoughts on starting a career as a software developer at a startup. &lt;/p&gt;

&lt;p&gt;Just a quick note to say there are many different startups out there employing different developers working on different tech stacks, so please bear in mind that this is my personal and unique experience. I am not saying that working at a startup is a breeze - there are certainly some downsides too - but I hope that this post provides you with an insight into how my development is progressing from beginner to mid-level engineer and the benefits that I've seen along the way due to working in this type of environment. &lt;/p&gt;

&lt;p&gt;So, with that in mind, let's get started!&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Pairing with the CTO
&lt;/h3&gt;

&lt;p&gt;This was something I appreciated right from the start. Before the pandemic hit, and with a small team of 3, I would usually meet up with the CTO and we would work on tickets side-by-side. He would (and still does) encourage, advise, question and provide great mentorship. This initial experience was invaluable as I was able to work closely with such a senior developer at an early stage of my development. Plus, I started to get a clearer idea of the skills and knowledge required to reach a higher level within the tech industry.&lt;/p&gt;

&lt;p&gt;Another side effect of this close contact was that I gained a better understanding of the company as a whole, which greatly helped my ability to implement business logic as well as my confidence to become more involved with discussions regarding the tech roadmap. In addition, I was able to shadow him as he planned and implemented certain infrastructure solutions such as using Docker containers for our local MySQL instances. It's always great to watch an expert at work!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Working full stack
&lt;/h3&gt;

&lt;p&gt;At a startup, you don't have the luxury of cherry picking a nice UI ticket or playing around with a low priority bug. There are too many new features and critical issues to address that there is simply no time to figure out your "area of expertise". Whether it's UX/UI fixes, database migrations or authentication, you will inevitably need to help out in all areas. &lt;/p&gt;

&lt;p&gt;I started my role in the September and spent the first month or so tackling front-end issues and contributing to new features. The following month, I moved on to back-end tickets where I became more familiar with the API and database structure. By Christmas that year, I was in a position to pick up whatever ticket was the highest priority across the whole stack and plan my workload appropriately. &lt;/p&gt;

&lt;p&gt;While coding relentlessly on a daily basis helps with your progress, doing it efficiently is not possible without excellent mentoring, support and patience from senior developers. It is tough getting told halfway through a ticket where you've spent hours working on that it may be better to go in a different direction - what makes the difficult next step easier is constructive feedback and proactive encouragement from above.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Growing with the codebase
&lt;/h3&gt;

&lt;p&gt;Like watching a young plant grow, seeing a codebase grow with you is just as satisfying. In the space of a year, our codebase has grown so much that it's easy to forget how many lines of code have been written in that time. One of my favourite things is coming across a snippet of my old (and not so well-written) code, taking some time out to refactor it and reflecting on my progress as a developer. &lt;/p&gt;

&lt;p&gt;Getting to a stage where you are familiar with all (or most) areas of the codebase is very pleasing and can give you a huge confidence boost, especially when it comes to debugging. Plus, my productivity has significantly increased as I no longer need to build components or integrations from scratch, the essential pieces are already in place and I simply need to borrow and adjust the relevant lines according to the latest use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Independent developer
&lt;/h3&gt;

&lt;p&gt;When starting a new role, a senior developer will generally talk you through or pair with you on your first tickets in order to provide support and general guidance while you learn the ropes. Naturally, the more experience you gain, the less guidance you will need. At a startup, I feel that this process is accelerated.&lt;/p&gt;

&lt;p&gt;While I would make mistakes and ask questions like all developers, the sheer volume of tickets meant that I would make &lt;strong&gt;a lot of&lt;/strong&gt; mistakes and ask &lt;strong&gt;a lot of&lt;/strong&gt; questions at the beginning - but I would learn fast. Having spent the past year learning this way, I am now confident enough to be given a brief description of a feature and I will be able to plan, design and build it myself. Inevitably, there will still be questions and discussions, but there won't be as many blockers and as a result I feel more independent and more trusted by the team. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Extra curricular
&lt;/h3&gt;

&lt;p&gt;One of the pleasant surprises of joining a startup in the early stages is that you can pitch an idea to the team and then run with it yourself (if you can fit it into your schedule!). It's useful to change focus sometimes and leave the code to one side while you contribute in a different way. For example, right now I manage the &lt;a href="https://twitter.com/JustFulfilLtd"&gt;company Twitter account&lt;/a&gt; and send out a weekly email to our clients with the latest tech updates. These latest tasks have definitely helped me to improve my content writing skills. My aim for 2021 is to focus a little more on our documentation in order to facilitate the onboarding of new developers and give talks at meet-ups/events regarding a particularly fun subject that I've worked on.&lt;/p&gt;




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

&lt;p&gt;Working at a startup is as hard as the next job, however I have seen some benefits in the past year that have helped me to become a more capable and well-rounded developer in a relatively short period of time. Perhaps these experiences would not be possible at a larger, more established company with rigid processes and several dev teams?&lt;/p&gt;

&lt;p&gt;As I've said before, I won't say that working at a startup is better than working at a digital agency filled with PMs, engineers, designers and testers. There will be advantages to working in both environments. I was lucky enough to have that decision taken out of my hands and I'm very grateful for the amazing opportunity at the start of my career.&lt;/p&gt;

&lt;p&gt;If you've worked or are working at a startup as a software developer, let me know what benefits (if any!) you've experienced while working at the company or ask me anything over on &lt;a href="https://www.twitter.com/samueldjones"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 👋&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using console.dir() to print JavaScript objects in the console</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Wed, 11 Nov 2020 11:05:40 +0000</pubDate>
      <link>https://dev.to/samueldjones/using-console-dir-to-print-javascript-objects-in-the-console-3jkh</link>
      <guid>https://dev.to/samueldjones/using-console-dir-to-print-javascript-objects-in-the-console-3jkh</guid>
      <description>&lt;p&gt;It usually happens when you need to quickly debug something. You want to check what an object looks like at a certain point in your code, so you print it out to the console. Naturally, you wrap the object in a console.log() statement, run the logic and wait for the printed output. But no. Instead of the expected object with all of its properties showing up in the console, you are given the ever unhelpful &lt;code&gt;[Object]&lt;/code&gt; or &lt;code&gt;[Array]&lt;/code&gt; elements. &lt;/p&gt;

&lt;p&gt;This has happened to me so many times that I just wish there was an in-built console method which would JSON stringify an object by default and print to the console, something like &lt;em&gt;console.stringify(obj)&lt;/em&gt;. Alas, we are stuck with wrapping our object in a JSON.stringify() and then wrapping it again in our console.log() statement. &lt;/p&gt;

&lt;p&gt;A quick note that the current approach of using JSON.stringify() - along with the replacer and space parameters - is perfectly valid and looks a little like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;There is nothing wrong with this solution and it works fine if you want to see everything in JSON format. But what if you want to see the object for what it is - a JavaScript object? &lt;/p&gt;

&lt;p&gt;Let's look at an example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nestedObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;consignments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;consignmentId&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="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;orderId&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="na"&gt;orderLines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;productRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Red Jumper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;orderComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="na"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMP-001&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="na"&gt;price&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="na"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we have a very nested object where we are trying to debug an issue with the &lt;code&gt;price&lt;/code&gt; field in the &lt;code&gt;orderComponents&lt;/code&gt; array. If we simply use console.log() to print out the object, we will get the following (not very helpful) output in our console:&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;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;nestedObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Output&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;consignments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;consignmentId&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="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;If we used our old friend JSON.stringify() to print out the entire object, we would get the following:&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;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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedObject&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Output&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consignments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consignmentId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orderId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orderLines&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;productId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;productRef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Red Jumper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orderComponents&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;componentRef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMP-001&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;That works! We can see that the &lt;code&gt;price&lt;/code&gt; field is suspiciously set to &lt;code&gt;null&lt;/code&gt;, so we can carry on with our debugging. Again, there is nothing wrong with this method. In this post, I'm simply providing an alternative way.&lt;/p&gt;

&lt;p&gt;For the same result, but displaying the output in a simple JavaScript object showing all its properties, we can take advantage of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/dir#:~:text=In%20other%20words%2C%20console.,the%20properties%20of%20the%20object."&gt;console.dir()&lt;/a&gt; along with one key parameter called &lt;strong&gt;depth&lt;/strong&gt;. Let's take a look:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nestedObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;depth&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;// Output&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;consignments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;consignmentId&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="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;orderId&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="na"&gt;orderLines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
             &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="na"&gt;productRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Red Jumper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="na"&gt;orderComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMP-001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&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="na"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Setting the depth parameter to &lt;code&gt;null&lt;/code&gt; is essential for this trick to work as it removes the limit of the object's depth, so we can view all levels of the nested object. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Remember that the object depth is unlimited. For example, when using the &lt;a href="https://momentjs.com/"&gt;Moment.js&lt;/a&gt; library, this method will print out the entire Moment date object if you have &lt;code&gt;moment.utc()&lt;/code&gt; as one of the object values. In which case, JSON.stringify() is probably the cleaner option.&lt;/p&gt;




&lt;p&gt;In this post, we learnt a different way of printing JavaScript objects to the console using the &lt;strong&gt;console.dir()&lt;/strong&gt; method. It helps us to see all the properties of a specified JavaScript object in the console without converting to JSON format. &lt;/p&gt;

&lt;p&gt;You may continue to use JSON.stringify() after reading this post (I probably will too!), but having seen the advantages of using console.dir(), at least we have another option now!&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback on this post, feel free to comment below or start a conversation over on &lt;a href="https://www.twitter.com/samueldjones"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Convert an array of objects to CSV string in JavaScript</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Thu, 29 Oct 2020 19:27:29 +0000</pubDate>
      <link>https://dev.to/samueldjones/convert-an-array-of-objects-to-csv-string-in-javascript-337d</link>
      <guid>https://dev.to/samueldjones/convert-an-array-of-objects-to-csv-string-in-javascript-337d</guid>
      <description>&lt;p&gt;On some occasions at work, we've needed to generate a CSV string on the server-side to send to our front-end app where the user can download a spreadsheet file e.g. report. &lt;/p&gt;

&lt;p&gt;Naturally, there are already packages out there that can handle a variety of CSV use cases, but we just wanted a simple solution in JavaScript as we knew that the data structure coming from our database was always going to be an array of objects.&lt;/p&gt;

&lt;p&gt;Before we continue though, it's worth pointing out that we'll be using a few JavaScript methods and techniques in the solution that you may or may not already be familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;Array.prototype.map()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join"&gt;Array.prototype.join()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"&gt;Spread syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of the above seem a little alien to you right now, then feel free to take a quick pause here to check them out and come back when you're feeling more comfortable with them.&lt;/p&gt;




&lt;p&gt;Welcome back if you took that break 👋&lt;/p&gt;

&lt;p&gt;So, how do we get from an array of objects to a CSV string while ensuring that the correct data will be displayed in the column headers and rows?&lt;/p&gt;

&lt;p&gt;Let's start by creating our array of objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;itemId&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="na"&gt;itemRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 001&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;itemId&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="na"&gt;itemRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 002&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;itemRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 003&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The first step towards creating the CSV string is to define our column headers and extract the key-value pairs into their own arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csvString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item Reference&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;itemsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemRef&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;csvString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*
   [
    ["Item ID", "Item Reference"],
    [1, "Item 001"],
    [2, "Item 002"],
    [3, "Item 003"]
   ]
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have all our data in arrays, we can use our &lt;code&gt;.map()&lt;/code&gt; and &lt;code&gt;.join()&lt;/code&gt; methods to bring everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;csvString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item Reference&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;itemsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemRef&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;csvString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*
  "Item ID,Item Reference
  1,Item 001
  2,Item 002
  3,Item 003"
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens here then? Well, the first &lt;code&gt;map/join&lt;/code&gt; combo combines the array of 4 arrays into a single array containing the headers and key-value pairs as string types e.g. "1,Item 001". Then, the final &lt;code&gt;join&lt;/code&gt; is needed to convert the single array into a string.&lt;/p&gt;




&lt;p&gt;In this post, we managed to convert an array of objects into a CSV string using some helpful array methods and the spread syntax in JavaScript. &lt;/p&gt;

&lt;p&gt;Please copy and experiment with the above code and feel free to ask me any questions on here or over on &lt;a href=""&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Using proxyquire and sinon for unit testing in Node.js</title>
      <dc:creator>Sam Jones</dc:creator>
      <pubDate>Mon, 10 Aug 2020 11:13:34 +0000</pubDate>
      <link>https://dev.to/samueldjones/using-proxyquire-and-sinon-for-unit-testing-in-node-js-5do9</link>
      <guid>https://dev.to/samueldjones/using-proxyquire-and-sinon-for-unit-testing-in-node-js-5do9</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Let me start by saying that, as a beginner, I found testing to be pretty tedious and complicated. I just wanted to create an app that was going to make millions and to hell with the test coverage! However, having spent the last year working across the full stack and writing a lot of unit and integration tests in the process, I am now more at peace with the testing gurus and appreciate the genuine value that tests can bring to your codebase. While it does require a slight change of perspective, testing should feel like taking a gentle stroll through the countryside away from the hustle and bustle of business logic. &lt;/p&gt;

&lt;h2&gt;
  
  
  Practical
&lt;/h2&gt;

&lt;p&gt;Diving straight into our scenario then. We simply want to test our function that fetches UK bank holiday dates from this URL - &lt;a href="https://www.gov.uk/bank-holidays.json"&gt;https://www.gov.uk/bank-holidays.json&lt;/a&gt;. A use case for this API could potentially be a serverless function that runs annually to fetch all bank holiday dates for that year in order to better manage dispatch/delivery times for a logistics company.&lt;/p&gt;

&lt;p&gt;Let's pause here to review the packages that we will be using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;proxyquire: overrides dependencies&lt;/li&gt;
&lt;li&gt;sinon: provides us with mocks (or stubs, in this case)&lt;/li&gt;
&lt;li&gt;node-fetch: fetches our data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The above packages work with any testing framework, but I'll be using Mocha and Chai in this particular example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create files
&lt;/h3&gt;

&lt;p&gt;Let's start by creating our &lt;code&gt;getBankHolidays&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BANK_HOLIDAY_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gov.uk/bank-holidays.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getBankHolidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;bankHolidaysResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BANK_HOLIDAY_URL&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;bankHolidaysResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getBankHolidays&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then the test file:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mocha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mocha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getBankHolidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;mocha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;getBankHolidays&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should get UK Bank Holidays&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&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;bankHolidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getBankHolidays&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bankHolidays&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;england-and-wales&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;northern-ireland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scotland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start testing
&lt;/h3&gt;

&lt;p&gt;If we run the test suite, it should pass. The call to the URL will have succeeded and the response returned will contain the expected keys.&lt;/p&gt;

&lt;p&gt;But what if, for example, our app also relies on data from a Weather API? &lt;/p&gt;

&lt;p&gt;We would also need to write a test for this new logic and make yet another call to a 3rd party service. Many integrations and API calls later, your testing suite could include several unit tests making various calls to live APIs. You may start to notice your CI/CD pipelines taking longer to complete or a few bugs may creep into your tests if, for example, a particular endpoint starts returning a 500 status. Or maybe the external API does not even offer a test/sandbox environment for you to use. &lt;/p&gt;

&lt;p&gt;Clearly, there are many reasons why you shouldn't make API calls in your tests, so a great way to avoid making them in the first place is to &lt;em&gt;mock&lt;/em&gt; the calls themselves and, if necessary, mock the response payload. Having control over both the call and response provides you with some key benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speeds up testing&lt;/li&gt;
&lt;li&gt;Easier to identify problems&lt;/li&gt;
&lt;li&gt;More secure (due to not sharing production API credentials with CI environment)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me show you what I mean by coming back to our example (now with our mock request and response defined):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;mock.json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"england-and-wales"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"division"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"england-and-wales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Year’s Day"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-01-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bunting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"northern-ireland"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"division"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"northern-ireland"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Year’s Day"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-01-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bunting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"scotland"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"division"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scotland"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New Year’s Day"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-01-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bunting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mocha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mocha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyquire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;proxyquire&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sinon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MOCK_BANK_HOLIDAYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./mock.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;mocha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;getBankHolidays&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;fetchStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;fetchStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MOCK_BANK_HOLIDAYS&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;getBankHolidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proxyquire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;~/Projects/exampleTest/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fetchStub&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should get UK Bank Holidays&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getBankHolidays&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchStub&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledOnceWithExactly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.gov.uk/bank-holidays.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So, what exactly is happening here? Basically, proxyquire is now intercepting that API call and returning the mock data as specified in our sinon stub. In other words, from proxyquire's perspective: "If I see the &lt;code&gt;getBankHolidays&lt;/code&gt; module, I will replace the &lt;code&gt;node-fetch&lt;/code&gt; dependency with the provided stub". This means that we avoid making the external API call and can slightly change our expectations too. Instead of testing the response (which is now mocked), we can put an expectation against the request payload being sent. If this is valid, then we can safely assume that the API is correctly set up and will return the correct response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: make sure your mock data replicates that which is returned by the external API in order to correctly test the outcomes and provide a valid comparison. &lt;/p&gt;

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

&lt;p&gt;That was pretty fun, right? Nothing too tedious or complicated, I hope! &lt;/p&gt;

&lt;p&gt;So, when testing logic that involves communicating with an external API, try using these packages to mock your calls. Having more control over this area will speed up your tests and allow you to quickly identify and resolve any issues.&lt;/p&gt;

&lt;p&gt;For more examples, head over to &lt;a href="https://www.npmjs.com/package/proxyquire"&gt;proxyquire&lt;/a&gt; and &lt;a href="https://sinonjs.org/releases/v9.0.2/"&gt;sinon&lt;/a&gt; and check out their excellent docs. And for a different solution, you can also look into &lt;a href="https://www.npmjs.com/package/nock"&gt;nock&lt;/a&gt; which simplifies further what we've talked about today and provides some additional capabilities.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>node</category>
    </item>
  </channel>
</rss>
