In the previous post I created a minimal skeleton app to pass some movie data from RavenDB through a WebAPI endpoint to an AngularJS frontend and also to save new movies back to RavenDB. The code was, as I mentioned in that post, really minimal and by no means a good way of writing it. So in this post I am going to improve on the AngularJS part. It still will not be perfect but better.

 

Inline JavaScript

There are cases where inline JavaScript mixed with you markup makes sense but as a general rule it should be avoided. So lets refactor this part and move out code to a separate JavaScript file. To separate the server and client part of the application as well as the standard JavaScript libraries from  my on code I always create an "app" folder to hold my own JavaScript code. Note that I am using lowercase folder and file names, not a must but a bit of a convention in the JavaScript world.

Another thing is that my ng-app attribute had no reference to a module. That may work in a really minimal application but in any real application you will be adding more like services and directives and you really want to use a module for that. And when you start adding external AngularJS dependencies your module has a dependency on the other modules.

 

   1: (function () {
   2:     'use strict';
   3:     var module = angular.module("myApp", []);
   4:  
   5:     module.controller("moviesCtrl", function ($scope, $http) {
   6:         $http.get("/api/movies").then(function (e) {
   7:             $scope.movies = e.data;
   8:         });
   9:         
  10:         $scope.newMovie = { Title: "" };
  11:         $scope.addMovie = function () {
  12:             $http.post("/api/movies", $scope.newMovie).then(function () {
  13:                 window.location = window.location;
  14:             });
  15:         };
  16:     });
  17: }());

 

All in all the code isn't much harder and at least it is in a separate file so we can start unit testing it as well. More on that in another post.

 

I mentioned that the code is still far from perfect. One of the things I am doing is injecting the $http service into the controller and requesting data from the server inside of the controller. This not only makes the controller harder to unit test but is also breaking the single responsibility rule. The controller should be about gluing things together and another part of the code should be responsible for the HTTP requests. But we will fix that bit in a future post after I have shown how to unit test the controller as it is now.

 

A bit about file organization

Because JavaScript is a really flexible and dynamic language you can be very flexible about how to mix and match code in different files as long as you make sure they are loaded in the right order. However this presents applications with a bit of a challenge. If you forget to include a file, or include then in the wrong order, a part of the application can be non functional and you will never now about it until you actually get to that part.

With AngularJS you can create modules and declare one module to depend on another. If you make sure that a complete AngularJS module is contained in a single file you can be sure that it is either completely there or completely missing. Now the good part with Angular is that if a depended module is not found the module depending on it will not load either. And the result is your complete app fails. Maybe not as good as having Angular load the module for you but at least a missing module is very clear. As a result of this I have a simple rule:

A complete AngularJS module must be defined in a single JavaScript file.

 

Try it

The running application can be found here and the source on GitHub here.

 

Conclusion

This is a small step in improving our AngularJS front end code but an important one. In the next post I will cover getting started to testing the client side JavaScript code.

 

Enjoy!


Blog Post by: Maurice