0

I am new to Angular and I am currently trying to build something very simple, but I have a problem I am stuck and I don't understand why is it happening.

I have a small project in Webstorm with Express and npm. Angular is added as a dependency, version 1.5.3. I am also using Jade as a template language. Here is what I have in Plunker http://plnkr.co/edit/qCR420hBgnlcUisSOwgw?p=preview

Also listed below:

doctype html
html(lang='en', ng-app='courses')
head
    meta(charset='utf-8')
    meta(name='viewport', content='width=device-width, initial-scale=1, user-scalable=no')

    script(src='/node_modules/angular/angular.js')
    script(src='/node_modules/angular-resource/angular-resource.js')
    script(src='/node_modules/angular-route/angular-route.js')
    script(src='/javascripts/app.js')
    script(src='/javascripts/controllers.js')
    script(src='/javascripts/services.js')

    title= title
    link(rel='stylesheet', ref='//netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css')
    link(rel='stylesheet', href='/stylesheets/style.css')
body(ng-controller='CoursesListController')
    nav.navbar.navbar-inverse.navbar-fixed-top(role='navigation')
        div.navbar-header
            a.navbar-brand(href='#/courses')=title
    div.container
        div(ng-view)

My app.js:

angular.module('courses', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
        .when('/courses', { templateUrl: 'partials/list.html', controller: CoursesListController })
        .when('/course/:courseId', { templateUrl: 'partials/item.html', controller: CourseItemController })
        .when('/new', { templateUrl: 'partials/new.html', controller: CourseCreateController })
        .otherwise({ redirectTo: '/courses' });
}]);

My controllers.js

function CoursesListController($scope, $routeParams, Course) {
    $scope.courses = Courses.query();
}

And my services.js:

angular.module('courseServices', ['ngResource']).factory('Course', function 
($resource) {
    return $resource('courses/:courseId', {}, {
        query: {method: 'GET', params: {courseId: 'courses'}, isArray: true}
    })
});

The error I get is:

angular.js:13294 Error: [ng:areq] Argument 'CoursesListController' is not a function, got undefined

And I not sure why. Besides, maybe some tips would be useful you think such a structure/separation makes sense?

10
  • Did you forget to register your controller with your module ? Commented Mar 24, 2016 at 14:54
  • Is this dupe of Use .controller('myCtrl', ['$scope', function($scope) {...? Commented Mar 24, 2016 at 14:55
  • No, it's not that, I fixed the typo. Commented Mar 24, 2016 at 14:58
  • I see the function for CourseListController, but where are you actually registering it as a module? Also, this: angular.module('courseServices', ['ngResource']) is going to create a new app module that makes courseServices unavailable in courses unless you inject it. Commented Mar 24, 2016 at 15:00
  • Definitely, fix that typo in your controller and put the app.js at the bottom of your script loading order. Commented Mar 24, 2016 at 15:01

1 Answer 1

2

This is a loading order issue.

Basically you first load app.js which tries to register the function that is not loaded yet.

To fix this just move the script(src='/javascripts/app.js') beneath the other includes.

Edit: Alternatively there is a whole bunch of alternatives to prevent such issues like RequireJS, Webpack, Grunt, etc.

Sign up to request clarification or add additional context in comments.

5 Comments

Is this loading order issue specific to the OP's framework implementation? Because I have always had my .js script references ordered by app.js, services.js, controllers.js, etc. and it's not an issue. I think, perhaps, there are other things happening here, like the failure to inject courseServices into courses and the failure to register CoursesListController as a controller module (this is probably the one actually causing the specific error referenced by the OP).
If I'm not mistaken it is not necessary to register the controller on the module, you can also define the controller as named or anonymous function.
Hmm, here's a JSFiddle illustrating the issue. Are you saying that the .controller('MyController', MyController) is not required (in the JSFiddle)? Because if you leave that commented the JSFiddle example does not work, but if you uncomment that it works. What am I missing?
In your fiddle you try referencing it by name. If you do that you need it registered on the controller. In OP's example he references the function itself on the router config
@Aides I gave up and removed my answer, I saw your edit and it's definitely a +1 for you :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.