Showing posts with label MEAN stack tutorial. Show all posts
Showing posts with label MEAN stack tutorial. Show all posts

Sunday, April 6, 2014

Angular JS - Directives

I've spent a lot of time recently mucking around across the whole MEAN stack. MEAN.io includes a lot of added tools, which is cool, but it can be distracting. So, I'm going to refocus now that I'm comfortable with the entire stack. No, I'm not an expert yet, just comfortable. Documenting almost every line of the code really helped to understand what was going on as did working on my own goofy project. I made a time/task tracking system to use at work. That was a good way to let the MEAN stuff sink in, but eventually the learning slowed and I started to focus on the business logic of what I was doing. That's fun, but now it's time to get back to deliberate study.
So, back to Angular. The first thing we'll focus on is directives.

Directives

There are lots of built in directives. Read over this cheat sheet and learn how they work.

How Directives Work

Directives identify parts of the DOM that should have special Angular goodness. These parts are picked up by the compiler (see $compile).
Directives are attached to modules using the directive method of the $compileProvider.
What is a directiveFactory?
The directive factory is executed the first time the compiler matches the directive. The function returns an object that tells $compile (see Directive Definition Object) how the directive works.

Making Custom Directives

A Simple Example

angular.module('foo').directive('pointless', function () {
    return {
        template: 'some text to show in directive'
    };
});

Isolate Scope

The purpose is to isolate the scope within the directive from the scope outside the directive. This is done with the scope option of the directive definition object.
The isolate scope does not inherit from the parent scope.
The scope option maps outer scope values to inner scope values in three different ways.
  1. @ - map from directive's attributes as strings
    • innerFoo: '@' The inner scope's innerFoo value comes from the directive's inner-foo attribute.
    • innerFoo: '@outerFoo' The inner scope's innerFoo value comes from the directive's outer-foo attribute.
    • Any interpolated values (defined in the directive's attribute to pull from the outer scope) will still populate from the outer scope.
  2. = - map from parent scope property to isolate scope property
    • innerBar: '=' - The inner scope's innerBar value is bound to the outer scope value indicated in the directive's inner-bar attribute.
    • innerBar: '=outerBar' - The inner scope's innerBar value is bound to the outer scope value indicated in the directive's outer-bar attribute.
    • Values bound like this will update each other. Changes in the isolate scope will be reflected in the outer scope and vice versa.
  3. & - map an expression to be executed in the outer scope
    • This follows the same pattern as above, though I can't think up an example.

References

Monday, March 10, 2014

No Update

Work has been keeping me way too busy the last few days, but I'm still keeping up my Github streak.  I'm currently (npm install is running now) trying to set up a MEAN stack with ExtJS 4 included.  Yeah, it's crazy, but I'm just goofing around.

It's interesting to see how Ext uses controllers.  They all appear to be bound to the viewport rather than within the scope of an element like in Angular.  For my commit tonight, I'm going to see if I can figure out a way to bind the Ext controllers the scope of an element.  Hopefully, after this sprint, I'll get out of the mire and back into the cool stuff.  Look at the last blog - I'm deploying to Heroku in minutes!  That's way more fun that what's happening at work.

An Aside

This really has nothing to do with my pursuit of MEAN-ness, but I'm going to include it.  Spaghetti code, hacking things together, ignoring conventions, and using design patterns only in conversation are so freaking bad!  There's a reason people identify patterns and anti-patterns.  Just because you're under pressure to make a deadline does not make it OK to avoid the collective wisdom of thousands of people who are more experienced and smarter than you.  In fact, it's the opposite.  A quick "win" today will inevitably lead to heartache later on.  Don't be short-sighted.

This message brought to you by the poor asshole who has to maintain, refactor, fix, and build on your mess.

Friday, March 7, 2014

Notes: Deploying MEAN Boilerplate to Heroku

Notes: Deploying MEAN Boilerplate to Heroku

Create the Heroku App

heroku create

Push to Heroku

git push heroku master

View the App

heroku open

WTF? Application Error

Mongo is not available.

Setup Mongo

MongoHQ offers free hosting for MongoDBs. Heroku has a free addon for MongoHQ.

Add MongoHQ

heroku addons:add mongohq
Heroku wants my credit card before allowing the addon. Um, no.

Use MongoHQ with Heroku without a Credit Card

The Heroku addon basically just sets up your HerokuHQ stuff for you. If you want to skip the credit card, you can set it up yourself.

Setup MongoHQ

Create a MongoHQ account. Choose the free sandbox version.
Once you're set up, find the url to your sweet new db. It looks something like: mongodb://:@troup.mongohq.com:10027/reergymerej
Create a user for the db through the web interface. I'm sure you can do it from terminal, but you're already here.
Now go to your terminal. :) Verify that you can connect.
mongo troup.mongohq.com:10027/reergymerej -u <user> -p<password>
or
mongo troup.mongohq.com:10027/reergymerej db.auth('dude', 'dude');

Connect Your App

See if you can connect to your MongoHQ db from your local MEAN app.
Where do you change the db settings?
/config/env/development.js
Change the db from localhost to the url you got above (the one with the username/password in it).
db: 'mongodb://dude:dude@troup.mongohq.com:10027/reergymerej',

Welcome to Error Town

/home/grizzle/code/the-runs/node_modules/mongodb/lib/mongodb/connection/base.js:242
    throw message;
I know the authentication works since I can connect through the terminal directly. I'm too tired to figure this out tonight.

Try, Try Again

The problem was with my copy/paste. In /config/env/development.js, I specified
db: 'mongodb://dude:dude@troup.mongohq.com:10027/',
instead of
db: 'mongodb://dude:dude@troup.mongohq.com:10027/reergymerej',
Dur.
I tested locally pointing at the remote db and everything's working. I confirmed through the UI and terminal.
mongo troup.mongohq.com:10027/reergymerej db.auth('dude', 'dude'); db.runs.find().pretty();
Now, let's deploy this sucker. Change db in production
/config/env/production.js

Commit and Push

git add . git commit -m 'change db config for production' git push heroku master
This pushes from our local repo to Heroku, not from our Github repo. Changes must be commited to the local git repo before they can be pushed to Heroku.
Around this point, my notes degrade pretty quickly. I changed the production db to the MongoHQ db and kept the dev db pointing at localhost. Heroku deployed alright, but the app wouldn't respond in the browser. heroku logs mentioned something about failing to connect to localhost, so I figured the app still thought it was in dev mode. For expediency, I changed the dev db to the remote also, deployed again, and everything started working.
Along the way, I noticed there's a MONGOHQ_URL in /config/env/all.js. We should probably use that, but lunch breaks are only so long. I chewed up a bit of my time researching how to keep from exposing credentials in Github.

Keep Production Credentials off Github

We use git to deploy to Heroku. We also use git to save our code on Github. How can we keep our production credentials in git, available to push to Heroku, but not available to Github?
I haven't quite figured it out and that's OK since my username &password are both 'dude' and no one's going to bring down my test db rocking one dyno. It's a good question, though. Here are a couple references I found:

tl;dr

  • Heroku doesn't provide MongoDB.
  • Create the db in HerokuHQ.
  • Configure MEAN environments to use HerokuHQ.
  • Don't push username/password to Github.

References

Wednesday, March 5, 2014

How to get Bootstrap with Bower

This is a quick post to explain how you can use Bower with your cool new MEAN stack. For this example, we'll install Bootstrap.

Install the Package(s)

bower install bootstrap

OK, all done. No, not really. All we did was download the files. They're not automatically added to our html somehow.

Where does Bower put files?

Out of the box, the MEAN stack puts Bower's files in /public/lib. This is a configuration setting in .bowerrc.

"directory": "public/lib",

How to Use the New Files

The lib directory is public, so we can access them directly. For simplicity, you can add it to /app/views/includes/head.html.

<script src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>

What about dependencies?

Dependencies will be installed automatically by Bower. That's one of the main reasons to use a package manager. Boostrap has a dependency on jQuery, so it has been installed as well.

How do you know what dependencies to use?

When you install a package, the dependencies are listed.

bower install bootstrap#3.0.3 bower install jquery#2.1.0

bootstrap#3.0.3 public/lib/bootstrap
└── jquery#2.1.0

You can view all your current packages and their dependencies with

bower list

You can view the dependencies in the package's bower.json file. /public/lib/bootstrap/bower.json shows that bootstrap needs jQuery.

"dependencies": {
    "jquery": ">= 1.9.0"
}

Include the dependencies the same way as the main package. <script src="/lib/jquery/dist/js/jquery.min.js"></script>

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.

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.