Lover of all things beautiful

NG-Form To The Rescue Dec 11 2014

A project I’m currently work on (for a very popular apparel company) is employing AngularJS for their site. I’ve created some directives to handle collecting addresses for billing and shipping. Reusable directives with their own isolate scope. To add more awesome to the mix, I’m using ngMessage to show various error messages with the form.

This all works great, but the problem was showing the error messages correctly when there are two forms on the page.

For example, if I had a form that had two addresses in my form, it might look like this with my directives.

1
2
3
4
5
6
<form name="myForm">
<div my-address-form-directive="billing"></div>
<div my-address-form-directive="shipping"></div>
</form>

One of my directives might have template code that looks like this to show the error messages. This would show the errors when the input for city had errors.

1
2
3
4
5
<span class="text-danger" data-ng-messages="myForm.city.$error" data-ng-show="myForm.city.$dirty">
<span data-ng-message="required">: this field is required</span>
<span data-ng-message="maxlength">: Please enter only 200 characters</span>
</span>
<input name="city" ng-required="true" ng-maxlength="200" ng-model="city" />

But do you see how the myForm form name is sort of hard coded?

How to get the name of the form?

The individual directives do not know how to get the name of the form since it’s outside the code of the directive. Hard coding would be a bad idea. Even if you can get the name, then if you had two my-address-form-directive on the page, the errors would show on each of the forms (even though they only applied to one)

One way to get the form is to require it in the directive and then assign it to the scope of the directive like this

1
2
3
4
5
6
7
8
9
function myDirective() {
return {
restrict: 'AE',
require: '^form', // The ^ means look at the parent elements
link: function(scope, ele, attrs, form) {
scope.parentForm = form;
}
};
}

This would allow you to grab the parent form and then use that in your template like this (notice we changed myForm to parentForm to match what we’ve assigned to the scope).

1
<span class="text-danger" data-ng-messages="parentForm.city.$error" data-ng-show="parentForm.city.$dirty">

Double Trouble

Now you’ve solved the problem of knowing what name the form has, but what about having two directives under the same form like my top example? The error messages would show on both directives when one of them tripped the error. Not what we want.

Most problems you encounter in your everyday coding have already been solved. Find the solution and your job is that much easier

ngForm To The Rescue

The answer is depressingly simple. Just add a ng-form="formName" around your directive template. Like this.

1
2
3
4
5
6
7
<div ng-form="myForm">
<span class="text-danger" data-ng-messages="myForm.city.$error" data-ng-show="myForm.city.$dirty">
<span data-ng-message="required">: this field is required</span>
<span data-ng-message="maxlength">: Please enter only 200 characters</span>
</span>
<input name="city" ng-required="true" ng-maxlength="200" ng-model="city" />
</div>

You can actually get rid of the code that require: ^form from the directive and its matching scope.parentForm = form. No longer needed, ngForm kills two birds with one stone.

Happy Bird Hunting.

Read More

Reformat with Tabs for Vim Nov 12 2014

While I’m not a big fan of TABS in my source code, a recent project I’m on has declared tabs are the way to go. So I needed to figure out two things.

  1. How do I tell Vim to use TABS on this project, but not on other project’s I’m on?
  2. How do I reformat some of my code to be tabs instead of spaces?

Using directory specific .vimrc file

This one was easy. Go into your global .vimrc file and enter this

1
set exrc " Per directory .vimrc file

Now in the root directory of your project, you will add a .vimrc file with these contents

1
2
3
4
5
6
set noexpandtab
set copyindent
set preserveindent
set softtabstop=0
set shiftwidth=4
set tabstop=4

NOTE: You may want to add .vimrc to your global .gitignore file so you don’t accidentally include it in your code :)

Reformatting code to use tabs instead of spaces

This one is already built right in. Just highlight a section of text in visual mode. Then type :retab! this should swap tabs for spaces. Try it out and tell me what you think.

Read More

Divorce is a good thing, for Single Page Apps Oct 21 2014

Read More

Why Vim Oct 10 2014

A coworker asked me the other day.

Why Vim, what do you like so much about it?

I would dare say everyone who encounters Vim has a similar story. Many years ago, while on a linux machine I first encounted Vim. It was a simple way to edit text on the server. It didn’t make sense, but it worked. That was the extent of engagement with Vim for about 10 years, just being able to do simple editing of text. More than a handleful of times I would get into some mode that I would not know how to get out of and have to force quit my session.

If you feel dumb, you’re in a good place, you’re learning.

Then a lot of developers that I admired would either show their screen during a presentation or screencast and they would be using Vim. Maybe it was Felix Geisendörfer, who said While vim may not help you to impress the ladies, it will please our BDFL and your grandpa will also approve. He’s not the only prolific developer that uses Vim, there are others and it made me think “Hey, maybe there is more to this Vim thing that first meets the eye”.

The article that by far helped me get starte with Vim was Learn Vim Progressively. The key is, get the basics down, then gradually learn more. Vim is not a, read the manual once and master it, but rather a 10 year plan. It’s old and odd at first, but the odd is there for good reasons.
G
Back to our question

Why Vim, what do yo like so much about it?

Here are a few of the features of Vim I use everyday, that make my life so much easier. Some of these you can find in other editors, but Vim really shines.

1. Replace inside quotes, parenthesis, brackets, you name it

Let’s say you have some code like such: var song = "I'm a little tea pot";, and you want to replace it with var song = "We will, we will, rock you". In Vim you simply place your cursor inside the quotes and press ci". This means Change (c), In (i), Quotes ("). This will clear out everything inside the " and you can begin typing what you want.

This works for any enclosing characters, (), [], ''; would be ci(, ci[, ci' respectively.

2. Navigation

Getting around in Vim is very quick. Use w or W to jump words. Use e or E to jump to the end of words. Use ft to jump to the next occurrence of t in the current line. Use $ to just to the end of the line (yeah, just like in RegExp). Try G to go to the bottom of the file, or Ctrl + o to go back to where you were (even in other files).

This isn’t monumental, but you can type /hello and it will find Hello and heLLo and hELL0, but if you type /Hello, it only find Hello, not hello. That’s because as soon as you type of capital, it turns into case sensitive.

4. Plugins, endless configurations

There are way too many plugins to cover them, but suffice to say here are a few that I use and depend on.

The dot .

Let’s say you type something like I just did https://github.com/. One you do that you can use the . to do that over and over anywhere. Move to different location, then press ., it inserts https://github.com/.

Read More

Using Environment Variables in Node.js with Amazon OpsWorks Oct 10 2014

I find it hard to believe that I could not find a good article online of how to get env vars working in OpsWorks. I think even more astounding is that it takes a custom recipe to accomplish this end. When you host your app on Heroku, you can easily just do an heroku config:set FOO=bar with the Heroku Toolbelt. In AWS OpsWorks, it’s a little more involved. Let’s see just how.

The Key Elements

Add a Custom Chef Cookbook to your Stack Settings

Here you are going to have to go to your Stack Settings and Edit them. You will see a section to Use custom Chef cookbooks. In this section you are going to choose git as the repository type and https://github.com/vlamic/OpsWorksEnvy.git as the repository URL. NOTE: You are more than welcome to fork this repo and use your fork.

Config Management

Add your JSON

Now while we are in the Stack Settings, we’ll add our Custom JSON that will specify our environment variables. Replace the information below with your own. NOTE: There are two sections below, one for the server instance, and one specifically for each App

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"environment_variables": {
"NODE_ENV": "production"
},
"deploy": {
"THE_SHORT_NAME_OF_YOUR_APP": {
"environment_variables": {
"NODE_ENV": "production",
"PORT": 80,
"mongoUri": "mongodb://xxxx",
"adminUsername": "admin",
"adminPassword": "password",
"s3Key": "XXX",
"s3Secret": "XXX",
"s3Bucket": "BUCKET",
}
}
}
}

Integration Custom Recipe into your Layer.

I think this was the hard part for me since I’m not real familiar with Ruby or Chef. Go to Layers, then Recipes, then Edit. Now you want to add environment_variables::default to the Deploy section. Then press the + to add it. When you are done, it will look like this.

Custom Recipe

Deploy your App

Now when you deploy your app, those variables will be in process.env. Use these like a boss and have pity on those that include passwords and such in their app source code.

One More Thing.

This is a plug for the best friend of your Environment Variables, the Node.js module nconf. It makes using these variables in your app a snap. I usually have it set up like this in my apps. That way you can easily provide env vars in a gitignore’d file in your app directory.

1
2
3
4
5
// Load config vars from commandline, ENV, file, and defaults
nconf.argv()
.env()
.file(YOUR_APP_ROOT_DIR/.env.json)
.set('VERSION', pkg.version);

Just to be sure, I have this in my .gitignore file to ignore anything that starts with .env...

1
.env*

Happy Camping.

Read More

Deploy Web App with Grunt Compiled Assets to Heroku Oct 10 2014

The conundrum is how do you deploy a web app to Heroku that needs to be compiled without including compiled files in your source?

Maybe you have some SASS that needs to be compiled into CSS. Maybe you want to minify your Javascript, or cache bust with some appended hash tags. In any case you want to run some tasks on your code to produce your distribution or build.

Here are some options.

Just include them in your your source code

This is the least desirable, but you could just include your dist or build folder in your source code. This gets to be messy as you will have compiled assets in your source code and if you have multiple people deploying you will get merge conflicts and what not. Only use this if you’re nuts.

Have Heroku compile them for you

You can do this by including all your devDependencies in your dependencies in your package.json file. Then have a Grunt task for compiling that is hooked to npm prepublish. Here is an example that will run grunt --env production on Heroku when Heroku runs npm install.

1
2
3
"scripts": {
"prepublish": "grunt --env production"
},

This works, but the drawbacks are having to include all those devDependencies in your code and then having Heroku download them and run. My Grunt tasks are kind of elaborate, so this becomes a pain for me. This can blow up in your face in the rare instance that npm is having issues :D.

Use a local distribution Git branch

This is a strategy I’ve started to use and works pretty good. It uses a local branch to add commit your compiled assets to Heroku, but doesn’t pollute your main branches (master and develop). Here is how it goes.

Setup

  1. Your dist or build folder is listed in .gitignore so that the files there are generally ignored by git.
  2. You create a branch that is used just to compile and push to heroku.
1
git checkout -b dist
  1. Run your Grunt task to create your distribution files
1
grunt buildprod
  1. In that branch you force git to include all the dist or build files that your Grunt task just made
1
2
git add -f ./dist
git commit -m 'Adding dist files'
  1. Now you can deploy to Heroku using the dist branch to push like this. This command tells git to push the local dist branch to the remote heroku branch of master. We use force.
1
git push heroku dist:master --force
  1. Now your files are on Heroku and have the compiled version

Updating Heroku

  1. Back on your develop branch you do a bunch of work, commit, etc.
  2. When you get ready to deploy again you will checkout your dist branch, then rebase against your develop branch
1
2
git checkout dist
git rebase develop
  1. Run your Grunt task
1
grunt buildprod
  1. Add newly created dist files
1
2
git add -f ./dist
git commit -m 'Adding dist files'
  1. Now you can deploy to Heroku using the dist branch to push like this. This command tells git to push the local dist branch to the remote heroku branch of master. We use force.
1
git push heroku dist:master --force
  1. Now your files are on Heroku and have the compiled version

Somethings to keep in mind, you can change these values to match your environment.

  1. My remote is called heroku
  2. My local branch for deploying to heroku is called dist
  3. My local folder that holds compiled assets is in ./dist
  4. I originally created the branch dist from develop, use master if that’s your gig.
Read More

Why you should be using a README Oct 10 2014

You’re one of the elite and have long since kept your code in git. You know how to branch, commit, and merge like a boss. Yeah, yeah, you comment your code (we known, your code is so solid it doesn’t really need comments).

But What About Process?

This is not as easy to describe. I’ve seen Google Docs, Confluence, and everything under the sun to document the details about an app. For years Github has suggested to create a README.md file when you create a new repo, why not try it sometime.

Advantages of using a README.md for documentation

  1. Changes with the code. Docs will always be uptodate
  2. It resides with the code, no hunting around
  3. You can use Markdown and Github will render it nicely on the web

What should be in your README.md

First, your README should give a general rundown of the app. Do you have any workflows to deploy the app that need to be followed a certain way? Think about it, you don’t remember much, why not write down what you need to do as a reminder to your future self what in the world you were doing.

Another good thing to put in the README is links to other types of documentation. I like to make Google Drawings, then linik to the PNG file in my READMEs, they get updated as you update the Google Drawing (ooops, kind of broke my own advantage about being source controller, crap).

Bonus

You can have a README in every folder of your app. Maybe talk about what the files in this folder do, why are they grouped together? Are they all models, controllers, config files, or what.

Resources

Read More

How I Organize My Angular Projects Aug 15 2014

Read More

Create a file in Vim Jul 11 2014

There are two primary was to work with the filesystem while in Vim. These two tools will allow you to create a new file, create a new directory, copy files, delete files and folders. Everything you need.

The built in File Explorer.

To use this built in file explorer, just think :Sex, that’s right Sex. This will open up the built in file explorer in a buffer and allow you to naviate around the filesystem. It can open up files on remote systems too by using SFTP, and other remote file reading tools. Some commands you can use

1
2
3
4
D Delete a file/folder
R Rename a file/folder
d Create a directory
% Create a folder

A better way

If you’ve been using Vim for more than a day, you should have already installed the NERDTree plugin. It’s pretty much indispensable. You can use NERDTree to navigate around the filesystem and open up files, but you can also, create, copy, move, and delete files and folders really easily with NERDTree.

So open the NERDTree sidebar, then put the cursor over a file and press the m key. A menu like the one below will appear at the bottom of the screen.

1
2
3
4
5
6
7
8
9
NERDTree Menu. Use j/k/enter and the shortcuts indicated
==========================================================
> (a)dd a childnode
(m)ove the current node
(d)elete the current node
(r)eveal in Finder the current mode
(o)pen the current node with system editor
(q)uicklook the current node
(c)opy the current node

From here you can press a to add a file in the same directory. Type the name of the file and press enter. BAM! Try it out, you’ll love it.

Read More

Essential Node.js Development Concepts, part1 Apr 14 2014

Every project tends toward insanity, it’s your job to Keep it Sane, Stupid.

This is the first in a multipart series on Node.js concepts that I consider to be essential to writing sane web apps. You already know how to Node and now it’s time to get serious about building apps. The problem you’ll run into every growing project is complexity. These concepts will help you keep things sane.

Fat Models, Skinny Controllers

Somewhere back in my PHP days while working with Zend Framework I read an article that talked about keeping your controllers small and put all your work / logic in your models. This rings true in every language / framework that I have encountered. Let’s see why.

Testing Controllers is hard

Controllers are hard to test, in fact I would say near impossible to unit test. It takes an integration test to see if your controllers are operating as you expect.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Don't do this
exports.controller = function(req, res, next) {
var id = param('id');
// Look up doc in DB
Model.find(id, function(err, doc) {
var data = req.body;
var error = null;
// validate input
if (!data.name) {
// Assign an error
error = 'Missing name';
return res.send(400, error);
} else {
// Set new data
doc.set(data.name);
// Save to db
doc.save(function(err, doc) {
if (error) {
return next(error);
} else {
res.send(200, doc)
}
});
}
}
}

To unit test this controller you’ll first going to have to stub out req, res, and next. You’re going to have a DB set up to hit because there is no way to stub out the Model object in this piece of code, so it’s going to hit the DB. We’ll now you’re going to have seed the DB with a document that matches the id we are trying to update.

See how what should be a simple unit test has errupted into a whole lot of setup?

Controllers also offer no opportunity for reuse.

Take the above controller. What if we wanted to use very simular code in another controller? You’d end up replicating the code in another controller (and it’s crazy unit testing).

Rules of Thumb

  1. All functions (Controllers esspecially) should not be more than a screen size. Preferably only 5-15 LOC.
  2. Controllers should have very little logic in them. They gather data (from input), pass it off to a Model, receive a result and write that to output.
Read More