Introduction to Services

Overview

A service is the act of addressing an issue or solving a problem. Examples of services are cooking food, fixing a computer, giving a lecture on endangered species, selling stocks, etc. To assist you in solving various types problems in your project, AngularJS supports the concept of providing a service.

There are two categories of services you will use: those you create and those that are already available (built-in services).

Overview of Custom Services

You can create a service, then use it in other parts (called components), such as controllers, that need that service. AngularJS supports three major categories of services: values, functions, and objects. Actually, AngularJS is so flexible that, instead of supporting just three types of services, it rather provides three techniques to create services. A service can be created as a value, as a function, or as an object.

A Service as a Value

A Service as a Simple Value

You can use a regular value to provide a service. Such a service is created using a method named value. To create the service, attach this method to the creation of a module. The formula to follow is:

module-name Or module-creation.value(value-name, value-definition);

The value() service takes two arguments. Like all AngularJS components, a value service must have a name. This is the role of the first argument. The name can be anything you want. The second argument is the value of the service. It can be any value of a primitive type (number, character, string, or Boolean). You can first declare a variable and pass it as this second argument. Here is an example:

var number = 39475;

. . ..value('operand', number);

If you had declared a variable and attached the creation of a module to it, you can create the value service and attach it. Here is an example:

var number = 39475;

appAlgebra.value('operand', number);

Instead of first declaring a variable, you can specify it directly as the second argument of the value() function. Here is an example:

var appAlgebra = angular.module("algebra", []);

appAlgebra.value('operand', 39475);

Before using the service, create a controller. You must "inject" the valued service to the controller. To do this, pass the name of the service as argument to the constructor of the controller. This would be done as follows:

var appAlgebra = angular.module("algebra", []);

    appAlgebra.value('operand', 39475);

    function calculate (operand) {

    }
    appAlgebra.controller("OperationController", calculate);

In the body of the function, you can access the service argument and use it. If you want to access the valued service in a webpage, you can create a local this variable and assign the argument to it. Here is an example:

var number = 39475;
appAlgebra.value('operand', number);

function calculate (operand) {
        this.result = operand;
}

Accessing a Valued Service

To access the service in the constructor of the controller, use the name of the variable to which it is assigned in the function of the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="algebra">
<p ng-controller="OperationController as oc">The number is {{oc.result}}</p>

<script type="text/javascript">
    var appAlgebra = angular.module("algebra", []);

    var number = 39475;
    appAlgebra.value('operand', number);

    function calculate (operand) {
        this.result = operand;
    }
    appAlgebra.controller("OperationController", calculate);
</script>
</body>
</html>

This would produce:

Value-Based Service

If you want, you can involve the valued service in an operation. To do this, involve the argument of the controller function in an expression of your choice. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="algebra">
    <p ng-controller="OperationController as oc">Half of {{oc.number}} is {{oc.result}}</p>

<script type="text/javascript">
    var appAlgebra = angular.module("algebra", []);

    appAlgebra.value('operand', 39475);

    function calculate (operand) {
        this.number = operand;
        this.result = operand / 2.00;
    }
    appAlgebra.controller("OperationController", calculate);
</script>
</body>
</html>

This would produce:

Accessing a Valued Service

Of course, you can define the constructor of the controller in the parentheses of the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="algebra">
    <p ng-controller="OperationController as oc">Half of {{oc.number}} is {{oc.result}}</p>

<script type="text/javascript">
    var appAlgebra = angular.module("algebra", []);

    appAlgebra.value('operand', 39475);

    appAlgebra.controller("OperationController", function calculate(operand) {
        this.number = operand;
        this.result = operand / 2.00;
    });
</script>
</body>
</html>

Remember that when creating a function as the second argument to a component, you can omit the name of the function. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="algebra">
    <p ng-controller="OperationController as oc">Half of {{oc.number}} is {{oc.result}}</p>

<script type="text/javascript">
    var appAlgebra = angular.module("algebra", []);

    appAlgebra.value('operand', 39475);

    appAlgebra.controller("OperationController", function (operand) {
        this.number = operand;
        this.result = operand / 2.00;
    });
</script>
</body>
</html>

Updating a Valued Service

To change the value of the service, simply assign a value to it. Here is an example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Exercise</title>
    <script src="Scripts/angular.js"></script>
</head>
<body ng-app="algebra">
    <p ng-controller="OperationController as oc">Half of {{oc.number}} is {{oc.result}}</p>

    <script type="text/javascript">
        var appAlgebra = angular.module("algebra", []);

        appAlgebra.value('operand', 39475);

        function calculate(operand) {
            operand = 9387314;

            this.number = operand;
            this.result = operand / 2.00;
        }
        appAlgebra.controller("OperationController", calculate);
    </script>
</body>
</html>

This would produce:

Updating a Valued Service

Attaching a Service

Instead of separately creating a service, you can attach its creation to that of a module or of another component. To do this, after the closing parenthesis of the creation of a module or other component, type a period followed by the creation of the service. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.js"></script>
</head>
<body ng-app="quotes">
    <p ng-controller="CommunityController as cc">Mutual Support: {{cc.repeat}}</p>

<script type="text/javascript">
    angular.module("quotes", [])
    .value('aSaying', "I scratch your back, you scratch mine")
    .controller("CommunityController", function (aSaying) {
            this.repeat = aSaying;
    });
</script>
</body>
</html>

This would produce:

Attaching Service

A Constant Service

As another technique to create a service that uses a value, AngularJS provides a method named constant. It it is primarily used like the value() method. Here is an example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Exercise</title>
    <script src="Scripts/angular.js"></script>
</head>
<body ng-app="algebra">
    <p ng-controller="OperationController as oc">Half of {{oc.number}} is {{oc.result}}</p>

    <script type="text/javascript">
        var appAlgebra = angular.module("algebra", []);

        appAlgebra.constant('operand', 39475);

        function calculate(operand) {
            operand = 9387314;

            this.number = operand;
            this.result = operand / 2.00;
        }
        appAlgebra.controller("OperationController", calculate);
    </script>
</body>
</html>

A Constant Service

Techniques of Creating Valued Services

An Object as a Valued Service

You can create an object that provides a valued (or valuable) service. To start, call the value() method ono a module (or on a component). Pass a name as the first argument. Use the desired object as the second argument. You can first create an object and then pass its name as the second argument of the value() method. Here is an example:

var validation = {

};

app.value('tsService', . . .);

A Property in a Valued Object

In the body of the object, you can create any type of member. At a minimum, you can create a property in the object. Here is an example:

var validation = {
    announce: "The username you provided doesn't match anything in our records."
};

app.value('tsService', . . .);

Accesing a Member of a Valued Service

To access the object in the service, you have various options. If you want to access only a property of the object, for the second argument of the value() method, type the name of the object, a period, and the member of the object. Here is an example:

var validation = {
    announce: "The username you provided doesn't match anything in our records."
};

app.value('tsService', validation.announce);

Then, use the service as we know already. That is, pass the valued service as the argument to the constructor of a controller. In the body of that constructor, you can use the service. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Kolo Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appTimeSheet">
<script>
    var app = angular.module('appTimeSheet', []);

    var validation = {
        announce: "The username you provided doesn't match anything in our records."
    };

    app.value('tsService', validation.announce);

    function present(tsService) {
        this.user = tsService;
    }
    app.controller("TimeSheetController", present);
</script>

<p ng-controller="TimeSheetController as tsc"><b>Error:</b> {{tsc.user}}</p>
</body>
</html>

This would produce:

Accesing a Member of a Valued Service

The object of a valued service can have as many members as you want. If you use the above technique of specifying a desired member in the second argument to the value() method, the controller can access only that member. In fact, in the consructor of the controller, the valued argument represents only the member that specified. Consider the following example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Social Science Studies</title>
    <style type="text/css">
        .bold {
            font-weight: 600;
        }
    </style>
    <script src="Scripts/angular.min.js"></script>
</head>

<body ng-app="socialScience">
    <h1>Social Science Studies</h1>
    <p ng-controller="KnowledgeController as kc">
        <span class="bold">Author:</span> {{kc.identification}}
    </p>

    <script type="text/javascript">
    var appSocialScience = angular.module("socialScience", []);
    var discipline = {
        field: "Psychology",
        author: "Abraham Maslow",
        proposition: "Hierarchy of Needs"
    };

    appSocialScience.value('study', discipline.author);

    appSocialScience.controller("KnowledgeController", function (study) {
        this.identification = study;
    });
    </script>
</body>
</html>

This would produce:

Accesing a Member of a Valued Service

If the object of the valued service has more than one member and you want to access all members of the object, pass the object or its name as the second argument to the value() method. Here is an example:

var appSocialScience = angular.module("socialScience", []);
var discipline = {
    field: "Psychology",
    author: "Abraham Maslow",
    proposition: "Hierarchy of Needs"
};

appSocialScience.value('study', discipline);

Once again, pass the name of the valued service as argument to the constructor of the controller. In the body of that controller, you can declare a this variable for each member and assign the desired service variable to it. In the webpage, access the object members through the variables from the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Social Science Studies</title>
<style type="text/css">
.bold { font-weight: 600; }
</style>
<script src="Scripts/angular.min.js"></script>
</head>

<body ng-app="socialScience">
    <h1>Social Science Studies</h1>
    <ul ng-controller="KnowledgeController as kc">
        <li><span class="bold">Field of Study:</span> {{kc.introduction}}</li>
        <li><span class="bold">Author:</span> {{kc.identification}}</li>
        <li><span class="bold">Proposition:</span> {{kc.definition}}</li>
    </ul>

<script type="text/javascript">
    var appSocialScience = angular.module("socialScience", []);
    var discipline = {
        field: "Psychology",
        author: "Abraham Maslow",
        proposition: "Hierarchy of Needs"
    };

    appSocialScience.value('study', discipline);

    appSocialScience.controller("KnowledgeController", function (study) {
        this.introduction = study.field;
        this.identification = study.author;
        this.definition = study.proposition;
    });
</script>
</body>
</html>

This would produce:

Value-Based Service

In this case also, you can create the valued object before creating the service or you can create the object directly in the second argument of the value() method. You can then pass the name of the service to the controller and, in the constructor of the controller, access each member of the service. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<style type="text/css">
.bold        { font-weight: 600;   }
.left-column { width:       125px; }
table        { width:       200px; }
</style>
<script src="Scripts/angular.min.js"></script>
</head>
<h1>Employee Record</h1>

<body ng-app="departmentStore">
    <table border="2" ng-controller="StaffController as sc">
        <tr>
            <td class="bold left-column">First Name:</td>
            <td>{{sc.fname}}</td>
        </tr>
        <tr>
            <td class="bold">Last Name:</td>
            <td>{{sc.lname}}</td>
        </tr>
        <tr>
            <td class="bold">Hourly Salary:</td>
            <td>{{sc.base}}</td>
        </tr>
        <tr>
            <td class="bold">Time Worked:</td>
            <td>{{sc.work}}</td>
        </tr>
    </table>

<script type="text/javascript">
    var appStore = angular.module("departmentStore", []);

    appStore.value('employee', {
        firstName: "Elihaz",
        lastName: "Haffsan",
        hourlySalary: 26.48,
        timeWorked: 38.50
    });

    appStore.controller("StaffController", function (employee) {
        this.fname = employee.firstName;
        this.lname = employee.lastName;
        this.base  = employee.hourlySalary;
        this.work  = employee.timeWorked;
    });
</script>
</body>
</html>

This would produce:

An Object as a Valued Service

A Method in a Valued Service

If you create an object that will provide a service, if you want to perform an operation as part of the service, you can create a function as a member of the object. This means that you can include a method in the object of a value-based service. The method can be as simple as one that displays something. Here is an example:

var quotation = {
   say: function () {
        return "The man who is swimming against the stream knows the strength of it. - Woodrow Wilson";
    }
};

As seen with properties, to use (only) this method, pass the name of the object, a period, the name of the method, and parentheses. Here is an example:

var app = angular.module('appSocialScience', []);

var quotation = {
    say: function () {
        return "The man who is swimming against the stream knows the strength of it. - Woodrow Wilson";
    }
};

app.value('valuedService', quotation.say());

The service can then be passed to a controller as we have done so far. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Social Science Studies</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appSocialScience">
<script>
    var app = angular.module('appSocialScience', []);

    var quotation = {
        say: function () {
            return "The man who is swimming against the stream knows the strength of it. - Woodrow Wilson";
        }
    };

    app.value('valuedService', quotation.say());

    function communicate(valuedService) {
        this.wisdom = valuedService;
    }
    app.controller("PoliticalScienceController", communicate);
</script>

<p ng-controller="PoliticalScienceController as psc"><b>Valuable Quote:</b> {{psc.wisdom}}</p>
</body>
</html>

This would produce:

Value-Based Service - A Method in a Valued Service

The above example supposes that you want to access the only method in the object or you want to access only one of the methods in the object. As done previously with properties, if you want to access most or all members (including methods) of the object, pass the whole object to the value() method. In this case also, you can create the object directly in the second argument of the value() method.

Most of the time, you create a method because you want the service to perform some operation(s). To make this happen, in the body of that method, return an expression of your choice. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<style type="text/css">
.bold        { font-weight: 600;   }
.left-column { width:       125px; }
table        { width:       200px; }
</style>
<script src="Scripts/angular.min.js"></script>
</head>
<h1>Employee Record</h1>

<body ng-app="departmentStore">
    <table border="2" ng-controller="StaffController as sc">
        <tr>
            <td class="bold left-column">First Name:</td>
            <td>{{sc.fname}}</td>
        </tr>
        <tr>
            <td class="bold">Last Name:</td>
            <td>{{sc.lname}}</td>
        </tr>
        <tr>
            <td class="bold">Hourly Salary:</td>
            <td>{{sc.base}}</td>
        </tr>
        <tr>
            <td class="bold">Time Worked:</td>
            <td>{{sc.work}}</td>
        </tr>
        <tr>
            <td class="bold">Net Pay:</td>
            <td>{{sc.salary}}</td>
        </tr>
    </table>

<script type="text/javascript">
    var appStore = angular.module("departmentStore", []);

    appStore.value('employee', {
        firstName: "Elihaz",
        lastName: "Haffsan",
        hourlySalary: 26.48,
        timeWorked: 38.50,
        netPay: function () {
            return this.hourlySalary * this.timeWorked;
        }
    });

    appStore.controller("StaffController", function (employee) {
        this.fname = employee.firstName;
        this.lname = employee.lastName;
        this.base = employee.hourlySalary;
        this.work = employee.timeWorked;
        this.salary = employee.netPay();
    });
</script>
</body>
</html>

This would produce:

A Method in a Valued Service

Remember that you can also attach the service creation to a module or other component. Here is an example of a valued service attached to the creation of a module:

angular.module("departmentStore", []).
        value('employee', {
            firstName: "Elihaz",
            lastName: "Haffsan",
            hourlySalary: 26.48,
            timeWorked: 38.50,
            netPay: function () {
                return this.hourlySalary * this.timeWorked;
            }
        }).
        controller("StaffController", function (employee) {
            this.fname = employee.firstName;
            this.lname = employee.lastName;
            this.base = employee.hourlySalary;
            this.work = employee.timeWorked;
            this.salary = employee.netPay();
        }
    );

Previous Copyright © 2017-2019, FunctionX Next