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.

1
  • your AddressBook dont have set function Commented Aug 15, 2014 at 14:02

3 Answers 3

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.

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

Comments

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

1 Comment

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.
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.

3 Comments

Thanks for this. Just wasted 20 minutes in frustration and this saved me.
@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).
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!

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.