<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[The Daily Coder]]></title><description><![CDATA[Coding one character at a time]]></description><link>https://blog.mellisdesigns.com/</link><image><url>http://blog.mellisdesigns.com/favicon.png</url><title>The Daily Coder</title><link>https://blog.mellisdesigns.com/</link></image><generator>Ghost 3.12</generator><lastBuildDate>Wed, 31 Dec 2025 08:06:18 GMT</lastBuildDate><atom:link href="https://blog.mellisdesigns.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Authenticated File Downloads in React]]></title><description><![CDATA[Authenticated File Downloads in React]]></description><link>https://blog.mellisdesigns.com/react-authenticated-file-downloads/</link><guid isPermaLink="false">5d7ac62b1b21102a38a2081d</guid><category><![CDATA[javascript]]></category><category><![CDATA[react]]></category><category><![CDATA[auth]]></category><category><![CDATA[component]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Tue, 17 Sep 2019 22:36:08 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2019/09/react_header.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.mellisdesigns.com/content/images/2019/09/react_header.png" alt="Authenticated File Downloads in React"><p>You know those moments when you're building something and questioning the approach? Those moments when something should be <em>easy</em> but it's not?</p><p>Restricting downloads to only users who are authenticated should be <em>EASY</em> from the client side ... right?</p><p>Having authentication between the client and api is stupidly common. Your client sends all its requests up with a `jwt`, the server validates the `jwt` through middleware and you have an authenticated api.</p><!--kg-card-begin: markdown--><p><img src="https://media.giphy.com/media/111ebonMs90YLu/giphy.gif" alt="Authenticated File Downloads in React"></p>
<!--kg-card-end: markdown--><p>So what happens when we can't add our token to a request header. A <em>Download Link</em> for example. We need a way to request and download a resource, and make it go through the same authentication pipeline as our app that is as seamless as ... clicking a link.</p><h2 id="probably-the-right-way">Probably the right way</h2><p>If we had all the resources in the world, we could use someones credit card, setup an account on AWS, setup profiles and policies and infrastructure to allow our server to generate signed urls that expire after a couple of minutes.</p><p>Well in the world of agile, priority arrangements and short sprints, sometimes you need to take an approach with far less overhead.</p><!--kg-card-begin: markdown--><p><img src="https://media.giphy.com/media/xT9DPlbvIe2POSISM8/giphy.gif" alt="Authenticated File Downloads in React"></p>
<!--kg-card-end: markdown--><h2 id="using-html5-blobs-and-javascript-in-react">Using HTML5, Blobs and Javascript in React</h2><h3 id="authenticated-file-downloads-in-react">Authenticated File Downloads in React<br></h3><p>We can use this technique with our existing authenticated api and build a component wrapper to handle the action lifecycle. An overview of this technique looks like this:</p><!--kg-card-begin: markdown--><ol>
<li>Have an authenticated <code>server</code> that can serve a file like <code>res.sendFile(filePath)</code> which is protected and requires a valid authenticated session</li>
<li>Make a request <code>const result = await fetch(...)</code> from the <code>client</code> to the server with your auth headers to an endpoint that can serve your file as the response.</li>
<li>When the client receives the response you convert the data to a <code>blob</code> using <code>const blob = await result.blob()</code>.</li>
<li>Create an object URL out of the blob by using <code>const objectURL = window.URL.createObjectURL(blob)</code></li>
<li>Assign that object url to the ancher tag <code>&lt;a href={objectURL}&gt;download&lt;/a&gt;</code></li>
<li>Programatically click the ancher tag to initiate the download so the user does not have to click a second time.</li>
</ol>
<!--kg-card-end: markdown--><p>Let see what a reusable component would look like in React.</p><pre><code class="language-javascript">import { createRef } from 'react'

export function AuthenticatedLink ({ url, filename, children }) {
  const link = createRef()
  
  const handleAction = async () =&gt; {
    if (link.current.href) { return }
  
    const result = await fetch(url, {	
      headers: {...authHeaders}
    })
    
    const blob = await result.blob()
    const href = window.URL.createObjectURL(blob)
    
    link.current.download = filename
    link.current.href = href
      
    link.current.click()
  }

  return (
    &lt;&gt;
      &lt;a role='button' ref={link} onClick={handleAction}&gt;{children}&lt;/a&gt;
    &lt;/&gt;
  )
}
</code></pre><p>we then call the component in its parent like</p><pre><code class="language-javascript">&lt;AuthenticatedLink url='/protected/api/documents/filename.png' filename='filename.pdf' &gt;
  Download file now
&lt;/AuthenticatedLink&gt;</code></pre><!--kg-card-begin: markdown--><ol>
<li>We check that the <code>a</code> element does not have a <code>href</code> attribute assigned to stop the recursive pattern that could happen when simulating a click and calling the click handler again.</li>
<li>Using <code>Reacts.createRef</code> allows us to manage the element with ease.</li>
<li>This pattern does not change how a link is clicked in a web application. It works like a normal link</li>
</ol>
<!--kg-card-end: markdown--><p>So there we have it, a pretty well supported way of protecting files from a server that requires  authenticated users to make requests.</p><p>Peace,</p>]]></content:encoded></item><item><title><![CDATA[Javascript {...restOfTitle}]]></title><description><![CDATA[<p><strong>EDIT 1</strong></p><p>It is quite common with axios to do something like `const { data } = await axios.get('...')` and return data. It can also be quite common to chain a set of asynchronous calls to get what you need. Below will not work because `data` is defined on the</p>]]></description><link>https://blog.mellisdesigns.com/deconstructing-using-the-spread-operator/</link><guid isPermaLink="false">5d300b2f71dcfb3fc48b6d04</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Thu, 18 Jul 2019 06:32:54 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2019/07/Screen-Shot-2019-07-18-at-4.26.02-pm.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.mellisdesigns.com/content/images/2019/07/Screen-Shot-2019-07-18-at-4.26.02-pm.png" alt="Javascript {...restOfTitle}"><p><strong>EDIT 1</strong></p><p>It is quite common with axios to do something like `const { data } = await axios.get('...')` and return data. It can also be quite common to chain a set of asynchronous calls to get what you need. Below will not work because `data` is defined on the first line.</p><pre><code class="language-js">const { data } = await axios.get('.../resource1')
const { data } = await axios.get('.../resource2')
const { data } = await axios.get('.../resource2')</code></pre><p>We can name deconstructed variables with the spread operator. The above can be rewritten like below which gives us access to the newly named resource constants.</p><pre><code class="language-js">const { data: resource1Result } = await axios.get('.../resource1')
const { data: resource2Result } = await axios.get('.../resource2')
const { data: resource3Result } = await axios.get('.../resource3')</code></pre><p>If you know the object in advance you can also deconstruct child properties as well.</p><pre><code class="language-js">const { data: child1: child2: { status: child2Status } } = { data: { child1: { child2: { status: 'child2 status' } } } }

console.log(child2status) // child2 status</code></pre><p>:cool:</p><p><strong>END EDIT 1</strong></p><p>The <em>spread</em> operator is amazing. It is probably single handedly one of the best bits of javascript functionality to be bestowed upon us.</p><p>It allows us to <em>manage immutability</em>,  <em>deconstruct and assign</em> variables in a single line, merge multiple arrays into a single collection.  But wait, that is <em>NOT</em> why I am here today. The reason I stand before you right now is ..., I learnt something else this magnificent operator can do. Take this snippet below;</p><pre><code class="language-js">const post = { title: 'Javascript', sub: 'is great', emotive: 'and I love it!' }

const { title, ...rest } = post</code></pre><p>Using the spread operator, I can pick  <code>title</code> out of the <code>post</code> object and assign the rest of the properties to a variable called <code>rest</code>.</p><p><code>rest</code> is now an object that does not contain <code>title</code>.</p><p>I know, it's a short post, but it was enough to make me smile!</p><p>Happy Developing!</p>]]></content:encoded></item><item><title><![CDATA[Using Dynamic Static Image URLS in Vue.js]]></title><description><![CDATA[Passing in localised dynamic image urls as props into a component]]></description><link>https://blog.mellisdesigns.com/using-dynamic-image-urls-in-vue-js/</link><guid isPermaLink="false">5ba34dffb72e354266555c0f</guid><category><![CDATA[vuejs]]></category><category><![CDATA[javascript]]></category><category><![CDATA[engineering]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Sun, 18 Nov 2018 21:47:37 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2018/11/VueLogo.jpg" medium="image"/><content:encoded><![CDATA[<blockquote>The quick answer, a partially defined path.<br>`:src="require(`@/assets/cards/${image}.jpg`)"`</blockquote><img src="http://blog.mellisdesigns.com/content/images/2018/11/VueLogo.jpg" alt="Using Dynamic Static Image URLS in Vue.js"><p>I should preface that <em><strong>I love Vue</strong></em>! I have said that far too often to colleagues with looks of, "huh?" and "what did you say?".</p><p>I started using Vue using the amazing <a href="https://cli.vuejs.org/">Vue CLI Tool</a> that is provided. Much like <code>create-react-app</code> , Vue has a really powerful, behind the scenes, (include all the things) CLI that gets you up and running in minutes instead of days. </p><p>Webpack is behind a lot of the magic that the Vue CLI client provides and one of complexities of Webpack is how it manages assets. Webpack must manage assets from two perspectives. One is on your <em>local development machine</em>, and the other is your built out <em>production ready version</em>.</p><h2 id="what-happens-behind-the-scenes">What happens behind the scenes?</h2><p>This is what it looks like to bring an image into a *.vue template</p><pre><code>&lt;template&gt;
  &lt;img src="@/assets/logo.jpg" /&gt;
&lt;/template&gt;</code></pre><p>The default webpack config will automatically transform <em>img</em> elements and convert the url to a production ready url. When your project is built out, you should find your assets renamed to something like below.</p><p><code>&lt;img src="/img/logo.f556f5d.png" /&gt;</code></p><p>This happens automagically with <em>img</em> elements. but most of the time we are using components from other frameworks and we need to be able to resolve asset paths on the fly.</p><p><strong>What about a dynamic static path?</strong></p><p>A team page would be dynamic to some extent. We would have team members, profile pictures that probably don't change too often associated with the team members id.</p><h2 id="resolved-assets">Resolved Assets</h2><p>We can use `require` in our source url of our customer component to tell webpack about the asset being used. When the file loader runs into a situation where we have partially defined the asset path, it will copy everything relative to the dynamic part of the path to the static assets directory. For example, everything in the <em>teams</em> directory will be copied across.</p><pre><code>&lt;my-image-component :image="require(`@assets/teams/${teamId}.png`)" /&gt;</code></pre><p>Another way we can use local assets is explicitly defining them as static assets. It could be icons, team pictures, or marketing collateral.</p><p>Using the Vue project config we can setup a static assets directory.</p><h2 id="static-assets">Static Assets</h2><p>Add `vue.config.js` inside the root of your project directory and add the following config to it.</p><pre><code>// Config file is automatically picked up by Vue CLI services.

module.exports = {
  build: {
    assetsPublicPath: '/',
    assetsSubDirectory: 'static'
  }
}</code></pre><p>This will copy all the assets inside this directory to the build directory. You can reference any of these urls inside your project by using relative paths like `/static/my-filename.png`</p><p>Remember that when you use static paths, any change to the assets name or sub directory requires all the paths in your project to be updated.</p><p>I hope this post provides a little more insight into how Vue CLI and webpack handle dynamically generated static urls.</p><p>👍</p>]]></content:encoded></item><item><title><![CDATA[Engineering using Environment Profiles in Chrome]]></title><description><![CDATA[<p>A typical developer has multiple account environments for testing and production. We currently have <strong>dev</strong>, <strong>test</strong>, and <strong>prod</strong> environments where I work. Every single 3rd party platform we use, has the same environments setup as well.</p><p>Most developers using AWS services would understand the pain of switching between different account.</p>]]></description><link>https://blog.mellisdesigns.com/engineering-using-environment-profiles-in-chrome/</link><guid isPermaLink="false">5b84a0c0b72e354266555c04</guid><category><![CDATA[javascript]]></category><category><![CDATA[aws]]></category><category><![CDATA[engineering]]></category><category><![CDATA[tips]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Tue, 28 Aug 2018 01:59:00 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2018/08/user_profile_banner.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.mellisdesigns.com/content/images/2018/08/user_profile_banner.png" alt="Engineering using Environment Profiles in Chrome"><p>A typical developer has multiple account environments for testing and production. We currently have <strong>dev</strong>, <strong>test</strong>, and <strong>prod</strong> environments where I work. Every single 3rd party platform we use, has the same environments setup as well.</p><p>Most developers using AWS services would understand the pain of switching between different account. For me, it involved opening an incognito window, pasting in the environments login url, entering my passwords into the password field, and entering my 2FA key.</p><blockquote>There has to be an easier way ...</blockquote><p>Chrome allows you to create <em><strong>Localised Users Profiles</strong></em> each with there own session data. This allows us to have a browser window instance per user with unique session data.</p><ol><li>Click on the user icon in the top right hand corner of your chrome window, and click on the Manage People button.</li></ol><figure class="kg-card kg-image-card"><img src="http://blog.mellisdesigns.com/content/images/2018/08/image-2.png" class="kg-image" alt="Engineering using Environment Profiles in Chrome"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.mellisdesigns.com/content/images/2018/08/image-4.png" class="kg-image" alt="Engineering using Environment Profiles in Chrome"><figcaption>The user dropdown</figcaption></figure><p>2. Add a New Person for each environment you use.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.mellisdesigns.com/content/images/2018/08/image-3.png" class="kg-image" alt="Engineering using Environment Profiles in Chrome"><figcaption>Creating users for each environment allows session data to persist but not be shared.</figcaption></figure><p>3. Now you can click on your created people and open up a new chrome window which is unique to each profile.</p><figure class="kg-card kg-image-card"><img src="http://blog.mellisdesigns.com/content/images/2018/08/image-7.png" class="kg-image" alt="Engineering using Environment Profiles in Chrome"></figure><figure class="kg-card kg-image-card"><img src="http://blog.mellisdesigns.com/content/images/2018/08/image-6.png" class="kg-image" alt="Engineering using Environment Profiles in Chrome"></figure><p>This was a huge productivity improvement when switching between accounts on a daily basis and has saved a chunk of time signing out, clearing cache and using incognito.</p>]]></content:encoded></item><item><title><![CDATA[The Tram Chronicles - Moving Art]]></title><description><![CDATA[<p>Creativity in coding plays a really important part to what I love doing every single day. I get an hour on the tram every morning to sit down and work on my own personal projects. This was one of the outcomes.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_GxLZyQ" src="https://codepen.io/mellisdesigns/embed/preview/GxLZyQ?height=300&amp;slug-hash=GxLZyQ&amp;default-tabs=js,result&amp;host=https://codepen.io&amp;embed-version=2" title="Art!" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe><figcaption>Creating a random visualisation on codepen</figcaption></figure>]]></description><link>https://blog.mellisdesigns.com/moving-art/</link><guid isPermaLink="false">5b5c05edb72e354266555bea</guid><category><![CDATA[javascript]]></category><category><![CDATA[creative coding]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Sat, 28 Jul 2018 05:59:25 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2018/07/Screen-Shot-2018-07-28-at-4.01.45-pm.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.mellisdesigns.com/content/images/2018/07/Screen-Shot-2018-07-28-at-4.01.45-pm.png" alt="The Tram Chronicles - Moving Art"><p>Creativity in coding plays a really important part to what I love doing every single day. I get an hour on the tram every morning to sit down and work on my own personal projects. This was one of the outcomes.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe id="cp_embed_GxLZyQ" src="https://codepen.io/mellisdesigns/embed/preview/GxLZyQ?height=300&amp;slug-hash=GxLZyQ&amp;default-tabs=js,result&amp;host=https://codepen.io&amp;embed-version=2" title="Art!" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe><figcaption>Creating a random visualisation on codepen</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[A dudes blog about javascript]]></title><description><![CDATA[<p>Oh shit, how exciting is this! I love all facets of JavaScript, Design and Principles. JavaScript is probably the most accessible language in the world and I can't wait to dive deep into my learnings and just develop fun and amazing things with it.</p><p>Looking forward to you all following</p>]]></description><link>https://blog.mellisdesigns.com/a-dudes-blog-about-javascript/</link><guid isPermaLink="false">5b5bf94ab72e354266555be6</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[Mitch Ellis]]></dc:creator><pubDate>Sat, 28 Jul 2018 05:05:05 GMT</pubDate><media:content url="http://blog.mellisdesigns.com/content/images/2018/07/all-about-javascript-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.mellisdesigns.com/content/images/2018/07/all-about-javascript-1.png" alt="A dudes blog about javascript"><p>Oh shit, how exciting is this! I love all facets of JavaScript, Design and Principles. JavaScript is probably the most accessible language in the world and I can't wait to dive deep into my learnings and just develop fun and amazing things with it.</p><p>Looking forward to you all following along and learning something on the way!</p><p>See you <code>Math.round(0.8)</code>.</p>]]></content:encoded></item></channel></rss>