5 May 2017

Fake it 'til you Make it

  • Vanilla JS
  • Vue
  • React

This is not an essay on the merit (or lack thereof) of using fake data in your prototype. Instead, this play gives you the tools you need to elevate your game from Lorem Ipsum to data that at least resembles what will eventually go in the interface you’re building

Scenario

You’ve mastered the art of working with tabular data. This time, though, you don’t have a CSV export handy, and need to populate a table with around ~25 rows of sample data. You know the general shape of the data, but need a means of generating it.

The Final Product

Rundown

As with the aforementioned play, we start by identifying a schema to represent the data. Each table row should show the user’s avatar, name, email, and favorite color.

let user = {
  name: 'Matt Rothenberg',
  avatar: 'http://placehold.it/50x50',
  email: 'hello@mattrothenberg.com',
  color: '#ffa2a2'
}

We’ll leverage a tool called Faker.js to generate as much fake data as we’d like. Faker can generate a wide variety of fake data, and offers an intuitive API for doing so. Let’s replace the hard-coded user object above with a function that generates a fake user instead.

function buildFakeUser() {
  return {
    name: faker.internet.userName(),
    avatar: faker.internet.avatar(),
    email: faker.internet.email(),
    color: faker.internet.color()
  }
}

Now when we call that function, we get a random user!

let user = buildFakeUser()
console.log(user)
/*
  Object {
    name: "Mae65"
    avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/pierre_nel/128.jpg",
    email: "Arch_Considine@yahoo.com",
    color: "#1b327b",
  }
*/

Our data set is ready. Let’s get to prototyping!


Implementation — Vanilla JS (ES6)

Here’s the game plan:

  • Build a list of fake users
let users = []

for (var i = 0; i < 25; i++) {
  users.push( buildFakeUser() )
}
  • Write a function that takes a user object and returns the corresponding table row markup (interpolating the avatar, name, and email, and color)
function generateTableRow (user) {
  return `
    <tr>
      <td class="pa3 bb b--black-10">
        <div class="flex items-center">
          <img class="br-100 w2 h2 mr2" src="${user.avatar}"/>
          ${user.name}
        </div>
      </td>
      <td class="pa3 bb b--black-10">
        ${user.email}
      </td>
      <td class="pa3 bb b--black-10">
        <div class="flex items-center">
          <div
            class="w1 h1 mr2"
            style="background-color: ${user.color}">
          </div>
          ${user.color}
        </div>
      </td>
    </tr>
  `
}
  • Iterate over our Array of users using forEach1
users.forEach(user => {
  let tableRow = generateTableRow(user)
  tableBody.insertAdjacentHTML("beforeend", tableRow)
})

See the Pen Fake Data - Vanilla JS (ES6) by Matt Rothenberg (@mattrothenberg) on CodePen.

Implementation — Vue JS

Here’s the game plan:

  • Construct a Vue instance, taking note to:
    • Initialize an empty users array on the instance’s data property
    • Hook into the instance’s created life cycle event in order to fill the users array with fake data2
new Vue({
  el: "#app",
  data: {
    users: []
  },
  created: function() {
    for (var i = 0; i < 25; i++) {
      this.users.push(buildFakeUser());
    }
  }
})
  • Define a user-table-row component to represent a given row of fake user data
Vue.component('user-table-row', {
  props: ['user'],
  template: `
  <tr>
    <td class="pa3 bb b--black-10">
      <div class="flex items-center">
        <img class="br-100 w2 h2 mr2" :src="user.avatar"/>

      </div>
    </td>
    <td class="pa3 bb b--black-10">
  
    </td>
    <td class="pa3 bb b--black-10">
      <div class="flex items-center">
        <div
          class="w1 h1 mr2"
          v-bind:style="{backgroundColor: user.color}">
        </div>
        
      </div>
    </td>
  </tr>
`
});
  • Iterate over the instance’s users property in our template using v-for syntax. Due to a template parsing caveat in Vue, we must use the is attribute to define which component should be rendered.3
<tbody>
  <tr is="user-table-row" v-for="user in users" :user="user"></tr>
</tbody>

See the Pen Fake Data - Vue JS (ES6) by Matt Rothenberg (@mattrothenberg) on CodePen.

Implementation — React JS

Here’s the game plan:

  • Create a stateless functional component called UserTable
    • It should accept an array of users as a property
    • It should render a UserTableRow component for each user in the users array
const UserTable = ({users}) => {
  return(
    <table className="bg-white w-100 data-table f6" cellspacing="0">
      <thead>
        <tr>
          <th className="tl pa3 bb b--black-10">User</th>
          <th className="tl pa3 bb b--black-10">Email</th>
          <th className="tl pa3 bb b--black-10">Fav Color</th>
        </tr>
      </thead>
      <tbody>
        {
          users.map(function (user) {
            return <UserTableRow user={user}></UserTableRow>
          })
        }
      </tbody>
    </table>
  )
}
  • Create another stateless functional component called UserTableRow
    • It should accept a single user object as a property
    • It should render out <tr> markup accordingly
    • In React, the HTML style attribute accepts a JavaScript object with camelCased properties rather than a CSS string. At the top of our render function, we can build that object by interpolating the color attribute on our user prop.
const UserTableRow = ({user}) => {
  let favColorStyle = {
    backgroundColor: user.color
  }
  return (
    <tr>
      <td className="pa3 bb b--black-10">
        <div className="flex items-center">
          <img className="br-100 w2 h2 mr2" src={user.avatar}/>
          {user.name}
        </div>
      </td>
      <td className="pa3 bb b--black-10">
        {user.email}
      </td>
      <td className="pa3 bb b--black-10">
        <div className="flex items-center">
          <div className="w1 h1 mr2" style={favColorStyle}></div>
          {user.color}
        </div>
      </td>
    </tr>
  )
}

See the Pen Fake Data - React JS by Matt Rothenberg (@mattrothenberg) on CodePen.

Footnotes