Tony
Tony

Reputation: 12695

AngularJS - factory is an empty object

I'm new in AngularJS - I can't figure out why I get the error mainDataService.refreshStatus is not a function in the $scope.clickMe function. I see the mainDataService variable is an empty object besides its initialization. What am I doing wrong here ?

    var mainDataService = {};

    var firstModule = angular.module('myModule', ['ngRoute', 'ngAnimate']);

    (function () {
        var mainDataServiceInjectParams = ['$http', '$q'];

        var mainFactory = function ($http, $q) {
            mainDataService.refreshStatus = function (id) {
                return $http.get('/api/values/' + id).then(function (results) {
                    return results.data;
                });
            };

            return mainDataService;
        };


        mainFactory.$inject = mainDataServiceInjectParams;
        firstModule = firstModule.factory('mainService', mainFactory);
    }());

    firstModule.controller('myCtrl', function ($scope, $http) {
        $scope.TST = '1';

        $scope.clickMe = function (id) {
            mainDataService.refreshStatus(id).then(function (results) {
                $scope.TST = results;
            });
        }
    });

Upvotes: 1

Views: 655

Answers (3)

Artūras
Artūras

Reputation: 473

Supply mainService to controller

firstModule.controller('myCtrl', function ($scope, $http, mainService) {

and then use it in the function

mainService.refreshStatus

Upvotes: 1

Alp
Alp

Reputation: 29739

You need to use the dependency injection mechanism to load your own services.

Put the mainDataService declaration in a local scope and inject the mainService into myCtrl:

var firstModule = angular.module('myModule', ['ngRoute', 'ngAnimate']);

(function () {
    var mainDataServiceInjectParams = ['$http', '$q'];

    var mainFactory = function ($http, $q) {
        var mainDataService = {};
        mainDataService.refreshStatus = function (id) {
            return $http.get('/api/values/' + id).then(function (results) {
                return results.data;
            });
        };

        return mainDataService;
    };


    mainFactory.$inject = mainDataServiceInjectParams;
    firstModule = firstModule.factory('mainService', mainFactory);
}());

firstModule.controller('myCtrl', function ($scope, $http, mainService) {
    $scope.TST = '1';

    $scope.clickMe = function (id) {
        mainService.refreshStatus(id).then(function (results) {
            $scope.TST = results;
        });
    }
});

Even better, you should explicitly assign the dependencies into the controller, so that your code still works after minifcation (as you already did it for the service):

firstModule.controller('myCtrl', myCtrl);

myCtrl.$inject = ['$scope', '$http', 'mainService'];
function myCtrl($scope, $http, mainService) {
    $scope.TST = '1';

    $scope.clickMe = function (id) {
        mainService.refreshStatus(id).then(function (results) {
            $scope.TST = results;
        });
    }
});

As you see, if you use normal function definitions, you can make use the function hoisting of Javascript and write the functions at the end while having the relevant code at the top. It's the other way round as in your example of the service.

Upvotes: 2

laurent
laurent

Reputation: 2620

I think you immediately invoked function is not invoked so mainDataService still reference the object you set at the first line

(function(){})() 

rather than

(function(){}())

Upvotes: 0

Related Questions