1


I'm working through this tutorial on creating a single-page MEAN stack todo app. I'm on this step, specifically. The tutorial covers modularization of code, and while I was able to separate my backend code (Express, Mongo, etc.) into modules successfully, when I separate my angular.js code, the todo app ceases to function. The specific error which is thrown to the console is "Uncaught Error: [$injector:modulerr]." The specific error is "nomod" (i.e. the module "simpleTodo" is failing to load.) I'd appreciate any help.

Code as one file (core.js):

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

simpleTodo.controller('mainController', ['$scope', '$http', function($scope, $http) {
$scope.formData = {};

$http.get('/api/todos')
  .success(function(data) {
        $scope.todos = data;
    })
    .error(function(data) {
        console.log('Error: ' + data);
    });

$scope.createTodo = function() {
    $http.post('/api/todos', $scope.formData)
      .success(function(data) {
            $scope.formData = {};
            $scope.todos = data;
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });
};

$scope.deleteTodo = function(id) {
    $http.delete('/api/todos/' + id)
      .success(function(data) {
            $scope.todos = data;
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });
    };
}]);

Code in modules:
New core.js:

var simpleTodo = angular.module('simpleTodo',['todoController', 'todoService']);

Create/Delete Todo Service (todos.js):

angular.module('todoService', [])
  .factory('Todos', ['$http', function($http) {
      return {
            get: function() {
                return $http.get('/api/todos');
            },
            create: function(todoData) {
                return $http.post('/api/todos', todoData);
            },
            delete: function(id) {
                return $http.delete('/api/todos/' + id);
            }
        }
}]);

Controller file (main.js)

angular.module('todoController', [])
  .controller('mainController', ['$scope', '$http', 'Todos', function($scope, $http, Todos) {
    $scope.formData = {};

    Todos.get()
      .success(function(data) {
            $scope.todos = data;
        });

    $scope.createTodo = function() {
        if ($scope.formData !== null) {
            Todos.create($scope.formData)
              .success(function(data) {
                    $scope.formData = {};
                    $scope.todos = data;
                });
        }
    };

    $scope.deleteTodo = function(id) {
        Todos.delete(id)
          .success(function(data) {
                $scope.todos = data;
            });
    };
}]);

Order of script loading on index.html:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.min.js"></script>
<script src="js/controllers/main.js"></script>
<script src="js/services/todos.js"</script>
<script src="js/core.js"></script>

Thanks!

New info: After following floribon's advice, I get the same error, except instead of "simpleTodo" failing to load, it is "todoController" that cannot be loaded. I appreciate his advice but it still isn't working. :( Here's a github repo with his changes implemented, if you want to see: https://github.com/LeungEnterprises/simpleTodo

Nathan L.
  • 243
  • 2
  • 10
  • 2
    can you show the relevant HTML where these script files are loaded, and which order they are loaded in? – Claies Feb 25 '15 at 01:58
  • jQuery, Angular, Controllers, Service, Load App – Nathan L. Feb 25 '15 at 02:03
  • as was mentioned, you are missing the most important part of the error; the module which is failing to load. – Claies Feb 25 '15 at 02:07
  • does your code work if you use the same version of angular which is used in the tutorial the code came from? – Claies Feb 25 '15 at 22:54
  • No, I'm using 1.3.13 while scotch.io is using ~1.2.x. However, after consulting the angular migration guide, I didn't see any breaking changes. – Nathan L. Feb 26 '15 at 01:48
  • did you *try* using the version in the guide? It will help eliminate possibilities. – Claies Feb 26 '15 at 03:31
  • Yes, but I got the same result. – Nathan L. Feb 26 '15 at 14:30
  • I'm really having a hard time seeing how your environment is different. I downloaded the github project and built it and it functions correctly, and all the code you posted seems normal. The only thing I can see that you are doing differently is that you are trying to pass the dependencies as an array to the controller, where in the sample code, they don't include a dependency array. – Claies Feb 26 '15 at 22:11
  • That was floribon's recommendation, but even when I followed the same steps as the sample app the same thing happened (nomod error) – Nathan L. Feb 26 '15 at 22:13
  • @Claies Do you think it would be easier for you to assist me if I posted the entire app (i.e. server.js, express routing, mongodb) onto github? – Nathan L. Feb 26 '15 at 22:56

2 Answers2

3

Since your controller needs to resolve the Todos dependency, you need to add the service todoService it to its module dependencies:

angular.module('todoController', ['todoService'])

Also, you will need to load the todos.js file before the main.js one (sicne it requires the former)

floribon
  • 19,175
  • 5
  • 54
  • 66
  • there are 2 different versions of the code listed in the question; it's not that it was declared twice... the first listing was one functional code sample, the other listings are an alternative which does not work. – Claies Feb 25 '15 at 02:01
  • I set my module like var simpleTodo = angular.module('simpleTodo', []); when everything is in one file; when I separate it into modules, it is set like this: var simpleTodo = angular.module('simpleTodo', ['todoController', 'todoService']); – Nathan L. Feb 25 '15 at 02:03
  • Oh I am sorry I didn't get it that way, of course, sorry. So indeed it seems good, please give us the full error so we know which module is wrong. I'll edit my answer or delete it otherwise. – floribon Feb 25 '15 at 02:05
  • Ok I changed my answer, I think I got your issue. – floribon Feb 25 '15 at 02:07
  • Now I'm getting a "failed to instantiate todoController due to nomod" error. If it helps, here's the code that they are using over at Scotch.io, where the tutorial is hosted. https://github.com/scotch-io/node-todo/tree/tut3-controllers-services/public – Nathan L. Feb 25 '15 at 02:13
  • Did you load the service file before the controller one? Could give give us the complete error message? (click on its link if you are using the minimized version of angular) – floribon Feb 25 '15 at 02:16
  • I followed the directions outlined in your answer and this came up: Failed to instantiate module todoController due to: Error: [$injector:nomod] http://errors.angularjs.org/1.3.13/$injector/nomod?p0=tod... at Error (native)... – Nathan L. Feb 25 '15 at 02:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71633/discussion-between-floribon-and-nathan-l). – floribon Feb 25 '15 at 02:34
0

I perused my files and after extensive experimentation I deduced that the problem was being caused in the HTML file. The problem was an unclosed script tag.

However, I do appreciate everyone's help, especially @floribon!

Nathan L.
  • 243
  • 2
  • 10