Services in AngularJS For Beginners

Services are one of the important concepts in AngularJS. In general, Services are functions that are responsible for specific tasks in an application. AngularJS services are designed based on two principles.

  1. Lazily instantiated: Angular only instantiates a service when an application component depends on it using dependency injection to make Angular the codes robust and less error-prone.
  2. Singletons: Each component is dependent on a service that gets a reference to the single instance generated by the service factory.

AngularJS supports the concepts of "Separation of Concerns" using a services-oriented architecture and it is at the heart when designing an AngularJS application. Controllers, filters, or directives can call them on the basis of requirements. The controller must be responsible for binding model data to views using $scope. It does not contain logic to fetch the data or manipulate it.

Services provide a method to share data across the lifetime of the AngularJS application. It provides a method to communicate data across the controllers in a consistent way. This is a singleton object and it is instantiated only once per application. It is used to organize and share data and functions across the application.

Thus a service is a stateless object that contains some useful functions. These functions can be called from anywhere; Controllers, Directive, Filters, and so on. Thus we can divide our application into logical units. The business logic or logic to call HTTP URL to fetch data from the server can be put within a service object.

Putting business and other logic within services has many advantages. First, it fulfills the principle of separation of concerns or segregation of duties. Each component is responsible for its own work making application code more manageable and more testable. Thus we can quickly write tests for our services making them robust and less error-prone.

AngularJS provides many built-in services, for example, $http, $route, $window, $location, and so on. Each service is responsible for a specific task, for example, $http is used to make an Ajax call to get the server data. $route defines the routing information and so on. Built-in services are always prefixed with the $ symbol.

AngularJS internal services

AngularJS internally provides many services that we can use in our application. $http is one example. There are other useful services, such as $route, $window, $location, and so on. Some of the commonly used services in any AngularJS application are listed below.

  • $window: Provide a reference to a DOM object.
  • $Location: Provides a reference to the browser location.
  • $timeout: Provides a reference to the window.set timeout function.
  • $Log: Used for logging.
  • $sanitize: Used to avoid script injections and display raw HTML on page.
  • $Rootscope: Used for scope hierarchy manipulation.
  • $Route: Used to display browser-based path in browser URL.
  • $Filter: Used for providing filter access.
  • $resource: Used to work with Restful API.
  • $document: Used to access the window. Document object.
  • $exceptionHandler: Used for handling exceptions.
  • $q: Provides a promise object.

Here, the question arises in our mind that we had window, window. Location, document, and timeout in the DOM in JavaScript, so why does $window, $location, $document, $timeout in terms of services? The reason behind this is to support dependency injection and to more easily test using a mocked version of $window, $location, $document, and $timeout services.

what is the mocked version and what is mocking?

Mocking is primarily used in unit testing. An object under test may have dependencies on other (complex) objects. To isolate the behavior of the object you want to test you replace the other objects with mocks that simulate the behavior of the real objects. This is useful if the real objects are impractical to incorporate into the unit test.

Let's understand some of the AngularJS internal services.

$window Service

Example-1

<!DOCTYPE html>
<html ng-app="WindowsServiceapp">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script>
        angular.module("WindowsServiceapp", [])
        .controller("WindowsServicectrl", function ($scope, $window)
        {
            $scope.dissplayAlert = function (msg)
            {
                $window.open("http://www.google.com", "test", 'height=200,width=550');
                $window.document.write("Testing....");
                $window.alert(msg);
            }
        });
    </script>
</head>
<body>
    <div ng-app="WindowsServiceapp">
        <div ng-controller="WindowsServicectrl">
            <div>
                <button name="btn" ng-click="dissplayAlert('clicked')">click me </button>
            </div>
        </div>
    </div>
</body>
</html>

Output

Output

Here the “WindowsServicectrl” $window service is injected and shows an alert and opening pop-up window in the preceding example. Note that $windows is not the same window object. To keep the window object an injectable component for manipulation of AngularJS that has created a wrapper on the window object.

$http Services

Let us understand the $http service that makes a service call for server communication. Now we will see a simple HTTP service that is used to fetch the data from an SQL Server database.

We have an employee table that contains some employee information as in the following.

Employee information

We have a web API that is a source of a data layer that connects to a database and we need to call it using Angular code.

Example 2

public class EmployeeAPIController : ApiController
{
    private EmployeeEntities db = new EmployeeEntities();
    public IEnumerable<Employee> GetEmployees()
    {
        return db.Employees.AsEnumerable();
    }
}

Service

app.service('EmployeeService', function ($http)
{
    this.getAllEmployee = function ()
    {
        return $http.get("/api/EmployeeAPI"); // Calling the web api here 
    }
});

Controller

app.controller('EmployeeController', function($scope, EmployeeService)
{
    GetAllRecords();

    function GetAllRecords()
    {
        var promiseGet = EmployeeService.getAllEmployee();
        promiseGet.then(function(pl)
        {
            $scope.Employees = pl.data;
        },
        function(errorPl)
        {
            $log.error('Some Error in Getting Records.', errorPl);
        });
    }
});

Module

var app;
(function()
{
    app = angular.module("EmployeeModule", []);
})();

HTML Page


<html ng-app="EmployeeModule">
<head>
    <style type="text/css">
        table.table-style {
            font-family: verdana, arial, sans-serif;
            font-size: 11px;
            color: #333333;
            border-width: 1px;
            border-color: #3A3A3A;
            border-collapse: collapse;
            border: 2px solid gray;
            background-color: #f5f5f5;
        }
        
        table.table-style th {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #FFA6A6;
            background-color: #D56A6A;
            color: #ffffff;
        }
        
        table.table-style tr:hover td {
            cursor: pointer;
        }
        
        table.table-style tr:nth-child(even) td {
            background-color: #F7CFCF;
        }
        
        table.table-style td {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #FFA6A6;
            background-color: #ffffff;
        }
    </style>
</head>
<body data-ng-controller="EmployeeController">
    <table class="table-style">
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Role</th>
            <th>Birth Day</th>
            <th>Gender</th>
            <th>HireDate</th>
        </tr>
        <tbody data-ng-repeat="emp in Employees">
            <tr>
                <td>
                    <span>{{emp.EmployeeID}}</span>
                </td>
                <td>
                    <span>{{emp.Name}}</span>
                </td>
                <td>
                    <span>{{emp.Title}}</span>
                </td>
                <td>
                    <span>{{emp.BirthDate}}</span>
                </td>
                <td>
                    <span>{{emp.Gender}}</span>
                </td>
                <td>
                    <span>{{emp.HireDate}}</span>
                </td>
            </tr>
        </tbody>
    </table>
</body>
</html>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/EmployeeScripts/Module.js"></script>
<script src="~/Scripts/EmployeeScripts/Service.js"></script>
<script src="~/Scripts/EmployeeScripts/Controller.js"></script>

Output

Details

User Defined Services

Let us create some of the services that we need to write based on our requirements. We will create a calculation web page that does Addition, Subtraction, Multiplication, and Division. We will create a service called "CalculatorService" and call this calculator service in the controller. From the controller, the service results are assigned to the Scope object and finally shown to the UI.

Example 3


<!DOCTYPE html>
<html ng-app="app">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script>
        var CalculatorService = angular.module('CalculatorService', [])
        .service('Calculator', function ()
        {
            this.Add = function (a, b) { return Number(a) + Number(b); };
            this.Sub = function (a, b) { return Number(a) - Number(b); };
            this.Mul = function (a, b) { return Number(a) * Number(b); };
            this.Div = function (a, b) { return Number(a) / Number(b); };
        });

        var myApp = angular.module('app', ['CalculatorService']);
        myApp.controller('CalculatorController', function ($scope, Calculator)
        {
            $scope.doAdd = function ()
            {
                $scope.result = Calculator.Add($scope.a, $scope.b);
            };
            $scope.doSub = function ()
            {
                $scope.result = Calculator.Sub($scope.a, $scope.b);
            };
            $scope.doMul = function ()
            {
                $scope.result = Calculator.Mul($scope.a, $scope.b);
            };
            $scope.doDiv = function ()
            {
                $scope.result = Calculator.Div($scope.a, $scope.b);
            };
        });
    </script>
</head>
<body>
    <div ng-app="app">
        <div ng-controller="CalculatorController">
            <div>
                <table style="width: 600px; border: 2px solid gray; background-color: #f5f5f5;">
                    <tr>
                        <td>
                            <strong></strong>
                        </td>
                        <td>
                            <strong>Calculator Service</strong>
                        </td>
                        <td>
                            <strong></strong>
                        </td>
                        <td>
                            <strong></strong>
                        </td>
                        <td>
                            <strong></strong>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <strong>Enter First Number:</strong>
                        </td>
                        <td>
                            <input type="text" ng-model="a" />
                        </td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>
                            <strong>Enter Second Number:</strong>
                        </td>
                        <td>
                            <input type="text" ng-model="b" />
                        </td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <br />
                    <tr>
                        <td></td>
                        <td>
                            <button ng-click="doAdd()">Add</button>
                            <button ng-click="doSub()">Subtract</button>
                            <button ng-click="doMul()">Multify</button>
                            <button ng-click="doDiv()">Divide</button>
                        </td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>
                            <strong>The Result from Calculation Service is: </strong>
                            <b>{{result}}</b>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    </div>
</body>
</html>

Output

Calculator service

So we created a service and saw the result of the service.

In general, a service can be created in many ways, they are,

  • Service
  • Factory
  • Provider
  • Value
  • Constant

Factory: A factory is a simple function that allows you to add some logic before creating the object. It returns the created object.

Example of defining a factory


// Define a factory using factory()
app.factory('MyFactory', function()
{
    var serviceObj = {};
    serviceObj.fun1 = function()
    {
        // TO DO the logic part goes here
    };
    serviceObj.fun2 = function()
    {
        // TO DO the logic part goes here
    };
    return serviceObj;
});
  • When to use Factory: It is just a collection of functions like a class. Hence, it can be instantiated in different controllers when you are using it with a constructor function.
  • Service: A service is a constructor function that creates the object using the new keyword. You can add properties and functions to a service object using this keyword. Unlike a factory, it doesn't return anything.

Example of defining a service using service()


function app.service('MyService', function()
{
    this.func1 = function()
    {
        // TO DO the logic part goes here
    };
    this.fun2 = function()
    {
        // TO DO the logic part goes here
    };
});
  • When to use Service: It is a singleton object. Use it when you need to share a single object across the application. For example, authenticated user details, shareable data, and so on.
  • Provider: A provider is used to create a configurable service object. It returns a value using the $get() function.

Example of defining a provider


function app.provider('configurable', function()
{
    var privateName = '';
    this.setName = function(newName)
    {
        privateName = newName;
    };
    this.$get = function()
    {
        return
        {
            name: privateName
        };
    };
});
//configuring provider using config()
function app.config(function(configurableService)
{
    configurableService.setName('Angular Js Provider sample');
});
  • When to use provider: When you need to provide a module-wise configuration for your service object before making it available. You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.
  • Value: Values are simple objects that are used to share data globally within a module. A value can be a number, string, date-time, array, or object. You can also register a function as a value.

Example 4


<!DOCTYPE html>
<html ng-app="app">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script>
        var app = angular.module('app', []);
        app.value('Data', { message: "I am data from a service" });
        app.controller('FirstCtrl', function($scope, Data)
        {
            $scope.data = Data;
            console.log($scope.data);
        });
    </script>
</head>
<body>
    <div ng-controller="FirstCtrl">
        <input type="text" ng-model="data.message">
        <br>data.message={{data.message}}
    </div>
</body>
</html>

Output

Output code

Constant: A constant is like a value. The difference between a value and a constant service is that a constant service can be injected into a module configuration function, in other words, config() or run() but a valued service cannot be.

Example 5


<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <meta charset="utf-8">
    <title>Validated constants</title>
    <script>
        angular.module('MyApp.Constants', []);
        angular.module('MyApp', ['MyApp.Constants'])
        .run(function ($rootScope, username)
        {
            // start using constants module
            $rootScope.username = username;
        });
    </script>
</head>
<body ng-app="MyApp">
    <script>
        // inject actual values when needed, the module already exists
        angular.module('MyApp.Constants').constant('username', 'World');
    </script>
    <p>Hello, {{ username }}</p>
</body>
</html>

Output: Hello, World

We could not provide any default values for the constants. We could not validate the constants passed to the module until much later, or by making a dummy.run calls just to validate them.

Let us see a sample wherein we will write 3 ways to return the service by factory, provider, and services in three ways as stated earlier.

Example 6


<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script>
        var myApp = angular.module('myApp', []);

        //Creating as service
        myApp.service('helloWorldFromService', function ()
        {
            this.sayHello = function ()
            {
                return "Hello, World!:I am From Service";
            };
        });

        //Creating as factory as a return function
        myApp.factory('helloWorldFromFactory', function ()
        {
            return
            {
                sayHello: function ()
                {
                    return "Hello, World!:I am From Factory";
                }
            };
        });

        //Creating as provider as a getter
        myApp.provider('helloWorld', function ()
        {
            this.name = 'Default';
            this.$get = function ()
            {
                var name = this.name;
                return
                {
                    sayHello: function ()
                    {
                        return "Hello, " + name + "!:I am From provider";
                    }
                };
            };
            this.setName = function (name)
            {
                this.name = name;
            };
        });

        myApp.config(function (helloWorldProvider)
        {
            helloWorldProvider.setName('World');
        });

        myApp.controller('MyCtrl', function ($scope, helloWorld, helloWorldFromFactory, helloWorldFromService)
        {
            $scope.hellos = [
                helloWorld.sayHello(),
                helloWorldFromFactory.sayHello(),
                helloWorldFromService.sayHello()
            ];
        });
    </script>
</head>
<body ng-app="myApp">
    <div ng-controller="MyCtrl">
        {{hellos}}
    </div>
</body>
</html>

Output

Hello world

Both services and factory providers get the same output but the choice of when to use them is important.

We can call services inside a service too. Consider a scenario in a real application with a service called Authentication services and services that must be determined based on the Authentication services result. In that scenario, we need to call services inside services. Let's see a simple example to demonstrate this. We have a service named MathService and CalculatorService. The Calculator Service needs MathService as a dependent service.

Example 7


<!DOCTYPE html>
<html ng-app="app">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script type='text/javascript'>
        var app = angular.module('app', []);
        app.service('MathService', function () {
            this.multiply = function (a, b) { return a * b; };
        });
        app.service('CalculatorService', function (MathService) {
            this.square = function (a) { return MathService.multiply(a, a); };
            this.cube = function (a) { return MathService.multiply(a, MathService.multiply(a, a)); };
        });
        app.controller('CalculatorController', function ($scope, CalculatorService) {
            $scope.doSquare = function () { $scope.answer = CalculatorService.square($scope.number); };
            $scope.doCube = function () { $scope.answer = CalculatorService.cube($scope.number); };
        });
    </script>
</head>
<body>
    <div ng-app="app">
        <div ng-controller="CalculatorController">
            Enter a number
            <input type="number" ng-model="number" />
            <button ng-click="doSquare()">X <sup>2</sup></button>
            <button ng-click="doCube()">X <sup>3</sup></button>
            <div>The Answer is: {{answer}}</div>
        </div>
    </div>
</body>
</html>

Output

Code

This is all about the basics of services in AngularJS. In the next article, I will return with more on services. I hope you now have a basic knowledge of services.

Thanks for reading.


Similar Articles