The Web Application Programming Interface

Introduction

The Web application programming interface, or Web API, is a list of techniques to create a Web-based application that allows a visitor of a webpage to interact with a webserver. The user uses a browser to open a webpage. The user creates and presents one or more requests, such as asking to see or view a document. The browser sends that request to the webserver, and the webserver responds, one way or another.

Both the .NET Framework and Microsoft Visual Studio support the Web API techniques to create a website. In Microsoft Visual Studio, to create a Web API project to support the Web API in your ASP.NET MVC project, start creating a project. In the New ASP.NET Web Application dialog box, click one of the Web API options and click OK.

Practical LearningPractical Learning: Introducing the Web API

  1. Start 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 MetropolitanTransitSystem1
  4. Click OK
  5. In the New ASP.NET Web Application dialog box, click the Web API icon

    New ASP.NET Web Application

  6. Click OK
  7. In the Solution Explorer, right-click TrafficTicketsManagement2 and click Manage NuGet Packages...
  8. In the NuGet tab, click Browser and, in the text box, type angularjs
  9. In the list, click angularjs
  10. Click Install.
    If a message box displays, click OK
  11. In the Solution Explorer, right-click MetropolitanTransitSystem1 -> Add -> New Folder
  12. Types Images and press Enter
  13. Add the following pictures to that folder:

    Metro Stations Metro Lines
    Metro Lines Maps Planning
    Metropolitan Transit System

    Metropolitan Transit System

  14. In the Solution Explorer, expand Controllers and double-click HomeController.cs to open it
  15. Add two methods as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace MetroSystem11.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "The Metropolitan Transit System provides a fast and reliable commute throughout our metropolitan area.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "For any concerns or questions, please contact us.";
    
                return View();
            }
    
            public ActionResult Get()
            {
                return View();
            }
    
            public ActionResult StationSearch()
            {
                return View();
            }
    
            public ActionResult Lines()
            {
                return View();
            }
            
            public ActionResult Emergencies()
            {
                return View();
            }
        }
    }
  16. In the Solution Explorer, right-click Content -> Add New Item...
  17. In the Add New Item dialog box, in the left framr under Visual C#, click Web and, in the middle frame, click Style Sheet
  18. Change the Name to MetroSystem
  19. Click Add
  20. Add a few styles as follows:
    body {
        background-color: #686666;
    }
    
    .bold { font-weight: 600; }
    .blue { color:       #0c47c1; }
    .container { background-color: #FFFFFF; }
    
    .top-group {
        background-color: #FFFFFF;
        border-bottom:    4px solid #000000; }
    
    .bottom-group {
        background-color: #000000;
        border-top: 4px solid #ffffff; }
    
    .top-group .navbar-nav > li > a { color: #0c47c1; }
    
    .top-group .navbar-nav > li > a:hover,
    .top-group .navbar-nav > li > a:focus {
        color: #ffffff;
        background-color: #0c47c1; }
    
    .top-group .navbar-nav > .active > a,
    .top-group .navbar-nav > .active > a:hover,
    .top-group .navbar-nav > .active > a:focus {
        color:            #ffffff;
        background-color: #080808; }
    
    .copy-holder { margin-top: 15px;
                   color:      #00ffff; }
    
    .metro-pic {
        height: 300px;
        padding-top: 120px;
        text-align: center;
        background-position: center;
        border-bottom: 2px solid #000000;
        background-image: url('../Images/mts3.jpg'); }
    
    .jumbotron { margin-bottom: 40px;
                 margin-left:   0; }
    
    .jumbotron h1 { line-height: 1;
                    color: #ffd800; }
    
    .container .jumbotron { border-radius: 1px; }
    
    @media screen and (min-width: 768px) {
        .jumbotron h1 { font-size: 63px; }
        .jumbotron { padding-top: 85px; }
        .container .jumbotron {
            margin-right: -15px;
            margin-left: -15px; }
    }
    
    .btn-info { color: #ffffff;
                background-color: #0c47c1;
                border-color: #000000; }
    
    .btn-info:hover,
    .btn-info:focus,
    .btn-info:active,
    .btn-info.active,
    .open .dropdown-toggle.btn-info {
        color: #ffffff;
        background-color: #39b3d7;
        border-color: #000000; }
    
    .btn-info:active,
    .btn-info.active,
    .open .dropdown-toggle.btn-info { background-image: none; }
    .common-font { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  21. In the Solution Explorer, expand Views and expand Shared
  22. Double-click _Layout.cshtml to open it
  23. Change the document as follows:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Metropolitan Transit System :: @ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar top-group 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>
                    <div><img src="~/Images/mts.png" alt="Metropolitan Transit System" width="172" height="50" /></div>
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav navbar-right">
                        <li>@Html.ActionLink("Metro Stations", "Get", "Home", new { area = "" }, null)</li>
                        <li>@Html.ActionLink("Metro Lines", "About", "Home")</li>
                        <li>@Html.ActionLink("Need Help?", "About", "Home")</li>
                        <li>@Html.ActionLink("About MTS", "About", "Home")</li>
                        <li>@Html.ActionLink("Contacts Us", "Contact", "Home")</li>
                        <li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer class="navbar bottom-group navbar-fixed-bottom">
                <div class="copy-holder">
                    <p class="text-center common-font">&copy; @DateTime.Now.Year - Metropolitan Transit System</p>
                </div>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  24. In the Solution Explorer, right-click MetropolitanTransitSystem1 and click Manage NuGet Packages...
  25. Click the Browser button.
    Do a search on angular (you must be connected to the Internet)
  26. In the list, click angularjs
  27. In the middle-right frame, click Install. If a dialog box comes up, read it and click OK

Introduction to Models

A database is a list of records. A record is a list of values of different categories. In other words, a record is an object in the JavaScript sense. To represent an object, you can start by creating a class. The class would contain one or more properties. Each property will represent a category of values.

In an ASP.NET project, to create a class that will represent the records of a database, you should use a folder named Models and create the class in it. If you create a project in Microsoft Visual Studio, the studio would create the Models folder for you. To get a model class, create the class in the Models folder.

Practical LearningPractical Learning: Introducting Models

  1. In the Solution Explorer, right-click Models -> Add -> Class...
  2. Type MetroStation as the name of the file
  3. Click Add
  4. Create the class as follows:
    namespace MetropolitanTransitSystem1.Models
    {
        public class MetroStation
        {
            public int    StationNumber { get; set; }
            public string StationName   { get; set; }
            public string Location      { get; set; }
            public bool   Parking       { get; set; }
            public int    BikeRacks     { get; set; }
        }
    }

Introduction to Web API Controllers

To support the Web API techniques of accessing and/or using records in a webpage, the .NET Framework provides a class named ApiController. It implements the IHttpController and the IDisposable interfaces.

To use the Web API in your project, create a class based on the ApiController class. To do this, in the Solution Explorer, right-click the Controllers folder, position the mouse on Add and click either Controller or New Scaffolded Item... In the Add Scaffold dialog box, click one of the Web API 2 options and click OK. A dialog box will ask you to name your new class. The name of the class must follow the rules of name in C# and must end with Controller.

When creating a controller, if you select Web API 2 Controller - Empty, you would get an empty class derived from ApiController. Here is an example:

using System.Web.Http;

namespace Exercises.Controllers
{
    public class ExerciseController : ApiController
    {
    }
}

The Data and the Data Repository

When creating a Web project, you must decide how you will handle data. You have many choices. You can use an array of objects. You can use a collection class for which you would serialize data to a hard drive and deserialize at will. You can use XML or a DataSet system. You can use JSON with AngularJS and use either the .NET Framework or third-party library to serialize and deserialize records. You can use a formal database (ADO.NET, Entity Framework, etc).

Your controller class is used to handle data, including creating records, getting/retrieving records, editing records, and deleting records. You must first decide by what means the controller class will locate (the origin of) those records.

Getting the Data

Whether your data is created in the controller class or stored in a file, you must first indicate how the controller class will get hold of it. To do this, you can create a method that returns a collection. The Web API suggests that you create a method that returns a collection, such as an object of a collection class or a class that implements the IEnumerable<> interface. Here is an example:

using System.Web.Http;

namespace Exercises.Controllers
{
    public class MerchandiseController : ApiController
    {
        public IEnumerable<...> Get()
        {
            return ...;
        }
    }
}

If you are using a generic collection class or interface, make sure you provide the appropriate type in <>. Probably the simplest list of values you can create and return is an array of strings. Here is an example from Microsoft Visual Studio:

using System.Web.Http;

namespace Exercises.Controllers
{
    public class ExerciseController : ApiController
    {
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    }
}

Otherwise, if you want to create a collection or array of objects, enter its class-name in <> and make sure the method returns a collection or array of that class.

Practical LearningPractical Learning: Getting the Data

  1. In the Solution Explorer, expand the Controllers folder
  2. Double-click ValuesController to open it
  3. Change the class as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Web.Http;
    using MetropolitanTransitSystem1.Models;
    
    namespace MetropolitanTransitSystem1.Controllers
    {
        public class ValuesController : ApiController
        {
            MetroStation[] stations = new MetroStation[]
            {
                new MetroStation { StationNumber = 2014, StationName = "Shady Grove",            Location = "Rockville", Parking = true,  BikeRacks = 32 },
                new MetroStation { StationNumber = 1660, StationName = "Rockville",              Location = "Rockville", Parking = true,  BikeRacks = 69 },
                new MetroStation { StationNumber = 9722, StationName = "Twinbrook",              Location = "Rockville", Parking = true,  BikeRacks = 68 },
                new MetroStation { StationNumber = 9722, StationName = "White Flint",            Location = "Rockville", Parking = true,  BikeRacks = 32 },
                new MetroStation { StationNumber = 8294, StationName = "Grosvenor - Strathmore", Location = "Bethesda",  Parking = true,  BikeRacks = 40 },
                new MetroStation { StationNumber = 2864, StationName = "Medical Center",         Location = "Bethesda",  Parking = true,  BikeRacks = 88 },
                new MetroStation { StationNumber = 2814, StationName = "Bethesda",               Location = "Bethesda",  Parking = false, BikeRacks = 48 },
                new MetroStation { StationNumber = 9204, StationName = "Friendship Heights",     Location = "DC",        Parking = false, BikeRacks = 50 },
                new MetroStation { StationNumber = 8648, StationName = "Tenleytown - AU",        Location = "DC",        Parking = false, BikeRacks = 20 },
                new MetroStation { StationNumber = 2522, StationName = "Van Ness - UDC",         Location = "DC",        Parking = false, BikeRacks =  9 }
            };
    
            // GET api/values
            public IEnumerable<MetroStation> Get()
            {
                return stations;
            }
    
            . . . No Change
        }
    }
  4. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  5. Type MetroSystem as the name of the file
  6. Press Enter
  7. In the empty document, type the following code:
    var appMetro = angular.module('metroSystem', []);

Routing the Web API Dependencies

When you create a Web API application, Microsoft Visual Studio creates a folder named Areas in your project. That folder contains classes and configuration files necessaray for a Web API website.

When you create a Web API application or create a Web API controller, Microsoft Visual Studio creates a static class named WebApiConfig in a file of the same name and stores it in the App_Start folder of your project. The class contains a method named Register that specifies the routing mechanism that its related webpages will follow:

using System.Web.Http;

namespace MetropolitanTransitSystem1
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

As you can see, the method indicates that the path to the data is a folder named api. To indicate this, when you create a method in the Web API controller class, you can precede it with a comment that contains api/.

The route also indicates the name of the controller. To show this, precede the method with api/ and the name of the controller. Here is an example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace MetropolitanTransitSystem1.Controllers
{
    public class MetroSystemController : ApiController
    {
        Models.MetroStation[] stations = new Models.MetroStation[]
        {
            . . . No Change
        };

        // GET: api/MetroSystem
        public IEnumerable<Models.MetroStation> GetAllStations()
        {
            return stations;
        }
    }
}

Introduction to HTTP Requests in AngularJS

Introduction to the HTTP Service

To support Ajax file communication between a browser and a webserver through the XMLHttpRequest object as it is done in JSON, AngularJS provides a service named $http. As seen with other services, to use this service, pass it as argument to the constructor of a service or controller. This can be done as follows:

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

function process($http) {

}
app.controller("ExerciseController", ['$http', process]);

The $http service is used as a function.

Practical LearningPractical Learning: Introducing the HTTP Service

Starting a Promising Service

The $http service is created as a promise. As you may be aware about promises in JavaScript programming, the $http service is created as a function that anticipates two outcomes: success and/or failure. The success is handled by the then() method (of the JavaScript's Promise object). As a result, the formula to use the $http service is:

$http(

	argument

).then(function successCallback(response){

	. . .

], function errorCallback(response){

	. . .

]);

To proceed, call the $http() function and attach a then() method to it. The then() method takes two (callback) functions as arguments. Both argument/functions are called asynchronously. Both function/arguments take an argument, the same argument, as the response to the $http() call.

The first argument/function will handle the successful outcome of the $http() function. It would be called when its argument becomes available.

The second argument/function will handle the failure (or error outcome) of the $http() function. It would be called if the call to the $http() function produces an error.

The Object of an HTTP Service

The $http() function takes one argument, which is an object. You can first create an object and pass it as argument to the function. Here is an example:

function locate($http) {
    var documentation = {};

    var file = $http(documentation);
}

Or

var arg = {};

$http(arg).then(function (){ . . . ],
                function (){ . . . ]);

Or you can define the function in the parentheses of the $http() function. Here is an example:

$http({

};).then(function (){ . . . },
         function (){ . . . });

Practical LearningPractical Learning: Creating a Promising Service

Characteristics of an HTTP Service

Introduction

The argument of the $http() function is referred to as a configuration object. It includes various pieces of information necessary to formulate a request to a webserver. We will review some of its properties (or the most commonly used ones).

The Document to Open

When using the $http() function, you must specify the path to the document you want to access. To support this, the configuration object is equipped with a property named url. Assign the relative or absolute path of the document to this property. As we saw ablove, the path to a Web API controller would be api, a forward slash, and the name of the Web API controller. Here is an example:

function locate($http) {
    var documentation = {
        url : "api/MetroSystem"
    }
    var file = $http(documentation);
}

The Method of an HTTP Service

The $http() service needs to know what HTTP method will be used to transmit the data. To support this, the configuration object is equipped with a property named method. Its value is the same as that of the METHOD attribute of the <FORM> HTML tag. This means that the value of this property can be GET, POST, etc. Here is an example:

function locate($http) {
    var documentation = {
        method: "POST",
        url : "api/MetroSystem"
    }
    var file = $http(documentation);
}

The Data to Access

To let you specify the data or message to transmit, the configuration object is equipped with a property named data. Here is an example:

function locate($http) {
    var message = "Garbage in garbage out";

    var documentation = {
        method: "POST",
        url: "api",
        data: message
    };

    var file = $http(documentation);
}

Practical LearningPractical Learning: Accessing the Data

  1. Change the document as follows:
    var appMetro = angular.module('metroSystem', []);
    
    function build($scope, $http) {
        $http({
            method: 'GET',
            url: '/api/values'
        }).
            then(function (response) {
                $scope.stations = response.data;
            },
            function (response) {
                $scope.error = "Something went wrong";
            }
            );
    }
    
    appMetro.controller("StationsController", ['$scope', '$http', build]);
  2. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  3. Change the document as follows:
    using System.Web.Optimization;
    
    namespace MetropolitanTransitSystem1
    {
        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/MetroSystem.js"));
    
                // 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/MetroSystem.css"));
            }
        }
    }
  4. In the Solution Explorer, under Controllers, double-clik HomeController.cs to open it
  5. In the class, right-click Get() and click Add View...
  6. In the Add View dialog box, make sure the View Name text is displaying Get.
    Click Add
  7. Change the document as follows:
    @{
        ViewBag.Title = "Metro Stations";
    }
    
    <h2 class="common-font bold text-center blue">Metro Stations</h2>
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="metroSystem">
        <table class="table table-striped common-font" ng-controller="StationsController">
            <tr>
                <td class="bold">Station #</td>
                <td class="bold">Station Name</td>
                <td class="bold">Location</td>
                <td class="bold">Parking</td>
                <td class="bold">Bike Racks</td>
            </tr>
            <tr ng-repeat="station in stations">
                <td>{{station.StationNumber}}</td>
                <td>{{station.StationName}}</td>
                <td>{{station.Location}}</td>
                <td>{{station.Parking}}</td>
                <td>{{station.BikeRacks}}</td>
            </tr>
        </table>
    
    </div>
  8. To preview the result, press Ctrl + F5:

    Web API Application - Accessing Data

  9. Close the browser and return to your programming environment
  10. In the Solution Explorer, right-click Scripts -> Add -> New Item...
  11. In the left frame of the Add New Item dialog box, click Web and click Markup
  12. In the middle frame, click JSON File
  13. Change the name to MetroStations
  14. Click Add
  15. Change the document as follows:
    [
      {
        "stationNumber": 2522, "stationName": "Van Ness - UDC", "location": "DC", "parkingAvailable": false, "bikeRacks": 9
      },
      {
        "stationNumber": 9741, "stationName": "Cleveland Park", "location": "DC", "parkingAvailable": false, "bikeRacks": 16
      },
      {
        "stationNumber": 1626, "stationName": "Woodley Park - Zoo / Adams Morgan", "location": "DC", "parkingAvailable": false, "bikeRacks": 8
      },
      {
        "stationNumber": 9279, "stationName": "Dupont Circle", "location": "DC", "parkingAvailable": false, "bikeRacks": 16
      },
      {
        "stationNumber": 7974, "stationName": "Farragut North", "location": "DC", "parkingAvailable": false, "bikeRacks": 16
      },
      {
        "stationNumber": 9294, "stationName": "Metro Center", "location": "DC", "parkingAvailable": false, "bikeRacks": 8
      },
      {
        "stationNumber": 1359, "stationName": "Gallery Place - Chinatown", "location": "DC", "parkingAvailable": false, "bikeRacks": 0
      },
      {
        "stationNumber": 8200, "stationName": "Judiciary Square", "location": "DC", "parkingAvailable": false, "bikeRacks": 18
      },
      {
        "stationNumber": 1802, "stationName": "Union Station", "location": "DC", "parkingAvailable": false, "bikeRacks": 23
      },
      {
        "stationNumber": 2014, "stationName": "NoMa - Gallaudet University", "location": "DC", "parkingAvailable": false, "bikeRacks": 10
      }
    ]

The Headers of a Document

The configuration object is equipped with a property named headers that holds a collection of strings or functions that represent the HTTP headers to send to the webserver. When you decide to use an $http service, the service automatically adds some preliminary HTTP headers. You can either change those ones or add your own.

The Response Type

The response type specifies the type of document that will be transmitted. To let you provide this information, the configuration object is equipped with a property named responseType. Its value is a string and it's defined in the XMLHttpRequest object that has a property of the same name. The possible values of this property are:

Here is an example:

function locate($http) {
    var message = "Garbage in garbage out";

    var documentation = {
        method: "POST",
        url: "api",
        data: message,
        responseType : 'text'
    };

    var file = $http(documentation);
}

Practical LearningPractical Learning: Accessing a JSON File

  1. Click the MetroSystem.js tab to access the JavaScript file
  2. Change the document as follows:
    var appMetro = angular.module('metroSystem', []);
    
    function display($scope, $http) {
       $http({
            method: 'GET',
            url: '/Scripts/MetroStations.json',
            headers: { 'Content-Type': 'application/json' },
            responseType: 'json'
    
        }).
            then(function (response) {
                $scope.stations = response.data;
            },
            function (response) {
                $scope.error = "The file could not be read";
            }
        );
    }
    
    appMetro.controller("StationsController", ['$scope', '$http', display]);
  3. In the Solution Explorer, under Views and under Home, double-click Get.cshtml to access the file
  4. Change the document as follows:
    @{
        ViewBag.Title = "Metro Stations";
    }
    
    <h2 class="common-font bold text-center blue">Metro Stations</h2>
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="metroSystem">
        <table class="table table-striped common-font" ng-controller="StationsController">
            <tr>
                <td class="bold">Station #</td>
                <td class="bold">Station Name</td>
                <td class="bold">Location</td>
                <td class="bold">Parking</td>
                <td class="bold">Bike Racks</td>
            </tr>
            <tr ng-repeat="station in stations">
                <td>{{station.stationNumber}}</td>
                <td>{{station.stationName}}</td>
                <td>{{station.location}}</td>
                <td>{{station.parkingAvailable}}</td>
                <td>{{station.bikeRacks}}</td>
            </tr>
        </table>
    
    </div>
  5. To execute the project and see the result, press Ctrl + F5:

    Web API Application - Accessing Data

  6. Close the browser and return to your programming environment

HTTP Service Shortcuts

To make it easy to formulate an HTTP request to the webserver, the $http object provides some shortcuts depending on the type of METHOD you want to use. Some of the shortcuts are $http.get() and $http.post(). The formulas to use them are:

$http.get(document-url, config).then(successCallback, errorCallback);
$http.post(document-url, data, config).then(successCallback, errorCallback);

In all cases, the first argument, which is the path to the document you want to transmit, is required. The second argument can be the data property or the other options we reviewed previously. Here is an example:

function display($scope, $http) {
    $http.get('MetroStations.json').
        then(function (response) {
            $scope.stations = response.data;
        },
        function (response) {
            $scope.error = "The file could not be read";
        }
    );
}

var appMetro = angular.module('metroSystem', []);
appMetro.controller("StationsController", ['$scope', '$http', display]);

ApplicationPractical Learning: Ending the Lesson


Previous Copyright © 2017-2019, FunctionX Next