selma
selma

Reputation: 77

Separate service from controller in Angularjs

I would like to separate the service from the controller in my angularjs application, I did it in a following way:

the app.js there is:

var myApp = angular.module('myApp',['restangular','ui.router','myApp.controllers','myApp.services']);

the controllers.js:

 angular.module('myApp.controllers',[]);

the services.js:

angular.module('myApp.services',[]);

I have a controllers related to the controllers.js:

angular.module('myApp.controllers',[]).controller('ContactController', ContactController);

ContactController.$inject = [ '$scope', 'ContactService' ];
function ContactController($scope, ContactService) {
     console.log("here call ctrl contact");
     $scope.contacts = ContactService.getAll(); 
}

This ContactController call the service ContactService defined in a separate file: ContactService .js

angular.module('myApp.services',[])

.factory('ContactService', function(Restangular){
    var Contacts = Restangular.all('contacts');

    return {
        getAll : function(){
            return Contacts.getList().$object;
        }
    };

});

the problem is when I have tried to invoke this controller I got the following error:

Error: [$injector:unpr] Unknown provider: ContactServiceProvider <- ContactService http://errors.angularjs.org/1.2.19/$injector/unpr?p0=ContactServiceProvider%20%3C-%20ContactService

how can I fix that?

UPDATE: this is the structure of my app:

structure of the app

I have in app.js:

.state('contacts', {
        url: '/contacts',
        templateUrl: 'templates/contacts.html',
        controller: 'ContactController'
    })  
    .state('todos', {
        url: '/todos',
        templateUrl: 'templates/todos.html',
        controller: 'TodoController'
    })

in the index.html i imported all th js files:

enter image description here

Upvotes: 1

Views: 920

Answers (3)

Sravan
Sravan

Reputation: 18647

Once you have initialized a module withm, angular.module('myApp.controllers', []) again you should not use second parameter dependency([])

So, in your controller,

 `angular.module('myApp.controllers',[])` should be `angular.module('myApp.controllers')`

So,

angular
  .module('myApp.controllers')
  .controller('ContactController', ContactController);
ContactController.$inject = ['$scope', 'ContactService'];
function ContactController($scope, ContactService) {
  console.log('here call ctrl contact');
  $scope.contacts = ContactService.getAll();
}

The same applies to your service/factory,

angular.module('myApp.services')
.factory('ContactService', function(Restangular){
    var Contacts = Restangular.all('contacts');

    return {
        getAll : function(){
            return Contacts.getList().$object;
        }
    };

});

PS: After seeing the order of your js file injection in index.html I found the major issue.

The order of your file scripts is wrong. In ContactController you are using contactService which is not defined before it. So change the scripts order in index.html as below.

<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/services/ContactService.js"></script>
<script src="js/services/TodoService.js"></script>
<script src="js/controllers/HomeController.js"></script>
<script src="js/controllers/ContactController.js"></script>
<script src="js/controllers/TodoController.js"></script>

Upvotes: 7

selma
selma

Reputation: 77

Seems the issue fixed by reorder the import of my js files as follows:

the app.js then the file services and then the controllers.

import js files

Upvotes: 0

Panos K
Panos K

Reputation: 1081

try to include

angular.module('myApp.controllers',['myApp.services'])

instead of

 angular.module('myApp.controllers',[])

cheers

Upvotes: 0

Related Questions