Ryan Tablada

Christian, UX Tycoon, Instructor at The Iron Yard

Checkout my screencasts at EmberGrep

Checkout my newest book on Leanpub

A Story about PS4 Pro

Sep/15/2016

I come home, throw the week's mail on the counter grab a glass of water and start to head towards my gaming options. On the table is my PS Vita charging for my weekend trip and in front of me is my 3 year old mid-tier gaming PC. I ignore both of these, grab my Dual Shock 4 and instinctively hit the PS button.

It's almost 11PM so as the home screen boots up, I have a choice to play a few competitive matches of Overwatch, explore some planets in No Man Sky, or start the second half of episode one of Life is Strange that I've been meaning to go back to. As I drop on to the couch and take a sip of water, I choose to work on some public matches and try a new hero in Overwatch. Right as I enter my first match and get killed with a Hanzo "headshot" that lands at my ankle, I get a message on Discord.

I don't even check the message because I know what it is going to ask "Hey do you want to play Overwatch with us on PC". In my mind I'm thinking of the great times I've had with some PC games: 52fps (yeah I have a European monitor) is a slight noticeable improvement over 30fps on my PS4 and the better draw distance and texture detail do look really nice. At the same time, I remember when PC gaming has been pretty bad for me: a random background process spins up and suddenly the game crashes, the framerate drops because the fans don't seem to be working super efficiently today, I seem to have to download new drivers and settings for every new AAA release. As I weigh the pros and cons, I yell at my public match team to get on the payload.

It gets me thinking, I think I'm exactly who the PS4 Pro was designed for. It's not for the traditional early adopters and it's not for the PC master race. Instead the PS4 Pro is aimed at the young professional market.

For me, I want a consistent easy to use and reliable platform to play on. I don't have a ton of time to fiddle with settings and when I get home I want to boot up my game and get started. Sure, the PS4 Pro is more expensive than the AMD 480 or Nvidia 1060. But for my PC those cards aren't the answer to the smooth gaming I actually want.

While my last update to my PC hardware was 2 years ago, alot of the bones are actually older than that. The CPU is starting to reach its limits for single thread output (I purchased the 6 core AMD originally for linux development). But, to upgrade this CPU I will actually need a new motherboard as well since the CPU was actually my third in this build and is near the max capable for my chipset. Now that I have a new motherboard, I'll likely have to upgrade my RAM to match speeds for the new motherboard. All of this and I still haven't ACTUALLY guaranteed a smooth running system.

Tonight I have about one hour to play a game, and this is the case most nights. I really can't be guessing if I'm going to get a silky smooth 60 FPS (because let's upgrade my monitor since we're throwing in a new build) or 15 chunks per second based on the weather and depending on if the label of my bourbon bottle is turned five degrees due north. This is why I'm probably going to get the PS4 Pro within the first few months.

On one side I'm looking at $400 even, being able to give my current PS4 to a friend or family member who does not have the money to buy their own (or I could sell it too), and getting an improved experience that still feels familiar and has all of my friends. On the other side, I have the bet that $250 of raw GPU power will solve all of my problems, but if the bet fails I'll be starting on a solid $400-600 more to get everything upgraded on my PC.

To be completely fair from the specs and stuff it looks like the PS4 Pro will just outperform my current PC build.

But...

If you want to come over and use a compass and rearrange my liquor cabinet, I'll be over here hitting the PS button.

Travel Loadout - The Gear

Jun/02/2016

I still don't travel as much as many developers I know: but, I have traveled a lot more this year than ever before. So, the night before I travel out to New York I think it would be good to cover my carry-on pack. This is going to be a series of posts, but for now, I'll start with the gear.

The Gear

All of my carry-on gear is shown in the picture above. Starting in the top left in columns:

Column 1

  1. Sony Vita Headphones - These earbuds are comfortable, have a toggleable microphone, and very importantly they work for voice chat on Vita and PS4 which have a different set of tollerances for the mic.
  2. Lightning Cable - This is the standard Lightning cable for my iPhone and iPad. I also travel with a longer amazon Lightning cable which is just off screen charging my phone
  3. Micro USB Cable - This cable is used for my non-Apple devices (mostly for my battery packs)
  4. Playstation Vita USB Cable - This cable can be plugged in to external batteries or my Mac to charge the PS Vita. Sadly the vita takes almost a full 2A to run while charging and the stock power pack is a bit bulky
  5. Anker 10,000mAh Battery - This backup battery can fully recharge my Vita and Phone with some room to spare. While that's really nice at a conference, this sees more use as a USB splitter that happens to act as a backup battery. Since this battery is fairly heavy, I don't usually cary it around cities.
  6. Jot 4.5 - This is actually the newest addition to my pack. The Jot is a small reverse e-paper eWriter. Clicking the button on top makes the whole screen black and then using the stylus (or your fingernail), draws white lines on screen. I've been impressed with the resolution so far. The small size also is great for a quick sketch or Pomodoro style notes. Since there's no storage, these notes here have to be single track and then moved to something more permanent or sent off to the ether.

Column 2

  1. 13" Macbook Pro Retina - This is my office, work horse, and most everything. Fully packed and ready for fullstack development, under the hood is a 2.8GHz i7 and 16GB of RAM.
  2. Brikbook Case (on Macbook) - I get asked about my new Macbook case at conferences. Brikbook was originally kickstarted and is now available for sale. Right now I'm sporting one of the monthly designs.
  3. Playstation Vita - The Vita is an impressive set of hardware for a handheld. While I don't spend much time playing Vita day to day, this gets a lot of use on the plane. It's an awesome break and since the battery life is pretty solid and all games support system lock and resume, it is nice even on public transit. I'm currently playing Jak and Daxter, Hitman Go, and Little Big Planet. Also, note the trigger case on the Vita, this helps for longer play times for when I am at home or on the plane (but the case is removed if I need to pocket and go).
  4. Notebooks - For times when the Jot isn't enough room, or I need to save something for later, I have two notebooks with me. The larger is a gift from The Iron Yard and is helpful for things like specing out app or assignment ideas. The smaller one is a fields note sized Moleskin I got from Conde Nast and is great for carrying even when I don't have a bag.
  5. USB Wall Wart x2 - These are standard Apple 1A wall warts. I carry two with me on trips for a few reasons: first I have enough devices that I likely need to charge two things at once. But, more importantly, I have a backup if one goes bad (which has happened on the last two trips I've been on). If I loose one power brick I still have another and don't have to wait FOREVER for something like my Anker or Vita to charge via the USB on my Mac.
  6. Apple Earpods - Standard pack Earpods. While I like the Sony earbuds above, it's not uncommon for me to have podcasts and my vita going at the same time. But, also it's a good idea to have two different style earbuds since my ears start hurting after a while. Then I can swap and not have the fatigue from the foam or hard Earpods

Column 3

  1. Bobble Infuse Water Bottle - While day to day on campus I cary a 32oz Contigo Water Bottle, that becomes hard to carry around when traveling. This Bobble seems to be a nice trick. The infusion basket can be used to filter fruit infused water, or you can pack it with a carbon filter basket which can help reduce some odd tasting water when running around. The Bobble still holds ~22oz so I don't think I'll be running to refill it every 10 mins. Plus the softer sides make it easier to pack (but more on that in the next post).
  2. Dynex Backup Battery - Another new addition to the bag. This backup battery only has a single port, but has enough juice to keep the old iPhone going for a few more hours. Being alot smaller than the Anker, the Dynex is even pocketable for time around town.
  3. 60W Apple Mag Safe 2 Charger - The old work horse needs some juice. This is it! I keep my extension cable on this charger at all times: outlets are always two tables away in the coffeeshop.
  4. Quirky Powercurl Round - Cables are always getting cluttered. The powercurl keeps the Mag Safe charger neat and tidy. It even stows away quickly. There's also a little powercurl on one of the USB blocks, but no cord is in there.
  5. Bag - My bag is a hand me down from my dad. Turns out, it's the best bag I've found for traveling. More on that in the next post though...
  6. Wallet - I go with the standard billfold. I've had this wallet since university. Nothing really special. This was really just laying next to the rest of my pack...

Stay tuned for the next post where I talk about something even more important than the gear... THE PACK!

Building Todo MVC from Scratch Using Ember CLI

Jan/22/2016

Creating a new Project

Right now Ember-CLI is in a bit of a teenage stage. While the 1.13.x branch of Ember CLI is crazy stable, I would rather get the benefits of building apps using hot style reloading and alot of the performance upgrades available in the 2.x beta versions. This means, we'll need to install the beta version of CLI:

npm install -g ember-cli@2.3.0-beta.1

Now once we have this, we can create a new Ember project:

ember new todo-mvc

Now we have a lot of files, but we can get started.

Assets

The first task we have to tackle is getting the Todo MVC styles and such into our app. A quick bower search todo yields: bower todomvc-app-css#* not-cached git://github.com/tastejs/todomvc-app-css.git#*.

Score!

We don't have to do too much to get things into our app from there. Looking at the bower_components/todomvc-app-css folder, we have a base.css file. We'll have to get that into our build steps.

To pull in third-party JS or CSS, we can go to ember-cli-build.js in our project and import the CSS into our build pipeline. After the creation of app, let's import our the base.css file we found earlier:

``` var app = new EmberApp(defaults, { // Add options here });

app.import('bower_components/todomvc-app-css/index.css'); ```

Now when we build our app, the base.css from Todo MVC will be wrapped, minified, and imported directly into our final app.

That brings us to making our first build. While we can run ember build to make a one off build of our project, ember serve will be more helpful since it continuously builds our projects after changes and serves things up on http://localhost:4200.

Now if we look at our app in the browser, we can see maybe there's some background to our app and we have a heading that says "Welcome to Ember".

Creating the Base Markup

Now we need to add some HTML into our app to make it actually look like TodoMVC. If we go to the template HTML for TodoMVC, we can grab all of the contents of section and footer and copy them.

Ok. We have some HTML, but where can we put it?

In Ember, our app is built of nested sets of routed Handlebars templates (more on routes in a bit). At the top of this hierarchy of nesting is the template in app/templates/application.hbs. This template will wrap and be shown for everything within our app. If we open this file, we'll see the "Welcome to Ember" heading we saw in the browser. Let's paste the HTML we got from TodoMVC template so that our application template looks like this:

<section class="todoapp"> <header class="header"> <h1>todos</h1> <input class="new-todo" placeholder="What needs to be done?" autofocus> </header> <!-- This section should be hidden by default and shown when there are todos --> <section class="main"> <input class="toggle-all" type="checkbox"> <label for="toggle-all">Mark all as complete</label> <ul class="todo-list"> <!-- These are here just to show the structure of the list items --> <!-- List items should get the class `editing` when editing and `completed` when marked as completed --> <li class="completed"> <div class="view"> <input class="toggle" type="checkbox" checked> <label>Taste JavaScript</label> <button class="destroy"></button> </div> <input class="edit" value="Create a TodoMVC template"> </li> <li> <div class="view"> <input class="toggle" type="checkbox"> <label>Buy a unicorn</label> <button class="destroy"></button> </div> <input class="edit" value="Rule the web"> </li> </ul> </section> <!-- This footer should hidden by default and shown when there are todos --> <footer class="footer"> <!-- This should be `0 items left` by default --> <span class="todo-count"> <strong>0</strong> item left</span> <!-- Remove this if you don't implement routing --> <ul class="filters"> <li> <a class="selected" href="#/">All</a> </li> <li> <a href="#/active">Active</a> </li> <li> <a href="#/completed">Completed</a> </li> </ul> <!-- Hidden if no completed items are left ↓ --> <button class="clear-completed">Clear completed</button> </footer> </section> <footer class="info"> <p>Double-click to edit a todo</p> <!-- Remove the below line ↓ --> <p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p> <!-- Change this out with your name and url ↓ --> <p>Created by <a href="http://todomvc.com">you</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p> </footer>

In our browser, we can see the standard TodoMVC app. It looks nice, but nothing is working... Let's start fixing that.

Submitting a New Todo

To get started we need to modify our markup a bit. For accessibility and submit capturing, let's wrap the new-todo input in a form tag:

<form> <input class="new-todo" placeholder="What needs to be done?" autofocus> </form>

Now we need to listen for our user to submit this input (with the "Enter" key most likely). We can add an onsubmit handler to the form HTML, but we need a way to let Ember know that something has been triggered from our template. To do this, we will use the action helper which allows us to capture user interaction and send it into Javascript where we can manipulate it. We'll call this new action createTodo:

<form onsubmit={{action "createTodo"}}> <input class="new-todo" placeholder="What needs to be done?" autofocus> </form>

If we try to load up our app in the browser, things will be broken and in our console we'll see a new error:

Uncaught Error: An action named 'createTodo' was not found in (generated application controller).

This error means that we don't have anything in our Javscript to handle createTodo. So, let's first create a controller which will allow us to handle this user interaction. To go along with our application template, we'll need an application controller. Similar to Rails, we can generate this from the command line:

ember g controller application

Now we will have a new file app/controllers/application.js:

```js import Ember from 'ember';

export default Ember.Controller.extend({ }); ```

But, our app is still not working. We need to create an "action handler" for the createTodo action within an actions object in our controller:

```js import Ember from 'ember';

export default Ember.Controller.extend({ actions: { createTodo() {

}

} }); ```

Now our app is loading, but if we hit enter, our page refreshes... Well, if we recall jQuery days, we need to prevent default. So, let's stick a debugger in the new createTodo method and see if we can figure out what we have to work with.

If we submit from the input and have our console open, we can inspect the values of arguments and see that Ember has passed along the DOM event from the form submitting. So, let's add another argument to our createTodo method and prevent default:

```js import Ember from 'ember';

export default Ember.Controller.extend({ actions: { createTodo(ev) { ev.preventDefault(); } } }); ```

Now we have a new way to capture user input, but we don't have a clean way to get WHAT the user has inputted.

Let's go back to our application template and work on this. Instead of using the native input element, we'll look at using Ember's input component.

Components in Ember are similar to standard HTML elements in that they have a name and arguments, but they also bring in some extra UI implementations. For instance the input component in Ember will allow us to listen for changes and update a property on our application controller. To use the input component, let's just replace the angle brackets with {{ and }}:

hbs {{input class="new-todo" placeholder="What needs to be done?" autofocus=true}}

NOTE since we want the input to autofocus, we modified that attribute to say autofocus=true

Now we can make our input live update a property on our controller named newTitle by setting a value attribute to newTitle:

hbs {{input value=newTitle class="new-todo" placeholder="What needs to be done?" autofocus=true}}

Note we are not using quotes here because we want to use JavaScript values not string literals

Ok... So we're changing a value called newTitle in our controller when the user inputs data. How do we grab that?

To the action helper after the action name, we can pass in a second parameter for data that we want to send along with the DOM event, in this case, our newTitle value:

hbs <form onsubmit={{action "createTodo" newTitle}}> {{input value=newTitle class="new-todo" placeholder="What needs to be done?" autofocus=true}} </form>

When we specify an argument for our action, it does come in as the first argument to our action handler. Let's grab that value as title and log it to the console.

```js import Ember from 'ember';

export default Ember.Controller.extend({ actions: { createTodo(title, ev) { ev.preventDefault(); console.log(title); } } }); ```

Woo! We've logged some input! Now to submit this to the server.

Submitting Todos to an API

For this tutorial, we'll be submitting to my API that is described in this article. I have hosted this API on Heroku at http://todo-mvc-api.herokuapp.com/api/todos.

We'll use the browser fetch to post to our API:

NOTE fetch is not implemented in all browsers, we'll fix this when we get to addons, but for now use latest Chrome or Firefox

```js import Ember from 'ember';

export default Ember.Controller.extend({ actions: { createTodo(title, ev) { ev.preventDefault(); window.fetch('http://todo-mvc-api.herokuapp.com/api/todos', { method: 'post', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({todo: {title}}) }); } } }); ```

If we look at our network tab, we'll see that we have made a OPTIONS request, but it doesn't look like our POST went through. But in the XHR tab, nothing is showing up... This is because the native fetch implementations will be listed under Other (at least for now). Let's turn our results into a JSON object and log it to the console to check that the server is responding.

```js import Ember from 'ember';

export default Ember.Controller.extend({ actions: { createTodo(title, ev) { ev.preventDefault(); window.fetch('http://todo-mvc-api.herokuapp.com/api/todos', { method: 'post', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({todo: {title}}) }) .then((response) => response.json()) .then((data) => console.log('request succeeded with JSON response', data)); } } }); ```

Clearing Out Our input

After we know that the user's todo has been saved, let's reset our input. We can do this by using Ember.set to set the value of our newTitle for our controller to an Empty string. We have to use the Ember.set method so that our template context is notified of the underlying changes. Here, we start by destructuring the set method from the Ember object, then calling set after our fetch has finished. Ember.set takes three arguments: the object to change values on, the name of the property to be changed, and the new value to be set.

```js import Ember from 'ember'; const {set} = Ember;

export default Ember.Controller.extend({ actions: { createTodo(title, ev) { ev.preventDefault(); window.fetch('http://todo-mvc-api.herokuapp.com/api/todos', { method: 'post', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({todo: {title}}) }) .then((response) => response.json()) .then((data) => { set(this, 'newTitle', ''); console.log('request succeeded with JSON response', data); }); } } }); ```

In the next article, we'll grab some data from our server so that our todo list starts filled out.

Creating a Simple TODO MVC API with API Kit

Jan/20/2016

For a long time, I've wanted a small JSON based API server that I could stand up in minutes with relationships. I decided that Node and Mongoose give me a lot of flexibility for small projects that I just want to try things out on.

I've been messing around with this stack and had a fairly large setup called express-shell that I use to make a more handrolled site using Express and Mongoose. But, express-shell focused on server rendering and there was a lot of things around sessions and mail that I didn't need for micro-services and smaller APIs.

So, I had a list of things that I wanted:

  • Quick start up
  • CLI Resource Generators
  • Support for One to One, Many to Many, and Has Many relationships (with foreign keys)
  • JSON output to match JSON API or namespaced JSON resources
  • OAuth 2 Bearer Grant Support
  • Easy (or auto) registration of public and protected resources

After a while of work, I've created api-kit and to go along with things generator-api-kit a Yeoman generator package to facilitate the creation of APIs.

Getting Started

To get started, install Yeoman and generator-api-kit:

npm install -g yo generator-api-kit

Then create a new API Kit project:

yo api-kit

This will create the boilerplate for our API project and install all the required Node modules.

Generating the Todo Resource for Todo MVC

One of the key points of API Kit was that it has to build quick JSON based APIs right from the command-line. So, to match Todo MVC, let's create a todos resource with two properties: an isComplete field which will be a boolean value and a title field which will be a string of what our user wants to do. We can now generate this using the api-kit:resource generator:

yo api-kit:resource todo isComplete:Boolean title:String

Here we are saying that we want to create a todo model with our different fields and data types.

This will create a few files for us:

  • app/models/todo.js - A Mongoose model describing our model schema
  • app/http/resources/public/todos.js - A set of Express.js routes for standard CRUD
  • app/transformers/todo.js - A Mystique transformer to map data in and out of our API

Using our API

Now, we can serve our API by running npm start.

If we use something like Postman, we can go to http://localhost:3000/api/todos and we'll see the following response back from our API:

{ "todos": [] }

Let's create a new Todo for our app by sending the following JSON to our API as a POST to http://localhost:3000/api/todos:

{ "todo": { "title": "Buy Milk", "isCompleted": false } }

And now the server responds with:

{ "todo": { "id": "56a01982f8630e7f4a771879", "title": "Buy Milk" } }

NOTE Your id will vary

And if we make another GET request to http://localhost:3000/api/todos:

{ "todos": [ { "id": "56a01982f8630e7f4a771879", "title": "Buy Milk" } ] }

What's Next

In the upcoming weeks I hope to document API Kit a bit more including:

  • Deploying to Heroku
  • Creating Related Records
  • User Authentication
  • Interacting with this data from a single page app (likely Ember.js)

Starting New JS Rapid App Development Tool

Nov/08/2015

For a while now, most of my new development has been working on interaction heavy client-side apps. So, with this, I've been wanting a better way of throwing up APIs fast.

I've learned enough Rails to cut my teeth in. But, I'm still not entirely comfortable putting a new app on it. And, when it comes to PHP with Laravel or Symfony, I tend to over architect things.

What I really have been craving was a HEAVILY opinionated set of tools to make APIs. The list is pretty short but here's what my ideal toolset would contain:

  • Easy 1-2 line route declarations
  • API formatting (for things like HAL or JSON API)
  • Clear DSLs for attribute binding
  • File and project organization

So after some thought, I messaged another JS instructor the following code:

function(req, res) {
  return req.store.resourceCollection('events', {queryBy: ['category'], orderBy: 'startDate'});
}

"Wouldn't it be nice?" I thought.

Then this last week, I looked back at this code and one of my Express apps and thought I should give it a shot.

But, before I started, I wanted to set some ground rules:

  • Make future room for abstraction in 2 main places
    • ORM layer
    • Serialization/Normalization
  • Don't solve every problem (we can always just write usual express routes later)

After a few hours I now have a decent start. There's still room to go before making a true NPM package from what works, but here's what a set of routes for a single resource looks like:

var express = require('express');
var router = express.Router();

router.get('/', function(req, res) {
  return req.store.recordCollection('Book', {
    include: ['author'],
    queryBy: ['year'],
    orderBy: 'year',
  });
});

router.get('/:id', function(req, res) {
  return req.store.recordItemById('Book', req.params.id);
});

router.post('/', function(req, res) {
  return req.store.createRecord('Book', {
    include: ['author'],
    beforeSave: (book, save) => {
      book.author = '563ed344bd48dfad25a9dbd2';
      save();
    },
  });
});

module.exports = router;

I think it's pretty clean so far. But let me know what you think.