Tuesday, May 21, 2013

AngularJS - Unit Testing - Controllers

Since Controllers carry the "business logic" of your Angular application, they're probably the single most important thing to unit test in your Application. I've run across a few tutorials on this subject, but most of them cover only the simplest scenarios. I'm going to try to add some slightly more complicated stuff in to my controller and test it, just to show examples. As I think of new examples as time goes on, I'll try to add those too.

The Controller: What are you testing?


First off, what is a controller? Well, in Angular all a controller really does, for the most part, is accept an injected $scope object and alter it by adding properties, member functions, and calling methods on it (such as $apply and $watch). That's really it. For those of us coming from other MVC backgrounds in other languages, it might feel like a class declaration of some sort with methods defined in the actual controller, but in reality, it's just a function that gets called to set up the state of a $scope object that is passed to it. Sometimes there are services injected into it that also get called or get their state altered, but I'll get to that in a bit.


Recommended Testing Suite: Jasmine


The recommended tool for testing Angular is Jasmine. You can, of course, use any unit testing tool you like, but for this blog entry, we'll be using Jasmine. To get started with Jasmine they have some really well annotated code on their site as a tutorial of sorts, but I'd recommend just going to Plunker and starting a new "Angular + Jasmine" Plunk and fiddling around until you get the hang of it.


To TDD or not to TDD? Yes.


I'm not going to go into the specifics of TDD, whether or not you should use it, the pros and cons of TDD, or even attack this blog entry from that angle. I'm going to assume that if you're here, you've probably written some Angular controller, or you know how to write an Angular controller, and you're thinking "how do I test this thing?". So we'll just cover some of those basics, mkay?


The Basic Setup


Let's start off with the basic Jasmine Set up. This is what's required to run the Jasmine specs you're going to write, and produce a report in HTML format you can read. So to do all of this, you will create some HTML file, we'll call it "SpecRunner.html" and this would be the basic content of it:

<!doctype html>
<html>
<head>
  <!-- jasmine -->
  <script src="jasmine.js"></script>
  
  <!-- jasmine's html reporting code and css -->
  <script src="jasmine-html.js"></script>
  <link href="jasmine.css" rel="stylesheet">

  <!-- angular itself -->
  <script src="angular.js"></script>
  
  <!-- angular's testing helpers -->
  <script src="angular-mocks.js"></script>

  <!-- your angular app code -->
  <script src="app.js"></script>
  
  <!-- your Specs (tests) -->
  <script src="specs.js"></script>
</head>
<body>
  <!-- bootstrap jasmine! -->
  <script>
    var jasmineEnv = jasmine.getEnv();
 
 // Tell it to add an Html Reporter
 // this will add detailed HTML-formatted results
 // for each spec ran.
    jasmineEnv.addReporter(new jasmine.HtmlReporter());
 
 // Execute the tests!
    jasmineEnv.execute();
  </script>
</body>
</html>



An Example Controller


So now we'll need something to test. I'm going to make up a completely contrived controller to create some unit testing examples against. Nothing special, and nothing that might even make sense. It's just different things you might commonly do in an Angular controller, that you might need to test. In the specsRunner.html file above, this would be our "app.js".

var app = angular.module('myApp', []);

/* Set up a simple controller with a few 
 * examples of common actions a controller function
 * might set up on a $scope. */
app.controller('MainCtrl', function($scope, someService) {
  
  //set some properties
  $scope.foo = 'foo';
  $scope.bar = 'bar';
  
  
  //add a simple function.
  $scope.test1 = function (){
    $scope.foo = $scope.foo + '!!!';
  };
  
  //set up a $watch.
  $scope.$watch('bar', function (v){
    $scope.baz = v + 'baz';
  });
  
  //make a call to an injected service.
  $scope.test2 = function (){
    //an async call returning a promise that
    //inevitably returns a value to a property.
    $scope.fizz = someService.someAsyncCall($scope.foo);
  };
});


/* Simple service example. 
 * This is a service created just to use as an example of
 * some simple service that is making some asynchronous call.
 * A real-life example of something like this would be a 
 * service that is making $http or $resource calls, perhaps. */
app.factory('someService', function ($timeout, $q){
  return {
    
    // simple method to do something asynchronously.
    someAsyncCall: function (x){
      var deferred = $q.defer();
      $timeout(function (){
        deferred.resolve(x + '_async');
      }, 100);
      return deferred.promise;
    }
  };
});


Unit Tests For Our Example Controller


So, given the above controller, here is a battery of unit tests that tests the behavior of this controller. Well, more importantly, it tests what has been set up on the $scope by the controller function. In the specsRunner html (above), this would be in our "specs.js":


describe('Testing a controller', function() {
  var $scope = null;
  var ctrl = null;
  
  /* A mocked version of our service, someService
   * we're mocking this so we have total control and we're
   * testing this in isolation from any calls it might
   * be making.
   */
  var mockService = {
    someAsyncCall: function (x){
      return 'weee';
    }
  }
  
  //you need to indicate your module in a test
  beforeEach(module('myApp'));

  /* IMPORTANT!
   * this is where we're setting up the $scope and
   * calling the controller function on it, injecting
   * all the important bits, like our mockService */
  beforeEach(inject(function($rootScope, $controller) {
    //create a scope object for us to use.
    $scope = $rootScope.$new();

    //now run that scope through the controller function,
    //injecting any services or other injectables we need.
    ctrl = $controller('MainCtrl', {
      $scope: $scope,
      someService: mockService
    });
  }));

  /* Test 1: The simplest of the simple.
   * here we're going to test that some things were 
   * populated when the controller function whas evaluated. */
  it('should start with foo and bar populated', function() {
    
    //just assert. $scope was set up in beforeEach() (above)
    expect($scope.foo).toEqual('foo');
    expect($scope.bar).toEqual('bar');
  });
  
  
  /* Test 2: Still simple.
   * Now let's test a simple function call. */
  it('should add !!! to foo when test1() is called', function (){
    //set up.
    $scope.foo = 'x';
    
    //make the call.
    $scope.test1();
    
    //assert
    expect($scope.foo).toEqual('x!!!');
  });
  
  
  /* Test 3: Testing a $watch()
   * The important thing here is to call $apply() 
   * and THEN test the value it's supposed to update. */
  it('should update baz when bar is changed', function (){
    //change bar
    $scope.bar = 'test';
    
    //$apply the change to trigger the $watch.
    $scope.$apply();
    
    //assert
    expect($scope.baz).toEqual('testbaz');
  });
  
  
  /* Test 4a: Testing an asynchronous service call.
   * Here we don't really even need to worry about asynchronicity.
   * Since we make a mockService (above) and injected it,
   * We can take out the asynchronous stuff and just test that it's 
   * returning a value.  We can test the service's asynchronous behavior
   * when we test the service, it's not the controller's concern. */
  it('should update fizz asynchronously when test2() is called', function (){
    //just make the call
    $scope.test2();
    
    //assert
    expect($scope.fizz).toEqual('weee');    
  });
  
  /* Test 4b: Probably should test that the service method was
   * called as well. We'll use Jasmine's spyOn() method to do
   * this. */
  it('should make a call to someService.someAsyncCall() in test()', function (){
    //set up the spy.
    spyOn(mockService, 'someAsyncCall').andCallThrough();
    
    //make the call!
    $scope.test2();
    
    //assert!
    expect(mockService.someAsyncCall).toHaveBeenCalled();    
  });
});



The Simple Tests


I don't want to dwell too much on the first two tests. They're fairly straight forward, and I don't want to patronize anyone that's made it this far. They're your basic, basic, unit tests. Make a call, assert a value, the end.


Testing a $watch()


Okay, here there's a little trick. If you have a $watch set up on a property, or on anything really, and you want to test it, all you need to do is update whatever you're watching on the $scope (or wherever it is), then call $scope.$apply(). Calling $apply will force a digest which will process all of your $watches.


Testing Service Calls and Asynchronous Service Calls


Really, anything asynchronous you do in an Angular controller should be done in some sort of injectable service. Whether that injectable service is $timeout, or some service you created yourself that makes async calls with $http or $resource. Because we're testing the controller, and because the service is injectable, you really shouldn't have to worry about the asynchronous nature of what's happening inside the service. Testing that should be done in your service unit tests, not your controller unit tests. So what we're going to do here is create a mock service (mockService in the example above). Because we're doing this we have a lot of control. Test 4a above shows a test that tests the result of the call.  Test 4b above shows a tests that uses Jasmine's spyOn() method to verify that our service method was indeed called.


View the complete example on Plunker

More to come...


I realize this is an article on unit testing just one, small, relatively easy to test part of Angular. And there are much scarier things to right tests for... like say... directives (shudder). However, I think this is a really good place to start off with unit testing in Angular. One, because your important business logic should really be happening in controllers anyhow; And two, because it really is one of the easiest things to test in Angular. 

Going forward, I will definitely try to add entries on unit testing things like services and directives.

Monday, March 4, 2013

Angular JS: Validating Form Elements in a Repeat

How do I use Angular's form validation on these dynamically created elements?


The common scenario is this, you have some ng-repeat creating inputs of some sort, and you need to validate them individually. The knee-jerk reaction is to try to dynamically add names to the input like name="test{{$index}}"... but that won't really work. So now what?


ngForm directive!


The ng-form directive allows for nesting forms that can be used for things like partial validation. The idea is simple, on each repeated element, add an ng-form directive with a name. Then inside that, you can now reference inputs by name on that subform.



<!-- The "main" form directive is the outer form tag. -->
<form name="mainForm" ng-submit="submitAll()">
  <ul>        
        <!-- We add ng-form to the tag ng-repeat is on,
               to create a nested form context. -->
 <li ng-repeat="item in items" ng-form="subForm">
   <input type="text" required name="name" ng-model="item.name"/>
          
          <!-- now we can reference the validated field by name -->
          <span ng-show="subForm.name.$error.required">required</span>
          
          <!-- the nested form context itself can also be checked for validity. -->
          <button type="button" ng-disabled="subForm.$invalid" 
                     ng-click="submitOne(item)">Submit One</button>
 </li>
  </ul>

  <!-- last, but not least, the validation from our 
         subform bubbles up to our main form! -->
  <button type="submit" ng-disabled="mainForm.$invalid">Submit All</button>
</form>



So that's the idea in a nutshell. I'm not going to get too much more verbose with it than that. I've already covered form validation and custom validation elsewhere in my blog. But I will leave you with this plunker to play with that demonstrates this sort of dynamically created form validation, so you can fork it and play with it for yourself:


Monday, February 25, 2013

JavaScript - Dynamic Prototyping

There are thousands of JavaScript prototype tutorials online


Okay, so most people know about and/or understand JavaScript's prototypical inheritance system. Every object has a prototype which is an object, and when you look for a property on that object, if it doesn't have it, it checks the prototype for the property, and if it doesn't have it, it checks prototype's prototype for the property, etc. etc. (If anyone really wants me to do an entry on this, let me know, but rest assured it's pretty well covered elsewhere)


First let me go over the plain, boring ways prototype is commonly used

(It gets better further down)

In practice, 99% of the time, JavaScript's prototype ends up getting used like this:

//create some class.
function Foo() {
}

//add some properties to it.
Foo.prototype.test = function () {
   alert('wee');
};
Foo.prototype.bar = 123;

//use it.
var foo = new Foo();
foo.test(); //alert wee
console.log(foo.bar); //123


Boring. Boring. Boring.


Then occasionally you'll see some blog entry come along about "OOP in JS" or whatever and you'll see prototype getting used like so:

//create a class.
function Foo(){
}
Foo.prototype.test = 'wee';

//create another class.
function Bar() {
}
//that inherits from the first class.
Bar.prototype = new Foo();

//try it out.
var bar = new Bar();
console.log(bar.test); //wee


Okay, well that's a little more interesting, right? We've got some semblance of two class definitions where one inherits from the other. Pretty cool, I guess. Still not terribly exciting, though.


Dynamic Prototyping! (Finally something interesting)


I'm sure there's a better word for it, but I'm calling it "Dynamic Prototyping" (it's my blog!). JavaScript is dynamic and fun. Certainly we can do something cooler with this right? I mean, this seems like something we can really hack to our advantage. And then I saw what AngularJS was doing with prototypical inheritance. They were using it in a dynamic way, allowing "scopes" to inherit from one another, and changes to propagate from parent to child (but not child to parent). Check this out:

//create a class
function Foo(){ 
}

//Give it a method to create child clones of itself
Foo.prototype.spawnClone = function() {
    //Dynamically assign the current instance as a prototype.
    Foo.prototype = this;
    //return a new one
    return new Foo();
};

//Give it a try
var foo = new Foo();
foo.bar = 'test';
var fooSpawn = foo.spawnClone();
alert(fooSpawn.bar); //test

//so far, so good, but watch this:
foo.bar = 'weee';

//we actually updated the child by updating the parent!
alert(fooSpawn.bar); //weee


Now that's cool! Now I can take an object, and create a "child object" that not only inherits its properties, but is actually bound to that object programmatically. Granted, it's a one way binding, but it's still a lot of fun.


Watch out! Prototypical Madness!


So, we learned that we can dynamically prototype a constructor function. That's pretty cool. But watch out! The class will use whatever prototype was assigned to it last!

See where we can run into problems here (assuming the above code):

var foo = new Foo();
var fooSpawn = foo.spawnClone();
foo.bar = 'test';

var foo2 = new Foo();
//OOPS: We don't want this! We've messed with the prototype and it stuck!
alert(foo2.bar); //test


The fix to get around that is simple, you just need to do one of two things: Copy off the original prototype and reassign it after the child is created and/or use an extend method (such as JQuery's extend) to augment your child class's prototype prior to created a new instance:

function Foo() {
}

Foo.prototype.betterSpawnClone = function (){
    //create a copy of the current prototype.
    var protoCopy = Foo.prototype;
    //dynamically assign the prototype.
    Foo.prototype = this;
    //create the clone.
    var clone = new Foo();
    //reset the prototype back to normal.
    Foo.prototype = protoCopy;
    //return our clone.
    return clone;
}

Anyhow, here's a fiddle to play with. It's a fun little trick with JavaScript and I hope it's useful to someone:

Wednesday, February 13, 2013

AngularJS: Creating A Service With $http

So I did a talk on AngularJS last night at the Pittsburgh .NET Users' Group. It was a great talk and you guys asked a lot of great questions. One of my friends that attended suggest people use my blog as a resource for Angular, and while I do have quite a few posts about Angular, I don't feel like it's quite as flushed out in that department as I'd like it to be before I wanted my friends plugging it like that. So I've decided to try to fill that gap, at least as far as Angular goes, over the next few weeks, if I can. (Don't worry, PGHNUG attendees, I'll still try to get a well commented Angular/Web API solution up on GitHub soon).


HTTP Service Calls In Angular The "Classic" Way

(old and busted)

One of the most common questions I see on StackOverflow regarding Angular, are questions involving the creation of AJAX-based angular services using $http. Commonly the pattern used is very reminiscent of JQuery, where there's a method with a callback when the data is received.

Common Callback Example


app.factory('myService', function($http) {
   return {
     getFooOldSchool: function(callback) {
       $http.get('foo.json').success(callback);
     }
   }
});

app.controller('MainCtrl', function($scope, myService) {
  myService.getFooOldSchool(function(data) {
     $scope.foo = data;
  });
});


That's fine. It's an easy to understand pattern that is predictable for most other developers using your service and most importantly, it works.


Angular Loves Promises

(the new hotness)

In Angular, there is a service called $q. It is a deferred/promise implementation built off of Q by Kristopher Kowal. I know I've talked about deferment and promises in JavaScript in the past, but as a very quick refresher, the idea behind this pattern is basically to have a mechanism to signal when one (or sometimes many) asynchronous actions are complete. It's the hub of JQuery's AJAX implementation, Angular $http implementation and Angular's $resource implementation. I like this mechanism so much I've even implemented it in my .NET Event Loop Framework.

Promises get special treatment in Angular however, because when a promise is resolved, Angular will trigger a digest, and any scope properties that contain a promise will be evaluated for that promise's resolved value. So in code, that means if you return a promise from your service, and put it directly in a scope property, it will asynchronously update that scope property and process the changes.

Promise Pattern Example


app.factory('myService', function($http, $q) {
   return {
     getFoo: function() {
       //create our deferred object.
       var deferred = $q.defer();

       //make the call.
       $http.get('foo.json').success(function(data) {
          //when data is returned resolve the deferment.
          deferred.resolve(data);
       }).error(function(){
          //or reject it if there's a problem.
          deferred.reject();
       });

       //return the promise that work will be done.
       return deferred.promise;
     }
   }
});

app.controller('MainCtrl', function($scope, myService) {
   //the clean and simple way
   $scope.foo = myService.getFoo();

   //OR if you need to wait for the value to return 
   //to do something with it...
   myService.getFoo().then(function(data) {
       //this will execute when the 
       //AJAX call completes.
       $scope.foo2 = data;
       console.log(data);
   });
};



And because some of you like to play around, here's a bit of code on plunker showing the promise pattern for $http calls in Angular:


Tuesday, February 5, 2013

Angular JS - Scrolling To An Element By Id

So a question on StackOverflow recently was asking about how to scroll to an element by an anchor id, and it garnered some really hacky answers. They worked, but it seemed weird that Angular would force you to jump through hoops to manage scrolling. I thought the question was intriguing because it dealt with a potentially common scenario with a client-side routed application: How do I scroll to an element on the page?



Angular Already Has It

(I'm hoping for $kitchenSinkProvider in 2.x!)

Turns out that Angular already has a mechanism for this called $anchorScroll(). Unfortunately, it's poorly documented, and I had to actually view the source code on GitHub to figure out how to use it. So here's my attempt to remedy this: A quick run down of how to use $anchorScroll to scroll to the proper element after a routed request:

$anchorScroll works off of the hash value set in $location.hash(), so to use it dynamically, you'll need to first set $location.hash to something, then you'll need to call $anchorScroll().


Scrolling To An Element By ID With Routing


So presuming you've set up routing for your application module already in your .config function, I'm going to set up the scrolling mechanism in the application module's run function like so:

app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    $location.hash($routeParams.scrollTo);
    $anchorScroll();  
  });
});

Pretty simple, right? What I did here is I subscribed to the $routeChangeSuccess event broadcast by the $routeProvider. Inside of that, I set the $location.hash to the value passed into $routeParams at the key scrollTo.

But where does that scrollTo value come from?

<a href="#/test/123/?scrollTo=foo">Test id=123, scroll to #foo</a>

The above link, assuming I have a route like "/test/:id" will route and then scroll to foo. It seems to be a little known thing about Angular that you can pass as many parameters as you like into $routeParams via a faux-querystring.

Anyhow, here is a demonstration on Plunker of the above technique.



Scrolling To An Element By ID Without Routing


Now something to note about $anchorScroll is that you don't have to use it just with routing, if that weren't obvious. You can inject it into any controller or directive and call it as you see fit. You just need to make sure you're setting the hash on Angular's $location.

For example, you could add an item to a list, and then scroll to it after it were added:


app.controller('MainCtrl', function($scope, $location, $anchorScroll) {
  var i = 1;
  
  $scope.items = [{ id: 1, name: 'Item 1' }];
  
  $scope.addItem = function (){
    i++;
    //add the item.
    $scope.items.push({ id: i, name: 'Item ' + i});
    //now scroll to it.
    $location.hash('item' + i);
    $anchorScroll();
  };
});


And here is demo of that on Plunker

Now, truth be told, it's a bit of fuzzy ground as to whether or not you should be using $anchorScroll in a controller like that. Since it's sort of "DOM manipulation" maybe it belongs in a directive... Then again, it never directly references the DOM does it? So it's most likely okay. It's down to a judgement call, and I always differ to whatever is easiest to maintain in those cases.


I Hope This Helps Someone


It's certainly not a well-documented feature. And in the sake of full (probably obvious) disclosure: I did of course contribute my answer on StackOverflow, I don't know or even care whether or not it's accepted, it's likely a better place than my blog for the answer to be so more people find it. I just want to make sure I got what I learned down somewhere I might think to look later, or that might help someone else.

If you found this and it helped you, I'd encourage you to head over the StackOverflow and answer just one question and help someone else. Pick a question you might not even know the answer to if you want to learn something new. The important thing is that we keep technology pushing forward by contributing, gaining knowledge, and innovating.

Monday, February 4, 2013

JavaScript - Scalar Promotion aka Hoisting

Scalar Promotion or Hoisting is a property of JavaScript that is often ignored but can cause some pretty crazy issues. (I like the term Scalar Promotion because it helps me fool people into thinking I'm smart and "Code Motion" sounds like I'm bullshitting too hard. Haha). To illustrate what it is and how it works, I'm going to show a few code examples. Take the following, very simple code for example:

(function() {
    var foo = 'abc',
          bar = 'xyz';
    console.log(foo + bar); //abcxyz
})();

The output of the above, as you might expect, will be abcxyz. Now lets have a look at what happens if we don't assign bar:


(function() {
    var foo = 'abc',
          bar;
    console.log(foo + bar); //abcundefined
})();


Now the output is going to be abcundefined. So what happens if we remove the declaration of bar?


(function() {
    var foo = 'abc';
    console.log(foo + bar); //ReferenceError!!!
})();


Now we get a ReferenceError, because bar was never declared. Well that makes sense, right? But to show you what Scalar Promotion is all about have a look at this.. we'll move the declaration of bar to somewhere below the console.log():

(function() {
    var foo = 'abc';
    console.log(foo + bar); //abcundefined again
    var bar;
})();

... and the result is abcundefined. Okay, what the tell right? Why does this behave that way? Scalar Promotion. Basically as a compiler optimization, all declarations are moved to the top of your code, so to speak. This is why you can use a function in code before you've declared it in javascript:

(function (){
  callMe();

  function callMe() {
    alert("I've been called!");
  }
})();


The reason this can become problematic is that JavaScript doesn't force you to declare your variables. So consider the following code:

// A Tale Of Two Foos
(function (){
    
    // an anonymous function to do something or other asynchronously
    // this could be anything, like an ajax callback for example.
    setTimeout(function (){
        
        //manipulate foo, but forget to declare it.
        for(var i = 0; i < 10; i++) {
          foo += 'x';   
        }
        
        // SORCERY?!!! 45xxxxxxxxxx?! 
        // this should just be ten  x's!
        console.log(foo);
    },0);
    
    /* ---
    assume some large amount of code here. So you don't 
    know/remember these two foos are in the same scope.
    --- */
    
    // declare foo and add some numbers to it.
    var foo = 0;
    for(var i = 0; i < 10; i++) {
        foo += i;
    };
    console.log(foo); //45
})();


Do you see what happened there? One little missed declaration and there's no error... just a bug. Generally the only way to avoid this is to try to declare your variables at the beginning of your function scope if possible/practical. Either way, be careful to declare you variables, kids!

Thursday, January 3, 2013

Structuring A Clientside JavaScript Application


World's largest bowl of spaghetti
... or how I wrote JavaScript the first half of my career




A lot of this will seem like common sense to some, but I have on many occasions seen very good developers write some pretty poorly structured JavaScript apps (including myself, haha), and I've been asked about it a few times recently, so I'll give it a shot. I hope to go over most of what I know in this arena.  There is a good amount to go over, but I'll try to hit the most important basics.


Use A JavaScript Bundler/Minifier/"Compiler"


Probably the biggest and most important thing to do with a large JavaScript client application is to give yourself the ability to separate your code out into individual files each containing code with a single responsibility without during your user experience with a ton of .js files to download.  The best way to do that is by using a tool to take your individual JavaScript files and compile them into a single JavaScript file (minified or un-minified). Fortunately, there are a lot of tools for doing this. Notably tools like UglifyJS and the build tool Grunt, ASP.Net MVC4's new Bundling and Minification features, extensions for Visual Studio like Mindscape Workbench.  They all offer a variety of features, some of them will even do things like run JSLint against your code or kick off unit tests in various JS testing frameworks.  The important features you're looking for is "bundling" or concatenation, and minification.


Use the Module Pattern


The module pattern is something that has been covered extensively all over the web, and probably better than I could do it, but the basics of the module pattern is to use JavaScript closure in an immediately executed anonymous function to contain all variables and functionality that you want to remain private to a set of code. You can do tons of stuff with this pattern, and it really saves you from junking up your global scope, be it a module in NodeJS or the window object in a browser. I recommend wrapping your practially your whole JS file in the module pattern specifically because then you're guaranteed to know what you're adding to the global scope, because you've done so explicitly.

So basically you're looking at something like this:
;var myModule = (function($, foo) {
    //here $ and foo are local to the scope.

    //here's some private variable.
    var bar = 123;

    //here's a private function
    function superThing() {
       alert('Bar is ' + bar++);
    }

    /** You can alter injected objects to
        effect the outside **/
    // here we'll alter the jQuery object by adding a plugin.
    $.fn.superPlugin = function() {
       $(this).on('click', superThing);
    };
    
    // same as above but we're removing a binding here.
    $.fn.removeSuperPlugin = function() {
       $(this).off('click', superThing);
    }

    /** You can have it return an interface 
        to whatever it's doing **/    
    return {
        incrementBar: function () {
            bar++;
        },
        callSuperThing: function (){
            superThing();
        }
    };
})(jQuery, foo);


Note: So what's the ; for in the module above? Basically to keep bundlers and minifiers from combining two function calls into one function call, causing errors: (function(a,b){})(c,d)(function(w,x){})(y,z)


Structure Your Files Appropriately


Think of your class files or code files in your usual programming language of choice: C++, Java or C# for example. You're breaking your code out into files based on single responsibility. (Or at least I hope you are). You should be doing the same with your JavaScript files. Because you're bundling them or building them into a single file prior to hosting them, you now have the freedom to structure your JavaScript files however you want.

An example of such a file structure might be (for an Angular app for example):


  +-App
  | +-Directives
  | | +-my-click-directive.js
  | | +-table-directive.js
  | | +-directives-module.js
  | |
  | +-Controllers
  | | +-HomeCtrl.js
  | | +-SearchCtrl.js
  | | +-FooCtrl.js
  | |
  | +-Services
  | | +-facebook.js
  | | +-twitterSearch.js


... you get the idea. But the point is that in the end, it doesn't matter how many files you have, as long as you can easily maintain and organize them. The alternative is to have the one JavaScript "mega-file" which I've seen way too many times.


But, How Do I Debug Bundled Or Minified Files?


This actually isn't ask bad as you'd think. Some of the packages, MVC4's bundler for example, will actually output individual files when you're in debug mode. Other bundlers will tack some whitespace and a comment in with the name of the file where concatenations have been done. This is helpful if it's not minified. Also if it's not minified, your comments will show up, and if you've added good comments, and you know how you've structured your app, it shouldn't be a huge leap to find the offending lines of code in your source while you're debugging.

But what about if the file is minified? Well, now you're in for it, I guess. However, some browsers, such as Google's Chrome actually have a feature to "prettify" minified code to so you can step through it in a readable format. (In Chrome this feature is a little button with a {} in it in your developer's console)



LOOK AT OTHERS' EXAMPLES!!!


Another really great way to get an idea on how to structure your JavaScript code is too look at examples presented by others. They are all over the place these days! Just think of your favorite JavaScript framework or library and check them out on GitHub: JQuery, Angular, Ember, etc. All really awesome examples of how to effectively structure your JavaScript code and files.