FIG is accepting new projects! Let’s discuss yours!

Fillmer Innovation Group

Software. Shipped.

Fillmer Innovation Group, or FIG, is a group of passionate software engineers that are more interested in solving difficult problems then just clocking in to get a paycheck. Our team is fully remote, as we believe that balancing work and personal life is more important than a commute. When you start a project with FIG you work directly with our founder and project manager on a daily basis, and touch base with the developers working on your project frequently.

One of the core tenets of the development process is that determining the scope of the work to be done is the most important aspect of a successful project. The adage "measure twice, cut once" is just as relevant to software development as it is carpentry. Leveraging our extensive experience in the industry, we pride ourselves on coming up with accurate estimates and creating high quality software for our clients.

The Latest News & Views from the FIG Team

Static Success with Hugo: Part II

May 25, 2020

This one simple trick…

Continuing on from our previous article, we enjoyed building our new website with Hugo, but we ran into some interesting challenges during setup and customization. One area that took a bit of digging to figure out was the mapping of single-use screens, such as our Get Started screen, to the appropriate content.

Mapping content to pages

Our solution involved creating a pages directory within the layouts directory. Inside we made a single template file, get-started.html, whose name maps exactly to a directory created within the content directory. The directory structure mapped out:

...
content/
  get-started/
    index.md
...
layouts/
  pages/
    get-started.html
...

The final piece of this puzzle was to make sure the contents of the index.md file in the content/ directory were correctly defined to pull the get-started.html template, which contains our custom code for our contact form:

---
title: "Get Started"
type: pages
layout: get-started
---

With this done, and our header navigation updated with the correct link, we were able to build out our custom contact form within the get-started.html file. A simple solution, but not immediately intuitive when coming into the Hugo ecosystem from the outside.


Static Success with Hugo: Part I

May 7, 2020

When it came time to do our recent rebuild of the FIG website, we were faced with the decision of deciding what tech stack to use to manage our content. The tempatation was to use something like Flamelink, which we love (more on this in a future article), or any other CMS solution. There came a time in the initial discussion where the YAGNI principle was broached, and that maybe a full CMS was overkill for our needs. It was agreed that a static site generator would be the way to go.

Once we made the choice to reduce the complexity of our project we jumped at the chance to use something that we had never used before to get the job done. Enter Hugo. In the past we had used the usual suspects of Javascript static site generators, the chance to play around with Go instead definitely appealed to our eternally curious developer side.

Hugo’s claim to fame is speed, and it is certainly fast. A build of this site averages 3ms at the time of this writing, which is fantastic, and a great perk of using the framework. It was also very quick to get up and running. This redesign of our site took about three billable days worth of work, only the first of which was getting Hugo up and running. The rest of that time was spent endlessly tweaking CSS until everything was just right.

However, not everything went smoothly. Hugo’s documentation can be somewhat confusing, and the terminology for concepts was fairly specific and opaque coming from outside the community. A fair amount of that initial setup time was spent digging through Stack Overflow posts and doing some trial and error until we got things working the way we wanted. Over the next few articles we will explore some of the gotchas we ran into, and the solutions that we found.


Context View Logic

April 24, 2020

The new Context API introduced in React 16.3 made quite a stir in the React community. Some are underwhelmed, some are claiming the upcoming death of Redux. Regardless, I prefer to focus on useful applications of the new pattern.

As I have begun using the new Context API I have found that I turn to it more and more to perform small, contained, view logic tasks. Some simple reusable patterns, such as tabs & modals, lend themselves very well to the Context pattern.

The Problem

As is common in an administrative UI there are many screens that are lists of data. In a recent project our list views could be in any of three states: loading, loaded with no data, or loaded with data. Using basic control structures in our JSX we end up with quite a few views that contain some variation on the following:

// Data is falsy, show Loading.
// Data is an empty array show <NoData />.
// Data is array of actual items, show <List />.
function IRecieveData ({data}) {
  return (
    <Section>
      {!data && <Loading />}
      {(data && data.length === 0) && <NoData />}
      {(data && data.length >= 1) && <List data={data} />}
    </Section>
  )
}

Nothing too crazy here, and it is simple and readable. However when we began copy and pasting multiple times throughout our application we knew it was time to generalize it and create a pattern. In our particular use-case we knew that all data coming from Redux would either be null, an empty array, or an array of items.

The Solution

function IRecieveData ({data}) {
  return (
    <Section>
      <Switch data={data}>
        <Switch.Loading render={Loading} />
        <Switch.NoData render={NoData} />
        <Switch.Data render={List} />
      </Switch>
    </Section>
  )
}

We have essentially taken our basic Javascript control structures, wrapped them with JSX; and leveraged the Context API to avoid passing data along to each component via props. What have we gained?

  1. Consistency in reuse. When leveraging this pattern in a new view simply making sure that data is mapped correctly is all that is necessary.
  2. It’s all JSX. JSX is readable, and React developers are used to reading it. This adds clarity to our code at a glance, without needing to understand the underlying data shape.

Etc.

An implementation of this pattern can be found on Github. As with most patterns in the React ecosystem, this is not appropriate for every use-case, there is no one-size fits all pattern.


Reducer Snapshots

April 17, 2020

Test Driven Design (TDD) is a great way to ensure that you are getting the expected behavior from any given piece of code.

When writing tests I follow Eric Elliott’s advice in TDD the Rite Way and favor equality tests as much as possible. A test written this way, with explicit expected results, is easier to reason about, reduces edge cases, and documents the codebase.

Redux reducers lend themselves well to this development pattern. As our reducers are pure functions we can simply define inputs and outputs and run our function. An example, written using Jest:

/* global describe, test, expect */
import {action, initialState, reducer} from 'state'
describe('reducer', () => {
  test('handles ACTION_TYPE correctly', () => {
    const name = 'A Name'
    const expected = {
      name,
      description: 'Some data that should not change.'
    }
    const actual = reducer(initialState, action(name))
    expect(actual).toEqual(expected)
  })
})

Simple and readable, we know exactly what the reducer should return when running the action mapped to ourACTION_TYPE. There is a downside to this, specially when iterating quickly through a prototype or MVP: writing out the full expected shape for any given part of our application state can take some time.

The example above has state that is rather trivial and thus the test is not particularly lengthy. When leveraging Redux in production, and in particular when attempting to keep our state normalized and as flat as possible, the opposite quickly becomes the case.

Jest Snapshots to the Rescue

Jest comes with a handy feature called Snapshot Testing. Essentially what snapshots do are create a JSON schema representation of whatever you pass in and do future comparisons against that representation.

Although commonly demonstrated as a clever way to test React components they also happen to be useful for testing reducers. First, the above test written with snapshots:

/* global describe, test, expect */
import {action, initialState, reducer} from 'state'
describe('reducer', () => {
  test('handles ACTION_TYPE correctly', () => {
    const actual = reducer(initialState, action('A Name'))
    expect(actual).toMatchSnapshot()
  })
})

Given the brevity of our reducer this does not seem like much of a gain, at least in lines of code. Lines of code savings do start to accumulate over time, however the big gain here is in maintainability and speed of development.

Setting up the test in this manner lets us get back to creating our reducer quickly. Tabbing over to the terminal, where we naturally have Jest running in watch-mode, allows us to watch the snapshot changes as we iterate on the logic contained within reducer.

Once the state shown in the snapshot reflects what we expect to see we simply update the snapshot and now have a baseline from which to compare any future changes.

A more complete example of using this pattern can be found on Github.