Some favorite posts to check out:

My Favorite Marvel Movies


I’m a big fan of the Marvel Cinematic Universe. I don’t hesitate to get a baby sitter and see new releases in the theater and I’ve pretty much preordered every release (sans Guardians 2). I love the genre, but even more so I think the MCU represents some of the best movie writing of my lifetime. Consistently the MCU rolls out great content, so that even the worst MCU movie is still a great movie. Not even Star Wars can rival the consistent greatness of the MCU’s story telling.


React PouchDB Components


Last night I released a new library to GitHub and npm called React PouchDB components. I'm excited to share this library, which started as an experiment to illustrate to my friend Jon how easy it could be to leverage PouchDB in React. After enough tooling around I suspected that the pieces could be extracted and shared more broadly.


A Budget with Consequences


Author's Note: I originally wrote this during the government shutdown earlier this year, but thankfully that's now over and I can maintain my streak of not writing about politics.


Budgeting is an exercise in compromise. Compromise is the right way to view it because unless you are really wealthy you never quite have enough money to buy and consume everything you want. Or at least, if you’re like me you don’t. I’m sure somewhere out there is a perfectly content person who isn’t filthy rich and has everything they want - but that’s not me. I constantly find myself thinking things like: wouldn’t it be great to have a new iPad? Just because I want something though, does not mean I buy it. I have bills to pay, mouths to feed and other commitments that all force me to make a compromise, at least for this month.


React, Relay & Mutations


A working example of what I'm going to describe here can be found at https://github.com/stanlemon/example-relay-app.


For awhile GraphQL has looked interesting to me, like something I wanted to learn. I love the concept of strongly typing expressive queries that can be batched into a single request. That's GraphQL, a technology that really seems to shine in UI work for single page apps (SPAs).

Relay is Facebook's GraphQL framework for React, it's really where GraphQL got its traction from. I love React and spend a good portion of my hobby time building stuff with it, so GraphQL was a natural progression for me. The problem is that documentation and examples on how to use Relay are all over the place and it's even harder to get into if don't already have a working GraphQL server. Some might point out that Apollo is a much easier place to start with React & GraphQL and that definitely seems true, but I specifically wanted to familiarize myself with Relay.

My first challenge was a working GraphQL server that I could issue queries against. Fortunately PostGraphile] makes this super easy. You need a Postgres instance to get going, but after that you have a working GraphQL server over top of a Postgres database. I won't go into how to setup PostGraphile, it's documentation is actually rather than good and there are some additional environment notes in the repository with my example code.

Querying from within Relay is pretty easy and straightforward and the documentation that Facebook offers is adequate. If you want to play around with querying check out this GraphQL playground with Star Wars data, it's pretty fantastic! GraphQL is not just for fetching data though, it also allows you to create, update and delete it. Those operations are called mutations and their documentation is a lot less clear.

A mutation in and of itself is not complicated, there are really two parts to it: (1) the mutation definition and then (2) committing the mutation to the GraphQL server. That looks like this:

import { graphql, commitMutation } from 'react-relay'

const mutation = graphql`
mutation AppCreatePersonMutation($input: CreatePersonInput!) {
createPerson(input: $input) {
person {
id
firstName
lastName
}
}
}
`


commitMutation(environment, {
mutation,
variables: {
input: {
person: {
firstName: "Stan",
lastName: "Lemon"
}
}
}
})

In the app I built I had already loaded all of the person records from my database using a query like this:

query AppQuery {
allPeople {
nodes {
id
firstName
lastName
}
}
}

When I first got this working I naively expected the properties in the react component that came from this query to update, such that my new person would appear in my list. But alas it did not! Updating the state store for relay is not straight forward. The mutation documentation on relay's site has some clues, but I ended up struggling to implement what I thought was a pretty straight forward user case: updating the list of nodes from my initial query with a new record.

Make sure your createPerson() mutation is returning the same fields as your allPeople query, and also make sure that allPeople is returning id. Matching fields in the response is important for new records. If you're only doing updates you can get away with returning just the fields you've changed, but the example below does not cover partial updates. The id field is not actually required for create mutations like this, but as soon as you start working with updates you'll thank me as the the global graphql id is the easiest way to yank an existing record out of the store.

What we need to do now is define an updater function on that the second parameter to commitMutation(). This updater receives a single parameter, the store and this is where we will do our handy work.

Inside the updater function the first thing we want to do is get the portion of the store where allPeople is at, because this is what we need to modify. We need to put our new person into the list of person records in that part of the store, which will in turn trigger the update to our UI. This is actually pretty easy to do as long as you know the key to pass the get() method. I found this out using the replay-devtools, which I highly recommend installing.

const allPeople = store.get('client:root');

Now we have the container of the query. Because we're using PostGraphile everything is nested under nodes so we actually need to yank that out from under our allPeople variable. That looks like this:

const nodes = allPeople.getLinkedRecord('allPeople').getLinkedRecords('nodes');

We also need to get the person record that our GraphQL server returned to us and then yank the payload from it. The payload in this case is that new person we created.

const payload = store.getRootField('createPerson');
const newPerson = payload.getLinkedRecord('person');

We have the original list of persons and the new person we added, now we need to combine them, this is really easy using the spread operation:

const newNodes = [...nodes, newPerson];

Now we have the full list of person objects as they exist in our database. Keep in mind if you were sorting these somehow with graphql you will need to insert the newPerson into the proper place, not just blindly at the end like we are doing. Lastly we take that new nodes list and replace it in our allPeople portion of the store like so:

allPeople.getLinkedRecord('allPeople').setLinkedRecords(newNodes, 'nodes');

Once this is done the local store in your react component will re-render with the new data.

Keep in mind, this is a root level scenario for the component in question. It seems pretty simple, but good luck finding an example that works like this one. If you're using data nested under another object (like comments on a post) than there are plenty of examples on the web more suited to that scenario, examples that involve things like the ConnectionHandler.

You can find all the code for my working example over at https://github.com/stanlemon/example-relay-app


Gillette Won


I do my best to avoid social media, and even when I do participate I consume a pretty narrow set of content. For example, my twitter is highly curated to focus on Indianapolis municipal happenings, Apple product rumors and javascript news. On the rare occasion I login to Facebook it’s mostly to respond to messages on my podcast page or to look at old pictures of Chicago North Western trains. I rely on my lovely wife and podcast cohort Jon to keep me in the know on the latest and greatest internet fads, at least the ones that stir up enough trouble to warrant a text. It really is a top notch curation system.

This week the Gillette “The Best Men Can Be” commercial somehow bubbled its way up into my view and I read reactions from both the political left and the political right on how wonderful and how terrible this commercial is. If you’re not familiar with the video you can find it on YouTube. Like so many things today it yielded truly polar reactions. Those that loved it applauded it for calling out what some refer to as “bro culture”. Those that hated it claimed it vilified all men universally.

Here’s what annoys me about this whole thing: Gillette won and everyone else lost. Anyone who thinks Gillette was somehow in pursuit of altruism forgets the age old axion that “any press is good press”. Gillette is owned by Proctor & Gamble, a behemoth of consumer goods based out of Cincinnati. It is a publicly owned and traded company whose sole purpose is to generate profits for its shareholders. Let that set in a minute. Gillette exists to make money, plain and simple.

In 2015 Gillette was the #1 shaving company in the United States, holding onto 64% of the market with runner up Schick. By all accounts both Gillette and Schick make crappy shave products. Both companies sell dull cartridge blade systems that generate an absurd amount of waste, but I digress. In recent years, Dollar Shave Club encroached onto Gillette’s market share by more than a razor’s edge, resulting in a 1 Billion dollar purchase by Unilever. Even beyond sub par subscription services like Dollar Shave Club, you have stores like The Art of Shaving popping up everywhere and a general interest in the more classical safety razor genre of equipment. All this is to say, Gillette is hurting. Its relevance is shriveling up and it needs some life kicked back into its blood. Don’t believe me though, take a look at Procter & Gamble’s stock prices. In a hugely volatile year on the stock market $PG is basically untouched. That’s not what share holders want to see, they want growth!

Gillette has to be loving all the PR it’s getting. Again, any press is good press. People who weren’t talking about Gillette are now, and a product that was not memorable is now gliding its way onto everyone’s social media feeds. So if you loved the video, maybe you’ll go out and buy some Gillette razors in support of the company and its bold position in this video. That’ll help Procter & Gamble’s quarterly sales, and that’s exactly what they want. Or maybe you hated the video, feeling like it unilaterally vilified half the population with stereotypes. If Gillette is lucky, you took to social media to complain about it, or shared some article or other post and further perpetuated their ad campaign. The best advertising is free, and you played right into Gillette’s hand. Either way, Gillette is on everyone’s mind, and that imprint will linger for a bit.

It really doesn’t matter where you stand on the issue, because in the end Gillette won. Nothing has changed, we’re just as angry and polarized as we were before the campaign, if not more so.

Gillette is in good company though. We hate to admit it, but this sort of appeal to our heart strings style advertising - which has absolutely nothing to do with the product being sold - is increasingly common. Tune in on a Sunday and the NFL is talking up fighting cancer and other diseases as well as supporting the military. Don’t be confused that these are somehow honest appeals. At the end of the day it’s just another ploy to get you to tune in and watch the real product, a football game. If you support our military and it appears like the NFL does, you tune in to support them, thus increasing their viewership and further increasing the cost of advertisement on one of the sacred NFL commercial slots. That’s the end goal of these heart string campaigns.

Don’t get me wrong, there are honest folks who mean well by participating in these campaigns their companies put on. I really don’t mean to discount the intent of both NFL players and Gillette employees, I just think we need to be honest about what drives campaigns like this. As much as I would love for it to be, it’s not altruism. We shouldn’t somehow project that onto the marketing departments of these big economic machines who ultimately have dividends to pay every quarter.


On an unrelated note, if you are either thinking of buying Gillette products because you loved the video or if you are thinking of no longer buying Gillette products because you hated the video let me take this opportunity to appeal to you. There’s a better way! Get yourself a good ol’ Merkur safety razor and some Astra blades and enjoy a better shave. Chances are you’ll support a smaller business in the process too, winning all around.