AngularJS Service Providers

Introduction to Providers

In previous lessons and sections, we saw that a service is an object that performs one or more operations to solve one particular, or various types of, problems. We also saw that AngularJS supports various types of services, including constant services, value services, service()-based services, and factory services. All these objects or services are referred to as service providers, or providers. To state it another way, a provider is an object that creates and manages one or more services, to solve one or more problems.

To support providers as a concept, AngularJS uses the general name of Provider as the parent to all types of service providers.

Introduction to Creating a Provider

To let you create a Provider, AngularJS provides a function named provider. It uses the same syntax we saw for the other components (controllers, services, and directives):

provider(name, function-definition);

As seen with the other components, to create a Provider, you can register it with a module. To do this, you can attach the provider() function to the creation of a module, or you can attach it to a module variable. Here is an example:

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

app.provider('exercise', function () {
    
});

To make your code a little clearer, you can end the name of a Provider with Provider. Here is an example:

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

app.provider('internetServiceProvider', function () {
    
});

Primary Operations on a Provider

Getting a Value from a Provider

If you need to send a value of a Provider to another component, to assist you with this, the Provider includes a nested function named $get. This function is accessed through the this object. The $get function must produce an object. This can be done as follows:

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

app.provider('exo', function () {
    this.$get = function () {
            return  { };
    }
});

In the body of the $get() function, create one or more properties by which you want to send (a) value(s) or object(s) to a view. Here is an example:

var appBank = angular.module('communityBank', []);

appBank.provider('customerSupportProvider', function () {
    this.$get = function () {
        return { slogan: 'Banking now for a better future...' };
    }
});

As seen previously, before using the service, you can pass it as argument to a controller. This can be done as follows:

var appBank = angular.module('communityBank', []);

appBank.controller('AccountsController', function (customerSupportProvider) {

});

appBank.provider('customerSupportProvider', function () {
    this.$get = function () {
        return { slogan: 'Banking now for a better future...' };
    }
});

In the constructor of the controller, you can access a value created in the $get object using the name of the provider, a period, and the name of the property, and then assign it to a this object. This can be done as follows:

appBank.controller('AccountsController', function (customerSupportProvider) {
        this.boast = customerSupportProvider.slogan;
    });

In the view, you can then access the $get value using an instance of the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Community Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    var appBank = angular.module('communityBank', []);

    appBank.controller('AccountsController', function (customerSupportProvider) {
        this.boast = customerSupportProvider.slogan;
    });

    appBank.provider('customerSupportProvider', function () {
            this.$get = function () {
                return { slogan: 'Banking now for a better future...' };
            }
        });
</script>

<div ng-controller="AccountsController as ec">
    <p>{{ec.boast}}</p>
</div>
</body>
</html>

This would produce:

Getting a Value from a Provider

Providing Various Values

Because the provider.$get() method returns an object, you can use it to pass as many values as you want to a controller. To do this, create the necessary properties in that method and access each by its name in the constructor of the controller, then, in the view, access those properties by their assigned names in the controller. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Community Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    var appBank = angular.module('communityBank', []);

    appBank.controller('AccountsController', function (customerSupportProvider) {
        this.institution = customerSupportProvider.bankName;
        this.boast = customerSupportProvider.slogan;
        this.adrs = customerSupportProvider.address;
    });

    appBank.provider('customerSupportProvider', function () {
            this.$get = function () {
                return {
                    bankName: 'Community Bank',
                    slogan: 'Banking now for a better future...',
                    address: '8274 Phenicia Rd, Smiths Grove, KY 42171'
                };
            }
        });
</script>

<div ng-controller="AccountsController as ec">
    <h1>{{ec.institution}}</h1>
    <p><b>Slogan:</b> {{ec.boast}}<br />
    <b>Location:</b> {{ec.adrs}}</p>
</div>
</body>
</html>

This would produce:

Providing Various Values

In the above code, we used the this object to get values in the controller. In the same way, you can use a $scope service for the same goal. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Community Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    var appBank = angular.module('communityBank', []);

    appBank.controller('AccountsController', function ($scope, customerSupportProvider) {
        $scope.institution = customerSupportProvider.bankName;
        $scope.boast = customerSupportProvider.slogan;
        $scope.adrs = customerSupportProvider.address;
        $scope.moreInformation = customerSupportProvider.webSite;
        $scope.emailAddress = customerSupportProvider.contact;
    });

    appBank.provider('customerSupportProvider', function () {
        this.$get = function () {
            return {
                bankName: 'Community Bank',
                slogan: 'Banking now for a better future...',
                address: '8274 Phenicia Rd, Smiths Grove, KY 42171',
                webSite: 'http://www.KentukyCommunityBank.com',
                contact: 'banksupport@KentukyCommunityBank.com'
            };
        }
    });
</script>

<div ng-controller="AccountsController as ec">
    <h1>{{institution}}</h1>
    <b>Slogan:</b> {{boast}}<br />
    <b>Location:</b> {{adrs}}<br />
    <b>For more information, visit</b> {{moreInformation}}<br />
    <b>Contact us at</b> {{emailAddress}}</p>
</div>
</body>
</html>

This would produce:

Providing Various Values

Setting a Value for a Provider

To pass a value to a provider, in its constructor, create a function named set. Attach the function to a this object. Pass an argument to the function. By tradition, the argument is named value (but you can name it anything you want). The set function can be started as follows:

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

app.provider('bank', function () {
    this.set = function (value) {
   
    }
});

In the constructor of the Provider, you should declare a var variable. Initialize that variable with the appropriate type of value. Here is an example:

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

app.provider('bank', function () {
    var ms = 'Anything';

    this.set = function (value) {
   
    }
});

In the body of the this.set() function, assign the argument to the local variable you had declared. Here is an example:

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

app.provider('bank', function () {
    var ms = 'Anything';

    this.set = function (value) {
        ms = value;
    }
});

To send a value to the Provider, in the constructor of a controller, access the set value through the Provider passed as argument to the controller and assign the desired value to it. Here is an example:

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

app.controller('businessController', function (bank) {
    bank.misssionStatement = "To serve the communities in Kentucky and address their financial concerns.";
});

app.provider('bank', function () {
    var ms = 'Mission Statement';

    this.set = function (value) {
        ms = value;
    }
});

To access the value of the Provider, in the body of its $get() function, set the local variable as the value of the property of the object you are returning. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Koko Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    var app = angular.module('communityBank', []);

    app.controller('businessController', function (bank) {
        bank.misssionStatement = "To serve the communities in Kentucky and addressg their financial concerns.";

        this.motivation = bank.misssionStatement;
    });

    app.provider('bank', function () {
        var ms = 'Mission Statement';

        this.set = function (value) {
            ms = value;
        }
        this.$get = function () {
            return  { misssionStatement: ms };
        }
    });
</script>

<div ng-controller="businessController as bc">
    <p><b>Mission Statement:</b> {{bc.motivation}}</p>
</div>
</body>
</html>

This would produce:

Setting a Value for a Provider

Providing an Object to a Component

If you want to pass various values from a Provider to a component, in the body of the provider() function, declare a variable and assign an object to it. Of course, in the body of the object, create the properties and you assign some default values to them. In the body of the set() method, assign the argument to the name of the object. In the object returned by the $get() method, you can set the value of each property to the equivalent var object. In the body of the controller, access the members of the $get() object as we have done so far. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Koko Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    'use strict'

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

    app.controller('businessController', function (bank) {
        bank.bankName = 'Community Bank';
        bank.slogan = 'Banking now for a better future...';
        bank.address = '8274 Phenicia Rd, Smiths Grove, KY 42171';
        bank.misssionStatement = "To serve the communities in Kentucky and address their financial concerns.";

        this.address = bank.address;
        this.motivation = bank.slogan;
        this.institution = bank.bankName;
        this.performance = bank.misssionStatement;
    });

    app.provider('bank', function () {
        var banker = {
            institution: 'Bank',
            motto: 'Guiding Beliefs',
            ms: 'Mission Statement',
            address: 'Somewhere'

        };

        this.set = function (value) {
            banker = value;
        }
        this.$get = function () {
            return {
                bankName: banker.institution,
                slogan: banker.motto,
                misssionStatement: banker.ms,
                address: banker.address
            };
        }
    });
</script>

<div ng-controller="businessController as bc">
    <h1>{{bc.institution}}</h1>
    <p><b>Slogan:</b> {{bc.motivation}}<br />
       <b>Mission Statement:</b> {{bc.performance}}<br />
       <b>Location:</b> {{bc.address}}</p>
</div>
</body>
</html>

This would produce:

Providing an Object to a Component

As an alternative, you can make the $get() method return the var object that is created in the Provider. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Koko Bank</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="communityBank">

<script>
    'use strict'

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

    app.controller('businessController', function (bank) {
        bank.bankName = 'Community Bank';
        bank.slogan = 'Banking now for a better future...';
        bank.address = '8274 Phenicia Rd, Smiths Grove, KY 42171';
        bank.misssionStatement = "To serve the communities in Kentucky and address their financial concerns.";
        bank.webSite = 'http://www.KentukyCommunityBank.com';

        this.site = bank.webSite;
        this.address = bank.address;
        this.motivation = bank.slogan;
        this.institution = bank.bankName;
        this.performance = bank.misssionStatement;
    });

    app.provider('bank', function () {
        var banker = {
            institution: 'Bank',
            motto: 'Guiding Beliefs',
            ms: 'Mission Statement',
            address: 'Somewhere',
            webSite: 'More Infor'

        };

        this.set = function (value) {
            banker = value;
        }
        this.$get = function () {
            return banker;
        }
    });
</script>

<div ng-controller="businessController as bc">
    <h1>{{bc.institution}}</h1>
    <p><b>Slogan:</b> {{bc.motivation}}<br />
       <b>Mission Statement:</b> {{bc.performance}}<br />
       <b>Location:</b> {{bc.address}}<br />
       <b>Visit Us:</b> {{bc.site}}</p>
</div>
</body>
</html>

This would produce:

Providing an Object to a Component

Providing a Configured Component

Providing a Service

In previous lessons and sections, we saw that, to create a component, you can register it using either its appropriate function or the provider() function to a module. To support another technique to create a component, AngularJS provides a service named $provide.

Configuring a Service

The functions used to create and register components are complete enough not to need much configuration. If you decide to call the provider() function to register a component, to assist you with this, AngularJS provides a function named config that is used with the Provider. The config() method takes one argument, which is a function:

config(function-definition);

The function passed as argument to the config() method takes the $provide service as argument. Once again, you can define the function separately or directly in the parentheses of the config() method. This would be done as follows:

config(function($provide){

});

In the body of the function, create the service by attaching it to the $provide object. To use the service, once again, pass it as argument to a controller. The member(s) of the service are accessed as seen previously.

The Categories of Providers

A Constant Provider

A type of service that handles a constant value or object is created using the constant() function. To create it as a provider, attach the function to a $provide object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Salary Evaluation</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appSalaryEvaluation">
    <h2>Salary Evaluation</h2>

    <table ng-controller="OperationController as oc" border="0">
        <tr>
            <td style="width: 135px">Hourly Salary</td>
            <td style="width: 75px">{{oc.hourlySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Daily Salary</td>
            <td>{{oc.dailySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Weekly Salary</td>
            <td>{{oc.weeklySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Biweekly Salary</td>
            <td>{{oc.biweeklySalary | number : 2}}</td>
        </tr>    
        <tr>
            <td>Monthly Salary</td>
            <td>{{oc.monthlySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Yearly Salary</td>
            <td>{{oc.yearlySalary | number : 2}}</td>
        </tr>
    </table>

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

    appOperations.config(function ($provide) {
        $provide.constant('baseSalary', 28.74);
    });

    appOperations.controller("OperationController", function calculate(baseSalary) {
        this.hourlySalary = baseSalary;
        this.dailySalary = baseSalary * 8.00;
        this.weeklySalary = this.dailySalary * 5.00; // baseSalary * 40.00;
        this.biweeklySalary = baseSalary * 40.00 * 2.00;
        this.monthlySalary = this.weeklySalary * 4.00; // baseSalary * 160.00;
        this.yearlySalary = this.monthlySalary * 12.00;
    });
</script>
</body>
</html>

This would produce:

Categories of Providers - A Constant Provider

A Valued Provider

As you may know already, one of the types of service providers you can create in AngularJS is with the value() function. To create such a service as a provider, attach its creation to the $provide object. Here is an example of creating a valued provider:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Salary Evaluation</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appSalaryEvaluation">
    <h2>Salary Evaluation</h2>

    <table ng-controller="OperationController as oc" border="0">
        <tr>
            <td style="width: 135px">Hourly Salary</td>
            <td style="width: 75px">{{oc.hourlySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Weekly Salary</td>
            <td>{{oc.weeklySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Biweekly Salary</td>
            <td>{{oc.biweeklySalary | number : 2}}</td>
        </tr>    
        <tr>
            <td>Monthly Salary</td>
            <td>{{oc.monthlySalary | number : 2}}</td>
        </tr>
        <tr>
            <td>Yearly Salary</td>
            <td>{{oc.yearlySalary | number : 2}}</td>
        </tr>
            
    </table>

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

    appOperations.config(function ($provide) {
        $provide.value('baseSalary', 86285);
    });

    appOperations.controller("OperationController", function calculate(baseSalary) {
        this.yearlySalary = baseSalary;
        this.monthlySalary = baseSalary / 12.00;
        this.biweeklySalary = this.monthlySalary / 2.00;
        this.weeklySalary = this.monthlySalary / 4.00;
        this.hourlySalary = this.weeklySalary / 40.00;
    });
</script>
</body>
</html>

This would produce:

Categories of Providers - A Valued Valued

Of course, the value can be an object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
table        { width:       300px; }
.bold        { font-weight: 600;   }
.left-column { width:       135px; }
</style>
<title>Weekly Salary</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="departmentStore">
    <h2>Weekly Salary</h2>
    
    <table 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 | number : 2}}</td>
        </tr>
        <tr>
            <td class="bold">Net Pay:</td>
            <td>{{sc.salary | number : 2}}</td>
        </tr>
    </table>

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

    appStore.config(function ($provide) {
        $provide.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:

Categories of Providers - A Valued Valued

A Service Provider

If you want to create a service that can perform various types of operations with high interactivity with a view, you can use the service() function. To make it a service provider, attach this function to the provide service. Include the creation in a call to config(). Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Employee Time Sheet</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appTimeSheet">
    <h1>Employee Time Sheet</h1>

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

    appAlgebra.config(function ($provide) {
        $provide.service('tsService', function () {
            this.wrongUsername = "The username you provided doesn't match anything in our records.";
            this.passwordMatch = "The passwords you provided do not match. Make sure you type the exact same password in both text boxes.";
            this.combination = "The combination of the username and password you typed do not match our records.";
        });
    });

    appAlgebra.controller("TimeSheetController", function (tsService) {
        this.user = tsService.wrongUsername;
        this.pass = tsService.passwordMatch;
        this.combo = tsService.combination;
    });
</script>

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

A Factory Service Provider

Besides the value() or the service() methods, you can call the factory() function to create a simple service that returns a constant. You can do this by calling this function from a $provide object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Major Study - Sociology</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appMajorStudy">
    <h1>Sociology</h1>

<script type="text/javascript">
    var appSociology = angular.module('appMajorStudy', []);

    appSociology.config(function ($provide) {
        $provide.factory('socioFactory', function () {
            return "Sociology is the study of the various aspects of the society in general. Sociology can also be confined to a specific aspect.";
        });
    });

    appSociology.controller("RevelationController", function (socioFactory) {
        this.definition = socioFactory; //.introduction;
    });
</script>

<div ng-controller="RevelationController as rc">
    <p><b>Introduction:</b> {{rc.definition}}</p>
</div>
</body>
</html>

Probably the most common way to create a service that produces a sophisticated object is by calling the factory() function. By attaching it to a $provide service, you can create an object-based service provider. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Major Study - Social Sciences</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="appMajorStudies">
    <h1>Social Science Studies</h1>

<script type="text/javascript">
    var appMajors = angular.module('appMajorStudies', []);

    appMajors.config(function ($provide) {
        $provide.factory('socialScienceFactory', function () {
            return {
                LNGST: 'Linguistics',
                SOCIO: 'Sociology',
                PSYCH: 'Psychology',
                PHILO: 'Philosophy'
            };
        });
    });

    appMajors.controller("AdmissionsController", function (socialScienceFactory) {
        this.ling = socialScienceFactory.LNGST;
        this.soc = socialScienceFactory.SOCIO;
        this.psyc = socialScienceFactory.PSYCH;
        this.phil = socialScienceFactory.PHILO;
    });
</script>

<div ng-controller="AdmissionsController as ac">
    <ul>
        <li><b>1001:</b> {{ac.ling}}</li>
        <li><b>1002:</b> {{ac.soc}}</li>
        <li><b>1003:</b> {{ac.psyc}}</li>
        <li><b>1004:</b> {{ac.phil}}</li>
    </ul>
    
</div>
</body>
</html>

A Provider for Each Built-In Service

As mentioned above, AngularJS consider the Provider concept as the parent of all components. To the object that provides the functionality of a built-in service, AngularJS provides objects whose names start with the name of the service followed by Provider. Some the names are $httpProvider for the $http service or $locationProvider for the $location service.


Previous Copyright © 2017-2019, FunctionX Next