Ryan Tablada

Christian, UX Tycoon, Instructor at The Iron Yard

Checkout my screencasts at EmberGrep

Checkout my newest book on Leanpub

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.

How Destiny Has Killed Its Base Game to DLC Growth

Jul/23/2015

Yes, I realize that we are now over a month past E3 and the Destiny wars, but today it struck me that there is a HUGE group of players that are being overlooked by Activision and the press alike.

Before I speak to this group, let me say quick impressions on two of the hot issues.

"Season 1 DLC Owners are Being Robbed"

This is a common thread whenever a game of the year or year 2 bundle comes out. You paid for the ability to play the DLC day and date. Even if you are like me (I bought a season pass about 4 days after House of Wolves), you aren't being ripped off. You paid for DLC (I'm assuming you liked what you got), some time later: there's a discount... This shouldn't surprise ANYONE!

"Collectors Edition... WAHHHHH!"

For the whole collector's edition debate, I have no feelings. The whole idea of a collector's edition is that YOU PAY MORE TO GET SPECIAL STUFF TO FEEL SPECIAL!

Is it cheaper for new players to upgrade to the collector's edition: yes.

Does that smell: a bit.

Do I care: no...

The Real Issue

The real issue with Destiny right now is that they have COMPLETELY disincentivized buying season 1 DLC right now!

Right now there's a summer loll in games. The people who played Witcher are wrapping things up, Batman players might have another week or two to really get everything done. So I have a question:

What better time to level up your character and play that Destiny DLC that you missed?

Really though, I have a few friends that heard I was having fun with some of the DLC for Destiny and have said something to the effect of: "I want to give it another go". And now is a great time to level up your character getting ready for Taken King or just killing off time in the summer.

The problem is that if anyone asks "should I get the DLC?" my answer has to be NO! The issue is the way things are priced for the retail Taken King.

If you were to buy the "Year 1" season pass, that'll be $35. Some say this price is high, but I got over 24 hours of gameplay from it and it does freshen up some aspects of the game. The digital price of JUST the Taken King expansion is $40. This means if you are all in for both you're down $75. None of this is disputed.

The problem that I have is that the retail copy comes in at $60. And this actually isn't a "well buying the retail shouldn't be cheaper" talk. Instead this is a rant about timing and a digital counterpart to the boxed $60 bundle.

What's So Wrong With a $60 Season 1 + Exapansion 3

In short for new gamers and people who want to play Taken King this is a HUGE win! But the people with nothing to play right now have a weird spot left in their heart. They can save the $$$ and plunk down $60 for the boxed copy, throw the disc away and only use the codes that come in the front to unlock the DLC they don't have yet. This is a great plan, but they have to wait until September 15 to play the DLC they bought.

Personally, I think this means you'll have fewer existing players coming in for Taken King since they can't really level up.

I understand that most preorders are only a $5 hold so you haven't REALLY bought the S1 DLC (I'll talk about this in my solution). So stop your comment before it starts.

Maybe a Solution?

What if you could preorder the Taken King bunduru and get your S1 DLC today? What if they even made this some crazy deal where only people that have the base game already could buy this level? What if they sold it only in the form of the Collector's Edition?

EVERYBODY WINS (or at least it's better)

Think about it:

  • Sony, Microsoft, and Activision get your hard money now instead of a $5 layaway that you might not redeem or even worse could return.
  • Sony, Microsoft, and Activision have more people buying Collector's editions rather than just lowly retail boxes (higher profit margins on digital)
  • Activision has more people playing now and still will get a big bump when Taken King drops (and possibly this would make that bump bigger?)
  • You get to play season 1 DLC now AND be hyped for Taken King day and date release.
  • For $15 less than just the season one and the base game you get both plus Taken King
  • For $5 more than just the DLC you haven't purchased yet, you will get those highly coveted emotes and guns that have been described as "spark to ignite" a "powder keg"

How Hard Would it Be?

The answer: not really that hard.

Both Xbox Store and the Sony Store have ways to email you codes when you buy something else. So, with some fairly common work in their store management system: set it so that whenever someone buys a Taken King Digital Collector's Edition, they get emailed codes to immediately unlock the base game and the "Year One Exapansion Pass". Then on Taken King's release date, you get the new expansion unlocked.

What About Returns

The good thing for stores and Activision is that there's a no return policy (for the most part). And they can't say that you aren't satisfied with Taken King if it turns out like a fish in the sun for too long.

Why?

Because you got enjoyment from the base game and Year One DLC (or at least they could argue that)! Basically at that point for this digital edition Taken King becomes a bonus. It's like a snack expansion: you're saving it for later.


So... Am I out of my mind? Does anyone agree? Does this make the pricing situation any better in your mind?

Leave a comment and let me know!