0

I am new to angularJS. I am trying to seperate service into a seperate file in my application. Everything works fine, but when i try to inject the factory object to the controller it is not working. Below is the code

here is the app file
app.js

'use strict';

var app = angular.module('myApp', ['ngRoute']);  
app.config(function ($routeProvider, $controllerProvider,

          $compileProvider, $filterProvider, $provide) {
app.controllerProvider = $controllerProvider;
app.compileProvider = $compileProvider;
app.routeProvider = $routeProvider;
app.filterProvider = $filterProvider;
app.provide = $provide;


app.routeResolver = function (basePath, viewName,controllerName, isSecure) {
    var routeConf =
        {
            templateUrl: 'Views/' + basePath + viewName + '.html',
            controller: controllerName + 'Controller',
            secure: isSecure ? isSecure : false,
            resolve: {
                deps: function ($q, $rootScope) {
                    var deferred = $q.defer();
                    var dependencies =
                    [
                        'Controllers/' + basePath + controllerName + 'Controller.js',
                    ];

                    require(dependencies, function () {
                        $rootScope.$apply(function () {
                            deferred.resolve();
                        });
                    });

                    return deferred.promise;
                }
            }
        }
    return routeConf;

}

$routeProvider
.when('/', {})
.when('/Admin', app.routeResolver('Admin/', 'Admin','Admin'))
.when('/Customer', app.routeResolver('Customer/', 'Customer','Customer'))
.when('/Teller', app.routeResolver('Teller/', 'Teller','Teller'))
.when('/Finance', app.routeResolver('Finance/', 'Finance','Finance'))   
.otherwise({ redirectTo: '/' });
});

Here is my factory
AuthenticationService.js

'use strict';

app.factory('authenticationService', ['$scope', 'httpService', function ($scope,      httpService) {

return {
    authenticateUser: function () {
        if (!$scope.userName && !$scope.keyWord) {
            var result = httpService.postService(
                 {
                     username: $scope.userName,
                     keyword: $scope.keyWord
                 }, "../api/authenticateUser");
            result.then(successCall, errorCall);
        }
    }
}

successCall =function(dataObject) {

}

errorCall = function (dataObject) {

}

}]);

Here is my controller
LoginController.js

'use strict';

app.controller('LoginController', ['$scope','authenticationService',  function ($scope, authenticationService) {

$scope.ValidateLogin = function () {
    var result = window.confirm("Validate Login Called for the user :" + $scope.userName);
    var result1 = authenticationService.authenticateUser();

}
}]);

the logincontroller is working fine when i am not injecting the authenticationservice. But when i try to inject authenticationservice, it is not working. what am i doing worng. Your help will be greatly appreciated. Thanks in advance.
Note : I have tried creating this as a service as well. Still this is not working.

4
  • Whats the error in the console, also what version of angular Commented Jan 2, 2015 at 23:24
  • I call this method ValidateLogin on click of Login button from index.html. this is called when i dont inject authentication service. that is how i am finding it out. @license AngularJS v1.3.8 Commented Jan 2, 2015 at 23:26
  • Why isn't app defined in each of the javascript files? Commented Jan 2, 2015 at 23:30
  • that is a global variable as defined in app.js. This has a value when i debug in all the files. Commented Jan 2, 2015 at 23:33

3 Answers 3

2

Although it's not recommended to access $scope inside your factories and services,you can using angular.element(ELEMENT).scope().

But it's better to make your authentication service accept a username and password and assume nothing about its current scope to make it re-usable:

authenticateUser: function (username, password) {
    ...... // 
    return result.then(successCall, errorCall); // return the promise 
}

Then in your controller:

$scope.ValidateLogin = function () {
 ....//
     authenticationService.authenticateUser($scope.username, $scope.password)
         .then(function(response){
          // deal with the response here
          });

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

8 Comments

Also as pointed by @topheman you have a hoisting problem, combine both answers and you have a functional factory.
thanks for the optimization tips. I have made the changes as suggested. but to begin with,the problem i have is, the validateLogin is not getting called when i inject authenticationService.
Can you make sure that your AuthenticationService is injected in the right order in your Index.html, before the controllers js and after the app.js
Hi teleaziz... thanks for the input. Now i could see the httpservice that i used in the authenticationservice is getting initialized, but not the authenticationservice. i have the files injected in the right order as you have mentioned.
is the httpService something you defined? or is it something I missed in Angular? I usually use $http instead: $http.post(authRoute, data)
|
0

The basic problem here is your factory is not getting initialized properly. The factory definition is incorrect because you are using $scope. $scope is not a service and but an object. $scopeobject is bound to some html elements/context. We can use $scope with controllers as Injector initializes controllers with $scope while parsing the html elements. Controllers are associated with html elements and hence Injector knows the $scope for the controller. But services/factories are singleton objects. So you cannot inject $scope here.

For additional clarifications, you may refer Injecting $scope into an angular service function()

using following code would resolve your issue. I assume you have already defined httpsService.

app.factory('authenticationService', ['httpService', function (httpService) {

return {
    authenticateUser: function (context) {
        if (!context.userName && !context.keyWord) {
            var result = httpService.postService(
                 {
                     username: context.userName,
                     keyword: context.keyWord
                 }, "../api/authenticateUser");
            result.then(successCall, errorCall);
        }
    }
}

app.controller('LoginController', ['$scope','authenticationService',  function ($scope, authenticationService) {

$scope.ValidateLogin = function () {
    var result = window.confirm("Validate Login Called for the user :" + $scope.userName);
    var result1 = authenticationService.authenticateUser($scope);

}
}]);

Comments

-1

You have a hoisting problem in your service :

'use strict';

app.factory('authenticationService', ['$scope', 'httpService', function ($scope,      httpService) {

//define them here before the return, if not, they won't be defined
var successCall =function(dataObject) {

}

var errorCall = function (dataObject) {

}

return {
    authenticateUser: function () {
        if (!$scope.userName && !$scope.keyWord) {
            var result = httpService.postService(
                 {
                     username: $scope.userName,
                     keyword: $scope.keyWord
                 }, "../api/authenticateUser");
            result.then(successCall, errorCall);
        }
    }
}

}]);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.