AngularJS service in a separate file

My app.js contains

var app = angular.module('myApp', []). config(['$routeProvider', function ($routeProvider, $http) { ... }]); 

The service looks like

 app.service('MyService', function () { addNums = function (text) { return text + "123"; } }); 

And in the contoller I have

 function adminCtrl ($scope, MyService) { $scope.txt = MyService.addNums("abc"); }; 

All of them are in separate files. The problem is that I get an Unknown provider: MyServiceProvider <- MyService error message Unknown provider: MyServiceProvider <- MyService

Looks like I'm doing something wrong.

+7
source share
3 answers

A vendor error may occur if you forget to tell Angular to load the myApp module. For example, do you have this in your index.html file ?:

 <html ng-app="myApp"> 

Your service is missing "this.":

 this.addNums = function(text) { 

Fiddle


There seems to be a lot of confusion in the Angular community about when to use service () vs factory () and how to code them correctly. So here is my brief tutorial:

The service () method expects a JavaScript constructor function. Many Angular code examples that use service () contain code that is not a constructor function. Often they return an object that hits the purpose of using the service () - more on this below. If you need to create and return an object, you can use factory () instead. Often, a constructor function is all that is needed, and service () can be used.

The following are quotes from various posts from the AngularJS Google group:

The main difference between using factory () from service () is that factory () should return an object, and service () does not return anything except it should be an object constructor function.

Use factory () if the function you provide creates the object you want. Ie, Angular will essentially do obj = myFactory () to get the object. Use the service () if the function you provide is a constructor for the object you want. Ie, Angular will essentially do obj = new myService ()
to get / instantiate obj.

Therefore, when people use service (), and its code โ€œreturnsโ€ the object, this is a kind of waste due to the fact that JavaScript โ€œnewโ€ works: โ€œnewโ€ will first create a completely new JavaScript object (then make a prototype material, then call the function defined by myService (), etc. - the details that we donโ€™t really like here), but since the function defined by myService () returns its own object, the "new" one makes an odd sentence: it throws an object, just took the time to create and returns the object created by the myS function ervice () is therefore "waste".

One of the reasons service () was introduced was to make it easier to use the "classic" TOE methods, such as defining your service as the coffeescript class.

Also, the undocumented naming convention for services seems to be camelCase with the first lowercase letter: for example, myService.

+11
source

You need to return addNums in the app.service callback.

 app.service('MyService', function () { addNums = function (text) { return text + "123"; } return addNums; }); 

Now that you are using MyService, angular will return the addNums function to you.

Therefore, you should use it in your controller like this (note that there is no addNums call):

 function adminCtrl ($scope, MyService) { $scope.txt = MyService("abc"); }; 
+2
source

Just like the added clarification in Brian's answer, if you want your code to call MyService.addNums, you could use the following:

 app.service('MyService', function() { var result = {}; result.addNums = function (text) { return text + "123"; }; return result; }); 

Then you can still use

 MyService.addNums("abc"); 

if you want it.

+2
source

All Articles