Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

AngularJS - new app structure and scope

Having worked through all the Angular courses here, and looking at some of the patterns in use for setting up new projects, I'm trying to understand what seems to be a common pattern for scaffolding larger Angular projects.

If you look at the structure below, in each file there is a variable declared with the angular.module container to add controllers, directives etc., which are injected into the app (myApp) in the app.js file as dependencies.

While I'm seeing very simple examples of this pattern, I'm unsure of whether it scales the way I've assumed it does here, or if I'm missing something entirely and this isn't the correct way to scaffold a larger project.

For example, if I create a separate file for specific controllers, and load it after my current controllers.js file, can I just start with "myControllers.controller('MyController..." to define additional controllers, or do I need to create a new variable, assign angular.module etc. to it again and add controllers to that in the second file. Does the first way (if that's valid) mean that all my controllers have access to each others public variables and methods, and the latter isolates each file's controllers from the other?

Should I be simply declaring one var myApp - angular.module('myApp',[]); in the app.js file and then referencing myApp.controller, myApp.filter, myApp.factory in all the other files directly without creating new specific variables for each type?

I feel like I'm missing some core piece of knowledge that would make all of these answers clear, but I don't have it at present.

Thanks, :Steve


app.js
var myApp = angular.module('myApp', [
  'ngRoute',
  'myApp.filters',
  'myApp.services',
  'myApp.directives',
  'myApp.controllers'
]);
controllers.js
var myControllers = angular.module('myApp.controllers', []);

myControllers.controller('MyController', function MyController ($scope, $http...)
directives.js
var myDirectives = angular.module('myApp.directives', []);

myDirectives.directive('MyDirective', function MyDirective ($scope, $http...)
filters.js
var myFilters = angular.module('myApp.filters', []);

myFilters.filter('MyFilter', function MyFilter ($scope, $http...)
services.js
var myServices = angular.module('myApp.services', []);

myServices.service('MyService', function MyService ($scope, $http...)
or
myServices.factory('MyFactory', function MyFactory ($scope, $http...)
Colin Marshall
Colin Marshall
32,861 Points

I fixed your code so it displays on the forum. Please see the Markdown Cheatsheet for instructions on posting code here. You can also edit your original post to see how I did it. Cheers!

Thanks Colin! That's much, much better!

2 Answers

If you want, you can define your controllers, etc. like this:

// app.js

angular.module('myApp', [
  'ngRoute',
  'myApp.filters',
  'myApp.services',
  'myApp.directives',
  'myApp.controllers'
]);
// filters.js

angular.module('myApp.filters', []);
// my-filter.js

angular.module('myApp.filters')
    .filter('MyFilter', function MyFilter ($scope, $http...)

The method angular.module when called with a name and an array of dependencies (like in app.js and filters.js above) is creating a module. When called with just a name (like in my-filter.js), it returns a module of that name (assuming one has been created). So you don't really need to assign any vars when creating modules and attaching things to them.

Hope this helps. Cheers.

Is that overall approach - myApp.filters, myApp.services etc. preferred to something like this?

app.js
var myApp = angular.module('myApp', ['ngRoute']);
controllers.js
myApp.controller('MyController', function MyController ($scope, $http...)
directives.js
myApp.directive('MyDirective', function MyDirective ($scope, $http...)
filters.js
myApp.filter('MyFilter', function MyFilter ($scope, $http...)
services.js
myApp.service('MyService', function MyService ($scope, $http...)
or
myApp.factory('MyFactory', function MyFactory ($scope, $http...)

Personally I'm pretty impartial to putting controllers/directives/filters/services into separate modules. It's not that much extra work, but it only really becomes necessary if you're ever at a point where you'd like to re-use one of your directives/filters/services in a different app.

Example:

Here is myFirstApp, where myService was created.

// my-first-app/app.js
angular.module('myFirstApp', []);
// my-first-app/services.js
angular.module('myFirstApp.services', []);
// my-first-app/services/my-service.js
angular.module('myFirstApp.services')
    .service('myService', function() { /* ... */ });

Here is mySecondApp, where myService can be re-used by listing myFirstApp.services as a module dependency and then injecting myService into controllers, etc.

// my-second-app/app.js
angular.module('mySecondApp', []);
// my-second-app/controllers.js
angular.module('mySecondApp.controllers', [
    'myFirstApp.services'
]);
// my-second-app/controllers/my-controller.js
angular.module('mySecondApp.controllers')
    .controller('MyController', function(myService) { /* ... */ });