3

I am trying a simple example of an AddressBook Angular application. I have a factory that returns an array of records and it it gets displayed in a list view using a List controller

angular.module('abModule', ['ngRoute'])
.factory('AddressBook', function() {
    var address_book = [
        {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "age": 29
        },
        {
            "id": 2,
            "first_name": "Anna",
            "last_name": " Smith",
            "age": 24
        },
        {
            "id": 3,
            "first_name": "Peter",
            "last_name": " Jones",
            "age": 39
        }
    ];
    alert('inside factory function');
    return {
        get: function() {
            return address_book
        }
    };
})
.config(function($routeProvider) {
    $routeProvider
    .when('/', {
        controller:'list_controller',
        templateUrl:'list.html'
    })
    .when('/add', {
        controller:'add_controller',
        templateUrl:'add.html'
    })
    .otherwise({
        redirectTo:'/'
    });          
})
.controller('list_controller',['$scope', function ($scope, AddressBook) {
    $scope.address_book = AddressBook;
}])
.controller('add_controller',['$scope', function ($scope,AddressBook) {
    //$scope.entry = {};
    $scope.save = function() {
        AddressBook.set(
            {
                "id": $scope.address_book.length +1,
                "first_name":$scope.entry.firt_name,
                "last_name":$scope.entry.last_name,
                "age":$scope.entry.age
            }
        );
    };
}]);

Here 'AddressBook' is always undefined inside 'list_controller'. Any idea where I am going wrong? Any help is greatly appreciated.

L1ghtk3ira
  • 2,330
  • 3
  • 26
  • 58

3 Answers3

7

You are not annotating AddressBook for your DI

.controller('list_controller',['$scope', function ($scope, AddressBook) {
    $scope.address_book = AddressBook;
}])

should be:

.controller('list_controller',['$scope', 'AddressBook', function ($scope, AddressBook) {
    $scope.address_book = AddressBook;
}])

Same for the other controller.

TheSharpieOne
  • 25,276
  • 9
  • 63
  • 74
2

Another approach is using $inject declaration of your dependencies , which are being used in the same order as arguments to your functionas show below . It helps in injecting the right services after the minification of the code.

var App = angular.module('myApp',[]);
App.controller('myCtrl',myCtrl);

//inject your dependencies;
myCtrl.$inject = ["$scope", "AddressBook","anotherService"] // 

function myCtrl($scope,AddressBook,anotherService){
.....
}

Note: Services names will be renamed after the minification and can indulge in breaking your application

Shushanth Pallegar
  • 2,654
  • 1
  • 12
  • 15
  • This helped me find my issue. My $inject looked like `PostsController.$inject = [ 'postsService', logger ];` where 'logger' was not defined. Turns out excluding the quotation marks will also throw the ReferenceError. – Matt Wagner Jun 19 '15 at 16:17
2

Another possible cause of always getting undefined in a factory variable is incorrect mapping of declared dependencies to the list of function parameters. E.g.:

var loginCtrl = loginModule.controller("loginController", 
    ['$scope', '$window', 'notificationMessage',
    function ($scope, $window, serverDataConvertor, notificationMessage) {

    // notificationMessage is undefined because serverDataConvertor factory is not a declared dependency

    // controller logic comes here
}

Unfortunately, Angular does not issue any warning or error and it can be very frustrating, especially when dependency list is large.

Alexei - check Codidact
  • 17,850
  • 12
  • 118
  • 126
  • Thanks for this. Just wasted 20 minutes in frustration and this saved me. – Henry Lin Dec 01 '17 at 23:38
  • @HenryLin - yes, it happened the same to me and I thought to provide this answer. Fortunately, dependencies declaration have been improved in subsequent versions (Angular 2, Angular 4). – Alexei - check Codidact Dec 02 '17 at 06:34
  • I just started working at a small company about a month ago. They're using AngularJS. They don't have any plans to upgrade however. I realise this could be problematic ehen AngularJS loses support in a few years. Maybe I can convince them it is better now than later! – Henry Lin Dec 02 '17 at 06:39