lemonbytes

husband, dad, steelers fan and software engineer

React PouchDB Components

by Stan Lemon


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.

There are a number of different ways to deal with state in React, everything from the simple setState() to redux. Most sites need remote data, and so as a developer your options become a little more complex, leveraging promises inside of componentDidMount() or tools like redux-thunk. These are all great, but what I wanted was a simple way to fetch data into PouchDB and for it to be declarative.

Here’s what I imagined…

import { Database, Document } from "@stanlemon/react-pouchdb";

function App() {
  return (
    <Database>
      <Document name="my-document">
        <MyComponent />
      </Document>
    </Database>
  );
}

function MyComponent({ name, description }) {
  return (
    <div>
      <h1>{name}</h1>
      <p>{description}</p>
    </div>
  )
}

There are two components here, the first <MyComponent /> is a simple view, it renders some properties that are passed to it. The other is <App /> which declaratively establishes a PouchDB database connection using the <Database /> component. This component can take an optional name and remote URL for syncing. The <App /> component also uses the <Document /> component which is responsible for fetching data out of a PouchDB document and setting it as properties on <MyComponent />.

One of the other advantages of the <Document /> component is that it provides a property to it’s children called putDocument() that allows you to update the state of your document, just as you might when using setState(). This method eagerly updates the component’s properties, and then ensures that the document is updated in PouchDB.

As an added bonus, if you’re syncing your PouchDB database to a remote CouchDB instance, the <Document /> component will update properties when change events occur. This means that you can sync down remote updates with little effort in near real time.

There is a working example in the GitHub repository under the ./example/ directory. It has it’s own README and is really easy to spin up and start playing. You can check out the example app over on glitch. This example app showcases several different ways to leverage a document including <Document /> and a higher order function withDocument().

Ready to give it a spin?

npm install --save @stanlemon/react-pouchdb pouchdb

From there the README is your friend!

This library is intended to quickly get a PouchDB database into your react application. It won’t work for every situation and there are definitely more complicated use cases that it does not cover, but as a starting point it should get you off the ground quickly. It’s also worth noting that this library is not intended to work with other state container libraries. Maybe it does, but that’ll be purely by chance. If you are using something like redux you should consider taking a look at redux-pouchdb.

Please reach out with feedback! I love questions and suggestions so send them my way.

Stay tuned, I have some more PouchDB related goodies coming.



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.

Let’s take a look at an example of everyday compromise in budgeting: let’s buy a car with financing. Before you sit down to sign the paper to buy a car you have to pick one out. Often you pick one out off of a lot. Your choices are limited by what’s available at that particular dealership. You may decide to buy the blue car that doesn’t have the sun roof over the red one that does because you like blue better. That’s a compromise. When you do sit down to finance it you have choices: a 3, 5 or even an 8 year car loan. Each requires a different amount of money paid for a downpayment and each will require a different amount of money monthly. As you continue the cycle of evaluating your options you are making more compromises, trading one thing for another in the hopes of reaching the ultimate goal: driving away with a new car. Maybe the compromises are big ones like, “This car is too expensive. I need to go get the gray car without the leather trim, instead,” thus blowing up the whole process and starting over. Or maybe the compromises are more subtle, like cancelling your satellite TV subscription in favor of over the air channels to free up more money in your monthly budget to pay for your car loan. Every decision, every step somehow involves a compromise.

Money and goods are in limited supply, and so you’re constantly making tradeoffs between what you have, what you need and what you want. I’ll buy that new chair for my office today rather than the Nintendo Switch I’ve been coveting because I have a limited amount of funds available. I value a comfortable chair I use every day over playing Mario Kart. In my ideal world I’d have it all. No compromise would be required, and it’d be even better if I didn’t have to work for it either. That’s just not the world we live in.

Everyone budgets, even if they don’t think they do. Maybe you don’t have a spreadsheet or fancy app to categorize and track your spending, but you’re still going through the budget process in your life. The loan example earlier is crude budgeting because it’s calculating a decision to spend funds. That’s really what budgeting is, calculating what to spend based upon compromises.

When we attempt to budget without compromise, bad things tend to follow. We buy a car we can’t afford and we default, resulting in it being taken away from us. Or we don’t pay that credit card off fast enough and attempt to buy food and when we have no credit left we end up not able to feed our families. Compromise is ultimately the curb that hones in responsible purchasing decisions. That curb is based off of consequences, which are critical. They are the thing that gives us pause when we don’t want to compromise.

Curbs are good, they keep cars on the road. Curbs provide the external boundaries for our path forward. This is the function of compromise, and our budget is really just that road we’re cruising down from month to month.

Want to hear more budgeting banter? Check out Episode 25 of Life with a Twist of Lemon.


React, Relay & Mutations

by Stan Lemon


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

by Stan Lemon


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.


Visualizing a Mortgage

by Stan Lemon


A drawing of the Lemon home representing our mortgage and showing our progress paying it off.

In Episode 8 of Life with a Twist of Lemon my friend Jon asked me about buying a house and for part of that discussion we talked about mortgages. One of the things that I mentioned our family does is visualize our mortgage on a piece of paper hanging on the side of our refrigerator. On the paper is a drawing of a house, which my lovely wife made to look like our actual house. It’s on graph paper and each square represents part of the mortgage we owe. As we pay down the mortgage we fill in boxes, with the ultimate goal of having the whole house filled in. This idea didn’t originate with me; I don’t actually even recall where I first saw this. I think it’s neat though, and I like that it’s there every day for us to see. A few listeners (it still amazes me that we have those, thank you mom and the other 3 folks that tuned in) asked me what that mortgage visualization looks like, so I thought I would share it here. The colors don’t mean anything, they were chosen based on the closest colored pencil at the time. The shaded parts (roof and windows) also don’t count in our drawing. Anyone can do this too, and you don’t need to be as fancy with the drawing as Mrs. Lemon was. That said, I think ours is pretty cool and I’m just tickled with what she made for our family. Now to fill it up!

The purpose of the drawing and really a good portion of Jon’s and my discussion is understanding your debt and having a strategy to get rid of it. I don’t think debt is in and of itself a bad thing. In many instances it’s simply a necessity, like buying a house. I do think society is perhaps too comfortable with debt though and it’s good to go into something like a mortgage with a desire not to have it. That desire is strong in me, and things like this visualization help keep it top of mind so that I am constantly being reminded to get rid of it.