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 Basics (1.x) Improving Our Todo App Create a Custom Directive For “todos”

Uncaught Error: [$injector:nomod] Module 'TodoListApp' is not available! You either misspelled the module name or forgot

Here's the error that I'm getting: - Please note that in the error todoListApp begins with capital T as "TodoListApp" and in my code I see it as "todoListApp" everywhere.

Imgur

Here's my code:

app.js

angular.module("todoListApp", [])

todos.js

angular.module('todoListApp')
.directive('todos', function() {
  return {
    templateUrl: 'templates/todos.html'

  }
})

todos.html

<div ng-controller="mainCtrl" class="list">
  <div class="add">
   <a href="" ng-click="addTodo()">+ Add New Task</a>
  </div>
  <div class="item" ng-class="{'editing-item' : editing,
'edited' : todo.edited}" ng-repeat="todo in todos">
    <input type="checkbox" ng-model="todo.complete"/>
    <label ng-click="editing=true;" ng-hide="editing"  ng-click='helloWorld()'>{{todo.name}}</label>
    <input ng-change="todo.edited = true" ng-blur="editing = false;" ng-show="editing"  ng-model="todo.name" class="editing-label"   type="text"/>
    <div class="actions">
      <a href="" ng-click=" editing = !editing">edit</a>
      <a href="" ng-click='saveTodo(todo)()'>save</a>
      <a href="" ng-click="deleteTodo(todo, $index)" class='delete'>delete</a>
    </div>
  </div>
 </div>

index.html

<!doctype html>
<html lang="en">
<head>
  <title></title>
  <link href='https://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
  <link href='styles/main.css' rel='stylesheet' type="text/css">
</head>
<body ng-app="todoListApp">
  <h1 ng-click="helloWord()">My TODO's</h1>
  <todos></todos>
  <script src="vendor/angular.js" type="text/javascript"></script>
  <script src="scripts/app.js" type="text/javascript"></script>
  <script src="scripts/controllers/main.js" type="text/javascript"></script>
  <script src="scripts/services/data" type="text/javascript"></script>
  <script src="scripts/directives/todos.js" type="text/javascript"></script>
</body>
</html>

main.js

'use strict';

angular.module("todoListApp") 
.controller('mainCtrl', function($scope, dataService) {
  $scope.addTodo = function() {
    var todo = {name: "This is a new todo."};
    $scope.todos.push(todo);
  };


  $scope.helloWorld = dataService.helloWorld;

  dataService.getTodos(function(response) {
  console.log(response.data);
  $scope.todos = response.data; 
  });

  $scope.deleteTodo = function(todo, $index) {
    dataService.deleteTodo(todo);
    $scope.todos.splice($index, 1)

  };
  $scope.saveTodo = function(todo) {
    dataService.saveTodo(todo);
  };
})

data.js

angular.module("todoListApp")
.service('dataService', function($http) {
  this.helloWorld = function() {
    console.log("This is the data sercies's method!!");
  };

  this.getTodos = function(callback){
    $http.get('mock/todos.json')
    .then(callback)
  };

  this.deleteTodo = function(todo) {
    console.log("The " + todo.name + " todo has been deleted!")
    // other logic

  };


  this.saveTodo = function(todo) {
    console.log("The " + todo.name + " todo has been saved!");
    // other logic
  };

});

Imgur

2 Answers

akak
akak
29,445 Points

Binding to a variable should not be necessary. My current angular project works fine without that. Try to fix:

  <script src="scripts/services/data" type="text/javascript"></script> <!-- should be data.js -->

and see if it's going to help. Maybe the flow of scripts gets interrupted by this and something weird happens.At a first glance the app looks fine and should work.

Resolved. Thanks for the pointers.

Sergey Podgornyy
Sergey Podgornyy
20,660 Points

Try to save your module on variable like

var tdApp = angular.module("todoListApp", []);

Then, bind your directives and controller to this variable

tdApp.directive('todos', function() {
  return {
    templateUrl: 'templates/todos.html'

  }
});
tdApp.controller('mainCtrl', function($scope, dataService) { ... });

Thanks for the consultation. Thanks to akak the bug has been identified and disabled. Further notes have been acquired on debugging methods thanks to Sergey Podgornyy.