Friday, February 28, 2014

Bitwise (Not)

I ran across an odd expression today in the Express config in the MEAN boilerplate.

if (~err.message.indexOf('not found')) return next();

Aside from the omission of the braces, which I'm vehemently against, I thought it looked interesting. Is this is the way the cool kids test for a substring? I played around a little bit, mulled it over, and came to a conclusion.

Test Code

Analysis

Basically, ~ flips the sign and adds -1. It's a neat trick and it saves a couple characters when testing for "anything other than -1". I recall from "JavaScript: The Good Parts" a mention of the inefficiency of JS conversions for bitwise operations. Ignoring that, there are two big problems:

  1. It's tricky. I knew it was a bitwise operator, but couldn't remember which. After dicking around, I see how it works, but will I remember next month? Probably not. If I start using it, what are the chances the other people on my team will know what it is?
  2. It's inconsistent. It doesn't return true or false, it returns something truthy or falsy. You can see that at the end of the gist above.

Conclusion

Don't use it. Code is for humans to read, so clarity is important. Otherwise, we could just write binary, right? Using something that can be easily misunderstood or misused to exhibit how smart you are is a bad practice. We all know you're smart, good-looking, and an excellent driver. Be confident in yourself and considerate to the poor dudes who have to read your code later.


Footnote

The title "Bitwise (Not)" was supposed to be clever; it is the bitwise not operator, but you could also read it as Wayne from Wayne's World. That was supposed to be ironic, because it's not wise to use bitwise operators in JS. Also, it was ironically funny to reference Wayne's World, which was only cool about 20 years ago.

Furthermore, the code snippet tests for "i" in "teamwork"...

Screw it. I'm going to start using ~ to test for indexOf.

Thursday, February 27, 2014

Does This Mean I'm Famous?

So, I've been digging through the MEAN.io boilerplate and learning quite a bit.  Just for fun, I decided to fork their related project and submit a pull request to address some errors.  The goal was simply to learn about the whole fork/pull request process and I suspected the request would be ignored.

Now look at this screenshot from their Github page.


I've learned a lot through Nice MEAN, my noob-friendly version of the stack, but there's still so much to learn.  However, I think this is evidence I'm on the right track to becoming a MongoDB, Express, Angular JS, and Node.js pro.

Wednesday, February 26, 2014

IRC?

This is kind of embarrassing, but I've never actually used IRC.  It's not hard.  Ubuntu comes with Empathy, but apparently it sucks.  We'll use XChat instead.

Steps

  1. Update apt-get (as always). sudo apt-get update
  2. Install xchat-gnome. sudo apt-get install xchat-gnome
  3. Open XChat-GNOME IRC Chat from the Dash Home button.  If you use a terminal, you can't use it for anything else while XChat is open.

Now join #mean.io.

Sunday, February 23, 2014

Blogs Are for Words, Github Is for Code

I'm still excited about keeping this blog, but it's awkward to try to explain the things I've been doing. I've learned so much over the past few days that it would take much longer than I'm willing to spend regurgitating it here.

An Epihany

Blogs weren't designed for code. Sure, it's OK to talk about code and include a few snippets or gists, but blogs are meant for rambling about stuff, not granularly documenting code. It's too cumbersome to add context. Additionally, I spend all my time in the code. Why not work on helping out noobs like us while I'm in there?

Github Accounts Are Free

I've forked the MEAN boilerplate (forking is just making your own copy in Github) and called it Nice MEAN. This is, to extend the Harry Potter reference, my textbook. I'm going to keep writing notes in comments to you, me, and everyone else explaning what's going on in the code. That's what I've been doing all week anyway. It's dumb to come to Blogger and try to reproduce that. So, while you're learning the MEAN stack, please feel free to use my book. You can get the version without dog-earred pages like everyone else, but my version has lots of comments from the layman's perspective. Hell, get both versions. It's not like you have to pay for them.

tl;dr

This was not too long, but for consistency... Today's lesson: Use the right tool for the job.

Thursday, February 20, 2014

Make the MEAN Boilerplate Your Own

I took my own advice and decided to make a new project. Here are my notes for adding a new page to the boilerplate.

  1. Add a reference to the HeaderController in /public/js/controllers/header.js in $scope.menu
  2. Add a route for the new link's path in /public/js/config.js. (hmm... they use $stateProvider instead of $routeProvider) Include a templateUrl.
  3. Create a template in /app/public/views/.
    • note - They use data-ng-foo for their directives. data- is ignored by Angular JS. This is just for html validation purposes. When in Rome...
    • Add a controller to the template. Cry when you refresh because Angular is sad.
  4. Create a module to attach the controller to in /public/js/app.js. Since they've already got everything hooked up to the 'mean' module, just dangle from that. angular.module('mean.notes', []);

I made a mistake at this point (metioned at the end). Next time, I won't. Learning is fun!


  1. Create the controller in /public/js/controllers/notes.js. Attach the controller to the module created above.
    • You can pretty much copy the first line of the definition from articles.js, just remove the Articles injection and name the controller correctly.
    • Add a $scope variable to the controller ($scope.foo = 'bar';) and in the view (step 3 above - {{ foo }}) so you can be assured it's all working.
  2. Add the controller reference so Angular won't cry anymore. Look for Application Controllers in /app/views/includeds/foot.html.
  3. Restart the server.

Dang

:( OK, everything seems hooked up, but the controller isn't found for some reason. I added a breakpoint in the new controller, and it is being loaded. I kept getting

Error: [ng:areq] http://errors.angularjs.org/1.2.13/ng/areq?p0=NotesCtrl&p1=not%20a%20function%2C%20got%20undefined

It turns out, although we set up a namespace and defined everything, the new controller was never injected into the main app's "mean" module. This was not noticed for a bit because of the in my opinion bad formatting that caused the dependencies to go way off the page.

tl;dr

Format the verbose injection so you can see everything!

You can't just define a module and add a reference to the script. You have to inject it!

Wednesday, February 19, 2014

Plugging Angular Seed Project into MEAN Boilerplate

So, I've got a little app and I want to start using REST methods for persistence. At this point, the app is just Angular with no backend, using localStorage like a database. Eventually, I'll be getting into Node, Express, and MongoDB, so why not use the MEAN boilerplate to whip up the backend? Just a little tinkering to get the services I need up and then I'll be free to start experimenting with $http and $resource.

I pulled down the boilerplate (instructions here) and moved my files to the corresponding directories. Some of the files didn't match up exactly, so I copied the code the corresponding boilerplate files. After shuffling a few things around and changing commenting out a few unneeded lines, I expected to be up and running.

No Grunting

I'd used grunt to run the MEAN apps I'd played with before, so I tried it again.

grunt

Grunt does all sorts of cool things like linting the app, running test suites, and monitoring for file changes. This last thing is super cool because, as we'll discover when we start working with Node and Express, changes to basically anything other than templates requires restarting the server. Grunt watches for these and restarts automatically - even triggering a browser refresh - so we don't have to.

Anyway, so when I reflexively started the server with grunt, I got a whole bunch of errors from tests, JSLint, and frankly a lot of shit I didn't even look at. I figured it would still work, I'd just have to go back and clean up a few things. Unfortunately, that was not the case.

I couldn't get anything to serve up in the browser. (Yes, I did note that the Angular JS seed serves on port 8000 and MEAN uses 3000). In order to get anything to the browser, I had to skip grunt and run the server manually.

node ./server.js

So Many Errors

The browser console (I shouldn't have to specify, but "the browser" is always Chrome) had a ton of errors, some more cryptic than others. I figured out that I could glean from the callstack or url where the error was emanating from or what it was looking for. Eventually I was able to track everything down and - keep in mind, my objective is just to get a backend up - comment a bunch of crap out. It's ugly, but it's a throw-away. Stop judging me.

Why Aren't You Updating?!

A lot of the resources I didn't care about anymore were specified in the node view in /app/views/includes/foot.html. (I thought these were Jade templates the last time I used this.) For some reason, most definitely user error, no matter what I changed or how often I cleared the browser's cache, the changes didn't show up. Honestly, I don't remember what I did to fix it and I may have the series of events backwards. Now that I write it, I think initially grunt may have worked despite the errors and it was caching the pages. Either way, I ended up starting the server as described above and restarting it after every change (ctrl + c x 2 to stop server). It was ugly and painful, but eventually I started to see my first app shining through.

Easy Street DETOUR

The final step of my plan was to delete the .git directory inside my initial app, which was lost somewhere amongst the MEAN files, reinitialize the repo, git add ., add a commit message, and check it in. That went well until the last part.

Apparently, Git's a little smarter and more cautious than I am when I only have 3 minutes left for lunch. It rightly told me that everything was all fucked up - I could be off with the wording - and it was not safe for me to just check everything in (see non-fast-forward errors). Since I don't have anyone else on my team and I was feeling particularly rushed, I forced git to accept it, consequences be damned.

git push -u origin master --force

This was dirty and careless, but I got everything back into my remote branch before lunch ended, so I considered it a success. A just remembered, there were a few hiccups while shuffling my files around that I omitted. This was probably due to having multiple directories named "notes". It came in handy to reject all the changes I'd made, several unintentionally, so I could start over. The useful command for that is:

git checkout -f

This is basically a big "undo" for all uncommitted changes in the current branch. Again, very heavy-handed, but I'm not focused on the minutia of git right now.

tl;dr

The lesson is, don't try to merge an existing project into the MEAN boilerplate in the last half of your lunch break. If your directives and services and whatnot are portable (they should be), just move those and recreate the views. Also, don't try to trick git; create a new repo.

Tuesday, February 18, 2014

Stand on Giant Shoulders

Before inventing our own wheels, let's try out some others have built already. MEAN.io has a full stack already stubbed out with some stuff for us.

Get the Code

There are two ways to get the code. The first is presented by the "Download Now" button and gives you a zip file. The second is better.

The Zippy Way

  1. Click the button.
  2. In terminal, go to where you want the app to live. I've created a directory in home (~) called node_projects. cd ~/node_projects
  3. Move the .zip. # mv can move and/or rename mv ~/Downloads/linnovate-mean-blah.zip ./
  4. Unzip and rename it. # unzip is pretty straight forward unzip ./linnovate-mean-blah.zip # mv can move and/or rename mv ./linnovate-mean-blah ./donkey

The Better Way (Clone the Repo)

  1. Clone the repo from Github. # clone from the repo git clone https://github.com/linnovate/mean.git
  2. Rename, because we'll probably do this again some day. Also, our project isn't called "mean." # rename with mv - this seems familiar mv ./mean ./clean-mean
  3. remove the old git info # change to the new dir cd ./clean-mean # remove the old .git dir so when we commit we don't have all the history rm -rf ./.git
  4. make it our own
  5. create repo in github (clean-mean) # initialize git repo git init # include username when setting up remote so we don't have to provide it repeatedly git remote add origin https://reergymerej@github.com/reergymerej/clean-mean.git # track all the files git add . # commit git commit -m 'init commit' # after the initial push, "git push" will suffice git push -u origin master

Start it Up

Whichever way you got the code, you'll have to start it up like this.

# install the dependencies with npm npm install # start it up with grunt on port 3000 grunt

Monday, February 17, 2014

Ketchup

Do What I Say I Did, Not What You Saw I Did

I've already spent a several weeks getting my feet wet.  Biting off the full stack is a lot, so I decided to begin with Angular, since it is all front-end, where I feel most comfortable.  Additionally, it stands alone - Express builds on Node and MongoDB is the data piece - so it seems like a good entry point.  The docs seem decent, if not unfamiliar, and the intro tutorial and developer guide are welcoming.  I'm getting OK with the core concepts and have taken a few stabs at custom directives and services.

At this point, I've got a simple app that I can use to manage tasks using a little bit of everything I've learned.  The problem is, I'm using localStorage for persistence, which means I haven't been using $http or $resource or any other asynchronous code.  This is obviously one of the major components of a single-page app, so they need to be explored.

So, next we'll blindly go through getting the full MEAN stack set up and start making this app use the interwebs.  I suppose we couldn't keep the components separate for long.

My Point

Although this blog starts with me poking around the full stack, I've actually spent several weeks just working with Angular.  I have proof.  If you want to be just like me, start with the Angular JS tutorial and read every page of the Developer Guide.  Then goof around on your own for a while until you're starting to feel more confident.  Add angularjs to your Stackoverflow tags and immerse yourself in the awesomeness. 

Getting Started

Read the Bible

Read JavaScript: The Good Parts.  When you're done, read it again.  You've probably read it before, so read it one more time.  Things that made your eyes gloss over the first couple times will be much easier to understand this time.  It's not that I'm a huge Crockford fan, but this is the Javascript book.  You may have discovered the same patterns on your own, but it will reflect negatively on you if you call memoization "method result caching" or some other weird phrase you coined.

It's easy to get submerged in whatever frameworks you've been working in and forget about the nuts and bolts.  Since we want to jump into the cutting edge of Javascript awesomeness, we'd better brush up on the mechanics.  Simply being able to drive does not make you capable of building a better car.

I got the book from Google and have started reading it a few pages at a time on my phone.  Instead of compulsively checking email in the elevator to impress the other people doing the same, I'll just read a page.  I may also revisit JavaScript Design Patterns, though I remember it being a little too verbose and covering much of the same content.

Leave Windows

The best way to learn Spanish is to wake up somewhere in Mexico, right?  So, I'm assuming the same goes for Linux.  Learning *nix has been on my to-do list for a decade, but it never seemed very urgent.  Nuts to that.  I spent a couple hours backing things up, then switched my computers to Ubuntu.  After the initial shock - Oh, god.  What are the shortcut keys?! - the difference isn't severe.  A small piece at a time, I'm learning about the environment, terminal especially.  The great thing about JS is it's interpreted; all we need is a text editor.  As a bonus, all the cool stuff we're going to be doing assumes that you're on Linux or OSX.  Steps in tutorials for Windows users are rare and a huge headache.

When I need to figure something out, I look up how to do it.  Eventually, I'm too lazy to keep Google-ing the same thing, so I just remember it.  Remember, once, sometime in ancient history, you didn't know Windows either.

Get Social

It is assumed that you have a Github account.  You should, and you should commit every day.  I haven't run in months, but I've committed (pun allowed, not intended) to show activity on Github every day.  I'm making it part of my routine.  I started just storing my own work, but now I'm starting to become interested in others'.  Star projects you're into and look at pull requests.  It's nice to see what other people are writing, and the more exposure the better.  Eventually, I'm going to look for some low-hanging fruit and take a stab at a pull request.  I'm sure there's a typo out there I can fix for starters.  Once I've been through that process, I'll aim bigger.

In addition to Github, I've started taking the time to become active on Stackoverflow.  This is like trivia and can be a good break from constant cramming.  Corny, yes, but it also makes me feel kind of nice to help lost noobs, since I have benefited from SO many, many times.

Most employers now research potential hires online, so it can't hurt to increase your presence on these major sites.  As a side-effect, some of the culture, language, customs, and technology is bound to rub off.  Unless you want people judging you based solely on Facebook, get on Github and Stackoverflow.  For me, these two are Facebook.

Assimilation Complete

We are now reading, computing, and social networking like ducks.  Let's start learning how to swim.


Appologies to GN's: I realize changing from talking about myself, us, you, then us, the x repeatedly is terrible.  I am embarrassed to a degree, but this is basically a journal.  If I take on the burden of proper editing and good writing, this blog will quickly become a chore and will die.