A Service Injector

Introduction

To support dependency injection as a service, AngularJS provides a service named $injector. To let you create an object that retrieves the services of a module, the angular object is equipped with a method named injector. Its syntax is:

$injector angular.injector(modules, strictDi);

This method takes one required and one optional arguments. The first and required argument is passed as an array that contains one or more dependent modules such as the AngularJS module ng. The module(s) must be passed as (a) string(s). The angular.injector() returns an $injector object. One way you can get an $injector object is to declare a variable using this service as name and initialize the variable with a call to angular.injector(). Here is an example:

Practical LearningPractical Learning: Introducing Service Injectors

  1. Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project...
  3. In the middle frame of the New Project dialog box, click ASP.NET Web Application (.NET Framework). Change the project Name to GasUtilityCompany3
  4. Click OK
  5. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK
  6. In the Solution Explorer, right-click GasUtilityCompany3 and click Manage NuGet Packages...
  7. Click the Browser button.
    Do a search on angular
  8. In the list, click angularjs
  9. In the middle-right frame, click Install. If a dialog box comes up, read it and click OK
  10. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  11. Type GasCompany as the name of the file
  12. Click Add
  13. Create some styles as follows:
    body {
        background-color: white;
    }
    
    .bold          { font-weight: 600;    }
    .bill-contents { margin:      auto;
                     width:       325px;  }
    .txtContext    { width:       80px;   }
    .btnFormat     { height:      32px;
                     width:       200px;  }
    .left-column   { width:       195px;  }
    .common-font   { font-family: Georgia, 'Times New Roman', Times, serif; }
  14. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  15. Type BillsController as the name of the file
  16. Click Add
  17. Type the following code in the empty document:
    var appUtilityCompany = angular.module("appGasCompany", []);
    
    function prepare() {
    
    }
    
    appUtilityCompany.controller("BillsController", prepare);
  18. To create a service, in the Solution Explorer, right-click Scripts -> Add -> New Item...
  19. In the left frame of the Add New Item dialog box, click Web and, in the middle frame, click JavaScript File
  20. Change the Name of the file to BillsService
  21. Click Add
  22. In the empty document, type the following code:
    function manage() {
        var taxableSalary = 0.00;
        var allowanceRate = 77.90;
    
        var gasBill = {
            accountType: ['Industrial', 'Residential', 'Commercial'],
            consumption: function (a, b) { return b - a; },
    
            therms: function (a, b) { return gasBill.consumption(a, b) * 1.0367; },
            adjust: function (a, b) { return gasBill.therms(a, b) * 0.13086; },
            carrying: function (a, b) {
                var thrm = gasBill.therms(a, b);
    
                if (thrm <= 5000)
                    return thrm * 0.016289;
                else
                    return thrm * 0.009577;
            },
            deliv: function (a, b, c) {
                var thrm = gasBill.therms(a, b);
                var trans = gasBill.carrying(a, b);
                var first50Therms = 0, over50Therms = 0;
    
                if (thrm < 5000) {
                    first50Therms = thrm * 0.05269;
                    over50Therms = 0;
                }
                else {
                    first50Therms = 5000 * 0.5269;
                    over50Therms = (thrm - 5000) * 0.04995;
                }
    
                var subTotal = trans + gasBill.adjust(a, b) + first50Therms + over50Therms;
    
                if (c == 'Commercial')
                    return subTotal + 34.05;
                else if (c == 'Industrial')
                    return subTotal + 26.68;
                else // if (c == 'Residential')
                    return subTotal + 17.84;
            },
            enviro: function (a, b, c) { return gasBill.deliv(a, b, c) * 0.0045; },
            pmt: function (a, b, c) { return gasBill.deliv(a, b, c) + gasBill.enviro(a, b, c); }
        };
    
        return gasBill;
    }
    
    appGasCompany.factory('billsService', manage);
  23. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  24. Change the document as follows:
    using System.Web.Optimization;
    
    namespace GasUtilityCompany3
    {
        public class BundleConfig
        {
            // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
            public static void RegisterBundles(BundleCollection bundles)
            {
                bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                            "~/Scripts/jquery-{version}.js",
                            "~/Scripts/angular.js",
                            "~/Scripts/BillsController.js",
                            "~/Scripts/BillsService.js"));
    
                bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                            "~/Scripts/jquery.validate*"));
    
                // Use the development version of Modernizr to develop with and learn from. Then, when you're
                // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
                bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                            "~/Scripts/modernizr-*"));
    
                bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                          "~/Scripts/bootstrap.js"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css",
                          "~/Content/GasCompany.css"));
            }
        }
    }

Injecting a Dependency

To let you explicitly inject a dependency to a component, the returned value of a component is equipped with a property named $inject. The value of an $inject property is an array. Therefore, to specify a dependency, after creating a controller, access the $inject property from its name and assign an array to it. Pass the name of the desired dependency inside the square brackets. The dependency must be included in quotes. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    var app = angular.module("appExercise", []);

    function calculate($scope) {
        $scope.subtract = function (a, b) {
            return a - b;
        }
    }

    app.controller("ExerciseController", calculate);

    calculate.$inject = ["$scope"];
</script>

    <div ng-app="appExercise">
        <p ng-controller="ExerciseController">438 - 153 = {{subtract(438, 153)}}</p>
    </div>
</body>
</html>

Practical LearningPractical Learning: Injecting a Dependency

  1. Access the BillsController.js file and change it as follows:
    var appGasCompany = angular.module("appGasCompany", []);
    
    function prepare(billsService) {
        this.filingStatus = billsService.accountType;
    
        this.proceed = function () {
            var readingBeginning = Number(this.counterReadingStart || 0);
            var readingEnd = Number(this.counterReadingEnd || 0);
    
            this.CCFTotal              = billsService.consumption(readingBeginning, readingEnd);
            this.totalTherms           = billsService.therms(readingBeginning, readingEnd);
            this.ditributionAdjustment = billsService.adjust(readingBeginning, readingEnd);
            this.transportationCharges = billsService.carrying(readingBeginning, readingEnd);
            this.totalDelivery         = billsService.deliv(readingBeginning, readingEnd, this.filingsStatus);
            this.environmentCharges    = billsService.enviro(readingBeginning, readingEnd, this.filingsStatus);
            this.amountDue             = billsService.pmt(readingBeginning, readingEnd, this.filingsStatus);
        }
    }
    
    prepare.$inject = ["billsService"];
    
    appUtilityCompany.controller("BillsController", prepare);
  2. In the Solution Explorer, expand Controllers and double-click HomeController.cs
  3. In the class, add a class named BillEvaluation as follows:
    using System.Web.Mvc;
    
    namespace GasUtilityCompany3.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
            public ActionResult BillEvaluation()
            {
                return View();
            }
        }
    }
  4. In the Solution Explorer, expand Home and expand Shared
  5. Double-click _Layout.cshtml to open the file
  6. Change the document as follows:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Gas Utility Company :: @ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Gas Utility Company", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("Bill Evaluation", "BillEvaluation", "Home")</li>
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p class="common-font text-center">&copy; @DateTime.Now.Year - Gas Utility Company</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  7. Click the HomeController.cs tab to access the controller
  8. In the class, right-click BillEvaluation and click Add View...
  9. Make sure the View Name text box is displaying BillEvaluation. Click Add
  10. Change the document as follows:
    @{
        ViewBag.Title = "Bill Evaluation";
    }
    
    <h1 class="common-font text-center bold">Gas Utility Company</h1>
    <h2 class="common-font text-center bold">Bill Evaluation</h2>
    
    @Scripts.Render("~/bundles/jquery")
    
    <div class="bill-contents" ng-app="appGasCompany">
        <form name="IncomeTaxPreparation" method="post" ng-controller="BillsController as pc">
            <table class="table table-condensed">
                <tr>
                    <td><label for="CounterReadingEnd" class="bold">Counter Reading End:</label></td>
                    <td>
                        <input type="text" id="CounterReadingEnd" class="form-control txtContext"
                               ng-model="pc.counterReadingEnd" ng-change="pc.proceed()" />
                    </td>
                </tr>
                <tr>
                    <td class="left-column bold"><label for="CounterReadingStart">Counter Reading Start:</label></td>
                    <td>
                        <input type="text" id="CounterReadingStart" class="form-control txtContext"
                               ng-model="pc.counterReadingStart" ng-change="pc.proceed()" />
                    </td>
                </tr>
                <tr>
                    <td><label for="FilingStatus" class="bold">Account Type:</label></td>
                    <td>
                        <select class="form-control" id="FilingStatus" ng-model="pc.filingsStatus" ng-change="pc.proceed()">
                            <option ng-repeat="fs in pc.filingStatus">{{fs}}</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td class="bold">CCF Total:</td>
                    <td>{{pc.CCFTotal}}</td>
                </tr>
                <tr>
                    <td class="bold">Total Therms:</td>
                    <td>{{pc.totalTherms | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Ditribution Adjustment:</td>
                    <td>{{pc.ditributionAdjustment | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Transportation Charges:</td>
                    <td>{{pc.transportationCharges | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Total Delivery:</td>
                    <td>{{pc.totalDelivery | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Environment Charges:</td>
                    <td>{{pc.environmentCharges | number: 2}}</td>
                </tr>
                <tr>
                    <td class="left-column bold">Amount Due:</td>
                    <td>{{pc.amountDue | number: 2}}</td>
                </tr>
            </table>
        </form>
    </div>
  11. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Adding an Array to a Service

  12. In the Counter Reading End text box, type 216079

    Adding an Array to a Service

  13. In the Counter Reading Start text box, type 214485

    Adding an Array to a Service

  14. In the Account Type combo box, select Residential

    Adding an Array to a Service

  15. Close the form and return to your programming environment

Injecting Many Dependencies

If you want to specify more than one dependency, put them in the square brackets. Separate them with commas. Each service must be included in the brackets. The depencies in the square brackets must appear in the exact same order as the arguments in the parentheses of the component.

Practical LearningPractical Learning: Injecting Many Dependencies

  1. Click the BillsController.js tab to access the file
  2. Change the document as follows:
    var appGasCompany = angular.module("appGasCompany", []);
    
    function prepare($scope, billsService) {
        $scope.filingStatus = billsService.accountType;
    
        $scope.proceed = function () {
            var readingBeginning = Number($scope.counterReadingStart || 0);
            var readingEnd = Number($scope.counterReadingEnd || 0);
    
            $scope.CCFTotal              = billsService.consumption(readingBeginning, readingEnd);
            $scope.totalTherms           = billsService.therms(readingBeginning, readingEnd);
            $scope.ditributionAdjustment = billsService.adjust(readingBeginning, readingEnd);
            $scope.transportationCharges = billsService.carrying(readingBeginning, readingEnd);
            $scope.totalDelivery         = billsService.deliv(readingBeginning, readingEnd, $scope.filingsStatus);
            $scope.environmentCharges    = billsService.enviro(readingBeginning, readingEnd, $scope.filingsStatus);
            $scope.amountDue             = billsService.pmt(readingBeginning, readingEnd, $scope.filingsStatus);
        }
    }
    
    prepare.$inject = ['$scope', "billsService"];
    
    appGasCompany.controller("BillsController", prepare);
  3. Click the BillEvaluation.cshtml tab to access the webpage
  4. Change its code as follows (delete "as pc" after the controller attribute and delete every instance of "pc."):
    @{
        ViewBag.Title = "Bill Evaluation";
    }
    
    <h1 class="common-font text-center bold">Gas Utility Company</h1>
    <h2 class="common-font text-center bold">Bill Evaluation</h2>
    
    @Scripts.Render("~/bundles/jquery")
    
    <div class="bill-contents" ng-app="appGasCompany">
        <form name="IncomeTaxPreparation" method="post" ng-controller="BillsController">
            <table class="table table-condensed">
                <tr>
                    <td><label for="CounterReadingEnd" class="bold">Counter Reading End:</label></td>
                    <td>
                        <input type="text" id="CounterReadingEnd" class="form-control txtContext"
                               ng-model="counterReadingEnd" ng-change="proceed()" />
                    </td>
                </tr>
                <tr>
                    <td class="left-column bold"><label for="CounterReadingStart">Counter Reading Start:</label></td>
                    <td>
                        <input type="text" id="CounterReadingStart" class="form-control txtContext"
                               ng-model="counterReadingStart" ng-change="proceed()" />
                    </td>
                </tr>
                <tr>
                    <td><label for="FilingStatus" class="bold">Account Type:</label></td>
                    <td>
                        <select class="form-control" id="FilingStatus" ng-model="filingsStatus" ng-change="proceed()">
                            <option ng-repeat="fs in filingStatus">{{fs}}</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td class="bold">CCF Total:</td>
                    <td>{{CCFTotal}}</td>
                </tr>
                <tr>
                    <td class="bold">Total Therms:</td>
                    <td>{{totalTherms | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Ditribution Adjustment:</td>
                    <td>{{ditributionAdjustment | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Transportation Charges:</td>
                    <td>{{transportationCharges | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Total Delivery:</td>
                    <td>{{totalDelivery | number: 2}}</td>
                </tr>
                <tr>
                    <td class="bold">Environment Charges:</td>
                    <td>{{environmentCharges | number: 2}}</td>
                </tr>
                <tr>
                    <td class="left-column bold">Amount Due:</td>
                    <td>{{amountDue | number: 2}}</td>
                </tr>
            </table>
        </form>
    </div>
  5. To execute, on the main menu, click Build Build Solution
  6. In the Counter Reading End text box, type 597
  7. In the Counter Reading Start text box, type 135
  8. In the Account Type combo box, select Residential

    Dependency Injection

  9. Close the browser and return to your programming environment

The Inline Array Annotation

Introduction

In our introduction to arrays in AngularJS, we saw that the second argument of the definition of a constructor or service could be passed as an array. This could be done as follows:

var app = angular.module("appExercise", []);

function calculate($scope) {
    $scope.add = function (a, b) {
        return a + b;
    }
}

app.controller("ExerciseController", [calculate]);

Notice that, in this case, the constructor takes a service as argument. In this case, you must indicate that the constructor takes an argument. In other words, the controller has a depencency. To provide this information, after the opening curly bracket of the array, provide the name of each service. The name must be included in quotes (single or double) and followed by a comma. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    var app = angular.module("appExercise", []);

    function calculate($scope) {
        $scope.add = function (a, b) {
            return a + b;
        }
    }

    app.controller("ExerciseController", ["$scope", calculate]);
</script>

<div ng-app="appExercise">
    <p ng-controller="ExerciseController">438 * 156 = {{add(438, 156)}}</p>
</div>
</body>
</html>

This technique is referred to as inline array annotation.

Injecting Many Dependencies

You can use the inline array annotation to pass as many dependencies as you want. In the parentheses of the constructor, provide the list of arguments you plan to use. After the opening square braket of the array, provide the exact same list of arguments. Make sure you include each dependency in quotes and follow it with a comma. The order of the dependencies must be the same that is in the parentheses of the constructor. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    var app = angular.module("appExercise", []);

    function something() { }
    app.service('someTypeOfService', something);

    function evaluate($scope, someTypeOfService, $window) {
        $scope.add = function (a, b) {
            return a + b;
        }
    }

    app.controller("ExerciseController", ["$scope", 'someTypeOfService', '$window', evaluate]);
</script>

<div ng-app="appExercise">
    <p ng-controller="ExerciseController">1424 * 318 = {{add(1424, 318)}}</p>
</div>
</body>
</html>

Of course, you can define the constructor directly in the controller or service. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    var app = angular.module("appExercise", []);

    function something() { }
    app.service('someTypeOfService', something);

    app.controller("ExerciseController", ["$scope", 'someTypeOfService', '$window', function ($scope, someTypeOfService, $window) {
        $scope.add = function (a, b) {
            return a + b;
        }
    }]);
</script>

<div ng-app="appExercise">
    <p ng-controller="ExerciseController">438 * 156 = {{add(438, 156)}}</p>
</div>
</body>
</html>

The inline array notation is the recommended technique to use.

Other Built-In Services

A Window

Remember that the DOM provides a class named window that can be used to get information about the window that is hosting a webpage. To support an adapted version of that class, AngularJS provides a service named $window. This object gives you access to the properties and methods of the DOM class.

To use the $window service, first pass it as argument to the constructor of a controller. Here is an example:

var app = angular.module("appExamination", []);

function identify($scope, $window) {

}

app.controller("ExaminationController", identify);

In the body of the constructor, you can use the $window service to access the members of the window object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="Scripts/angular.min.js"></script>
<title>Exercise</title>
</head>
<body ng-app="appExamination">
    <p ng-controller="ExaminationController">{{messageBox()}}</p>

<script>
    var app = angular.module("appExamination", []);

    function identify($scope, $window) {
        $window.alert("Make sure you fill your time sheet before leaving for the day.");
    }

    app.controller("ExaminationController", identify);
</script>
</body>
</html>

A Document

You may remember that the DOM provides an object named document that gives you access to the contents of a webpage, including its tags (elements, webcontrols, etc). To support a customized version of that object, AngularJS provides a service named $document.

Before using the $document service, pass it as argument to the constructor of a controller in which you want to use this service. In the body of the constructor, you can access some of the members of the HTML's document object.

Introduction to the Location of a Web Document

Overview

As you may know already, the DOM supports the addresses of Web documents through an interface named Location and its derived location object. To use this object in AngularJS, the library provides a service named $location. As seen in JavaScript, this service provides a round-trip operation. On one hand, it can be used to specify the address of a document to access. On the other hand, it can be used to get the address of a document or webpage that is currently opened.

As done with other services, to use $location, pass it as argument to the constructor of a controller. Here is an example:

var appTicketSystem = angular.module('trafficTicketSystem', []);

appTicketSystem.controller("TrafficTicketController", function ($location) {});

The Address of a Document

As you may be aware already, the location of a Web document is its address, known as its URL. To let you get the address of a document, the $location service is equipped with a method named absUrl. This method returns the address of a document, as a string. Therefore, to get the address of the current document, call this method on a $location service and assign it to a local variable or pass the method to a function. Here is an example:

@{
    ViewBag.Title = "Exercise";
}

<h2>Exercise</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="appExercise">
    <div ng-controller="ExerciseController">
        <p>Address of Current Web Page: <b ng-bind="address"></b></p>
    </div>
</div>

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

    appExercise.controller("ExerciseController", ['$location', '$scope', function ($location, $scope) {
        $scope.address = $location.absUrl();
    }]);
</script>

This would produce:

The Address of a Document

The URL of a Web Page

The address of a webpage is an object with a constructor. At a minimum, it is provided as a string. In fact, as an alternative to the $location.absUrl() method, the $location service is equipped with a method named url. This method takes an optional argument. If you call it without an argument, the method refurns the address of the current document. To specify a url to use, pass the address as a string to the method.

The Protocol Used to Access a Web Page

A Web protocol is the language that is used to transmit information to a Web service such as a webpage (you are surely aware that there are various types of Web services (such as email, FTP, chat, etc) and webpage transmission/publication is just one of them). To let you find out the type of protocol used by a webpage, the DOM's location object and the AngularJS's $location service are equipped with a method named protocol. You can call it to get the protocol host by a webpage. Here is an example:

@{
    ViewBag.Title = "Exercise";
}

<h2>Exercise</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="appExercise">
    <div ng-controller="ExerciseController">
        <p style="color: red">The protocol used by this Web page is: <b ng-bind="pageProtocol"></b></p>
        <p>Address of Current Web Page: <b ng-bind="address"></b></p>
    </div>
</div>

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

    appExercise.controller("ExerciseController", ['$location', '$scope', function ($location, $scope) {
        $scope.address = $location.absUrl();
        $scope.pageProtocol = $location.protocol();
    }]);
</script>

This would produce:

The Protocol Used to Access a Web Page

The Host of a Web Site

A Web host is the computer and related technology in which a website (the folder, files, etc that constitute a website) is stored and made available to the public. To let you find out the host of a website, the DOM's location object and the AngularJS's $location service provide a method named host that you can call. Here is an example of calling the $location.host() method:

@{
    ViewBag.Title = "Exercise";
}

<h2>Exercise</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="appExercise">
    <div ng-controller="ExerciseController">
        <p style="color: tomato;">The host of this Web page is: <b ng-bind="webHost"></b></p>
        <p style="color: blue">The protocol used by this Web page is: <b ng-bind="pageProtocol"></b></p>
        <p>Address of Current Web Page: <b ng-bind="address"></b></p>
    </div>
</div>

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

    appExercise.controller("ExerciseController", ['$location', '$scope', function ($location, $scope) {
        $scope.webHost = $location.host();
        $scope.address = $location.absUrl();
        $scope.pageProtocol = $location.protocol();

    }]);
</script>

This would produce:

The Protocol Used to Access a Web Page

The Port Through Which a Web Site is Accessed

To let you the port by which a website is available, both the DOM's location object and the AngularJS's $location service are equipped with a method named port. Here is an example of calling the $location.port() method:

@{
    ViewBag.Title = "Exercise";
}

<h2>Exercise</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="appExercise">
    <div ng-controller="ExerciseController as ec">
        <p style="color: brown">Port through which this Web site is accessed: <b ng-bind="ec.porte"></b></p>
        <p style="color: tomato;">The host of this Web page is: <b ng-bind="ec.webHost"></b></p>
        <p style="color: blue">The protocol used by this Web page is: <b ng-bind="ec.pageProtocol"></b></p>
        <p>Address of Current Web Page: <b ng-bind="ec.address"></b></p>
    </div>
</div>

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

    appExercise.controller("ExerciseController", ['$location', function ($location) {
        this.webHost = $location.host();
        this.address = $location.absUrl();
        this.pageProtocol = $location.protocol();
        this.porte = $location.port();
    }]);
</script>

This would produce:

The Protocol Used to Access a Web Page

The Parameters to a Location

A Location Provider

The $location service primarily follows the DOM's location object. Still, in AngularJS, the $location service provides some features not available in the DOM. To let you get these enhancements, AngularJS has a provider named $locationProvider. It is used to indicate to the AngularJS compiler how the $location service should be handled.

To use the $locationProvider provider in your code, simply type it. You can then access its members. This is a small object that has only two methods.

Passing Parameters to an Address

The URL of a webpage can receive one ore more values from either you or the visitor of your webpage. To start, you must write code that can catch a (the) value(s) passed to the URL. To do this in ASP.NET MVC, create an action method. Pass a (the) value(s) to the method as (a) string(s). In the method, use the argument(s) as you see fit. For example, you can display the value(s) in a webpage or prepare to send them to the view. This can be done by using ViewBag. Here is an example:

using System.Web.Mvc;

namespace Exercise1.Controllers
{
    public class TrafficTicketsSystemController : Controller
    {
       . . .

        // GET: TrafficTicketsSystem/Driver
        public ActionResult Driver(int? DriverID, string DrvLicNbr, string FirstName, string LastName, string State)
        {
            ViewBag.Identification = DriverID + ": " + FirstName + " " + LastName + " (" + DrvLicNbr + "), " + State;

            return View();
        }
    }
}

To do the same thing in JavaScript or AngularJS, create a function and pass a(the) desired value(s) to it. In the webpage or view, create the necessary section(s) that will use the value(s). At a minimum, you can display the value(s) to the user. Here is an example:

@{
    ViewBag.Title = "Vehicles Owner/Driver";
}

<h2>Vehicles Owner/Driver</h2>

<p><b>Identification:</b> @ViewBag.Identification</p>

To manually pass a parameter to an address, a visitor can click on the right-side of the address, type a question mark, an equal sign, and the nececssary value. To add another value, the user can type an ampersand sign, &, followed by an expression similar to the first. Here is an example (?DrvLicNbr=100008&FirstName=Raymond&LastName=Kalla&State=TN)

After typing the parameter(s), the user can press Enter. If you are writing your code in JavaScript or AngularJS, to programmatically pass one or more values to a URL, pass the whole address to the $location.url() method. Here is an example:

var appTicketSystem = angular.module('trafficTicketSystem', []);

appTicketSystem.controller("TrafficTicketController", ['$location', function ($location) {
    $location.url("http://localhost:53030/TrafficTicketsSystem/Driver?DrvLicNbr=102004&FirstName=Jennifer&LastName=Colson&State=PA");
}]);

The section from the question mark to the end of the address is called a query string. For our example, the query string is ?DrvLicNbr=102004&FirstName=Jennifer&LastName=Colson&State=PA.

The Path to a Document

To let you get or set the path to a document, the $location service is equipped with a method named path. It works like the $location.url() method as it takes one optional argument. Here is an example:

@{
    ViewBag.Title = "Exercise";
}

<script src="~/Scripts/angular.js"></script>

<h2>Exercise</h2>

<div ng-app="exercise">
    <div ng-controller="ExerciseController as ec">
        <form name="Exercise">
            <p><input type="button" value="Search the Path" class="btn btn-primary" ng-click="ec.search()" /></p>
            <p><b>Web Page Path:</b> <span ng-bind="ec.way"></span></p>
            <p><b>Web Page Address:</b> <scan ng-bind="ec.address"></scan></p>
        </form>
    </div>
</div>

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

    exercise.controller("ExerciseController", function ($location) {
        this.search = function () {
            $location.url("https://docs.angularjs.org");

            this.address = $location.url();
            this.way = $location.path();
        }
    });
</script>

This would produce:

The Path to a Document

The Path to a Document

If the address of the webpage has (a) parameter(s), the path section is not included in the path results. Consider the following example:

@{
    ViewBag.Title = "Vehicles Owner/Driver";
}

<h2>Vehicles Owner/Driver</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="trafficTicketSystem">
    <form name="Employee" ng-controller="TrafficTicketController as ttc">
        <p><input type="button" value="Search the Path" class="btn btn-primary" ng-click="ttc.locate()" /></p>
        <p><b>Web Page Path:</b> <span ng-bind="ttc.way"></span></p>
        <p><b>Web Page Address:</b> <scan ng-bind="ttc.address"></scan></p>
    </form>
</div>

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

    appTicketSystem.controller("TrafficTicketController", ['$location', function ($location) {
        this.locate = function () {
            $location.url("http://localhost:53030/TrafficTicketsSystem/Driver?DrvLicNbr=102004&FirstName=Jennifer&LastName=Colson&State=PA");

            this.address = $location.url();
            this.way = $location.path();
        }
    }]);
</script>

This would produce:

The Path to a Document

The Path to a Document

Searching Through a Query String

One of the jobs that interests you with the query string is its content. At times, you may want know what it contains or whetner it contains a certain value. To assist you with looking for a value in the query string, both the DOM's location object and the AngularJS's $location service are equipped with a method named search. It produces an object that holds a combination of "key": "value" pairs (actually, in future lessons, we will learn that is referred to as a JSON object, for now, we don't care about that. Here is an example of calling the $location.search() method:

@{
    ViewBag.Title = "Exercise";
}

<h2>Exercise</h2>

<script src="~/Scripts/angular.js"></script>

<div ng-app="trafficTicketSystem">
    <form name="Employee" ng-controller="TrafficTicketController as ttc">
        <p><b>Web Page Address:</b> <scan ng-bind="ttc.address"></scan></p>
        <p><input type="button" value="Search the Path" class="btn btn-primary" ng-click="ttc.locate()" /></p>
        <p><b>Search Results:</b> <span ng-bind="ttc.result"></span></p>
        <p><b>Web Page Path:</b> <span ng-bind="ttc.way"></span></p>
    </form>
</div>

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

    appTicketSystem.controller("TrafficTicketController", ['$location', function ($location) {
        this.locate = function () {
            $location.url("http://localhost:53030/TrafficTicketsSystem/Driver?DrvLicNbr=102004&FirstName=Jennifer&LastName=Colson&State=PA");

            this.address = $location.url();
            this.way = $location.path();
            this.result = $location.search();
        }
    }]);
</script>

This would produce:

Searching Through a Query String

Searching Through a Query String

{"DrvLicNbr":"102004",
  "FirstName":"Jennifer",
  "LastName":"Colson",
  "State":"PA"}

As you can see, the result is made of sections where each is represented by a name and a value.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2018-2019, FunctionX Next