Introduction
In AngularJS and REST API, Part 1, I introduced some AngularJS concepts and demonstrated a REST API to fetch items from a database table and display them on a web page using AngularJS. For part 2, I've created an application that displays information about airports on a web page using a REST API and AngularJS. Two approaches will be used to display the data. The first approach will be similar to that used in AngularJS and REST API, Part 1, and the second approach will use the AngularJS md-autocomplete directive. As with the previous article, it is assumed that the reader is familiar with JavaScript, ASP.NET MVC, C#, Entity Framework, HTML, JSON, and CSS. And now you are familiar with AngularJS. You will also need a key to access Bing maps, available for free from The Bing Maps Developer Center. (This article only uses the Bing map API; Steve Wellens has a good article comparing Google and Bing map APIs.)
Create the Table
My first objective with this project is to use Entity Framework Database First model in order to use an existing database table of airport data called Airport
. To create the Airport
table, in the CreateAirportTable.sql script change [YOUR_DATABASE_NAME]
to the name of your database and then execute the CreateAirportTable.sql script in SQL Server Management Studio (SSMS). After the table has been created, you can populate it by executing the AirportDataBaseLosAngeles.sql script in SSMS. The script should insert 163 rows, each one with data for a single airport. In order to keep the Airport
table to a reasonable size for demonstration purposes, this is a small portion of available data that I obtained from https://openflights.org/data.html. You can also get airport data from other sources such as the FAA website.
To add an existing table to a project, you add an ADO.NET Entity Data Model to the project. Since I have already done this, all you will need to do is change the AirportEntities
connection string in Web.config to point to your database by setting [YOUR_SERVER_NAME]
and [YOUR_DATABASE_NAME]
the name of your server and database, respectively. (Note there are two different Web.config files, but only one has the AirportEntities
connection string.) The following is a snippet that shows what the AirportEntities
connection string
looks like:
<connectionStrings>
<add name="AirportEntities" ... connectionString="source=[YOUR_SERVER_NAME];
initial catalog=[YOUR_DATABASE_NAME] ... />
</connectionStrings>
Using the Code
Download the AirportDatabaseProject.zip file and extract it. It consists of a directory called AngularJS_REST_API_AirportLocator which contains the JavaScript and HTML files, two SQL script files, and the Visual Studio 2015 project AirportsAPI
. Open the AirportsAPI
project with Visual Studio. Build it by pressing F6; the project should build successfully with no errors.
Press F5 to run the AirportsAPI
project in debug mode. You might want to place a breakpoint in this key portion of the C# code, the controller, in AirportController.cs. This is the REST API to fetch all the airports from the Airports
table.
[Route("api/Airports")]
[HttpGet]
public IEnumerable<Airport> GetAirports()
{
try
{
var db = new AirportEntities();
var airports = db.Airports.ToList().OrderBy(a => a.Name);
return airports;
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(String.Format("Error: {0}", ex.Message));
return null;
}
}
When the AirportsAPI
project is running, if you have the curl utility installed, you can execute the API like this: curl -X GET http://localhost:55213/api/Airports
which should return all of the airports as a JSON string. (The "55213
" in the URL is simply the port id and is set via the Project URL in the project's properties.) There is also an API to fetch a single airport by its ID, curl -X GET http://localhost:55213/api/Airport/23
. Note the singular Airport
in the URL, and that the id of 23
is included at the end of the URL and thus is fetching the airport with an ID of 23
from my database, Long Beach (where I learned to fly). You should get this JSON as response:
{"ID":23,"VendorID":3582,"Name":"Long Beach /Daugherty Field/ Airport",
"City":"Long Beach","Country":"United States","IATA":"LGB","ICAO":"KLGB"
-118.152000,"Altitude":60,"Timezone":-8.00,"DST":"A","TZ":"America/Los_Angeles",
"Type":"airport","Source":"OurAirports"}
Using ng-repeat and ng-click
Using the same technique as described in AngularJS and REST API, Part 1, there are two main JavaScript files to invoke the REST API: app\airports\airportsController.js and app\airports\remoteAirportsService.js. Right-click on AirportLocaterApproach1.html, and select "Open With Chrome." (You might also want to open Chrome's "Developer Tools" window in order to see any error messages.) Clicking on the "All Airports" button calls the fetchAirports
method which in turn invokes the api/Airports API described above. This first approach uses the AngularJS ng-repeat
directive and a filter to select all airports whose name contains the filter string, "long
", as shown in the following screen shot.
The matching airports are displayed as HTML buttons and the AngularJS directive ng-click
causes clicking on the button to call the JavaScript method showMap
with the Airport ID:
<input type="button" ng-click="showMap(singleAirport.ID)"
value="{{ singleAirport.Name }}" class="btn-success" data-toggle="tooltip"
title="Single Airport" id="singleairport">
Clicking on the "Long Beach /Daugherty Field/ Airport" button displays a map of Long Beach airport (note how Bing maps provides buttons to zoom in and out):
Using AngularJS Autocomplete
My second objective was to use the AngularJS md-autocomplete directive which displays a drop-down of all matches to a custom query. In the image below, all airports that contain "Lo
" in the airport name or city name are displayed.
To see this in action, first edit scripts\AutoCompleteController.js and replace 'YOUR CREDENTIALS
' with your Bing key. In Windows explorer, right-click on AirportLocaterApproach2.html, and select "Open With Chrome." (You might also want to open Chrome's "Developer Tools" window in order to see any error messages.) The page should appear like the image above, consisting essentially of a text box from which you can search for an airport by name or city. After you have selected the airport, the name, city, IATA and ICAO codes, latitude, longitude, altitude and time zone will be displayed in an HTML table. A map showing the airport will also be displayed as illustrated in the image at the beginning of this article.
The key method in the controller AutoCompleteController
in AutoCompleteController.js is called filterFn
which returns true
if an airport in the list of airports obtained via the call to the REST API contains the query string. (In the code, I have comments describing how to return only airports that begin with the query string, though I think that is less useful in this case.)
I've utilized Steve Wellens' DragEnd
method to give the ability to drag the markers to determine runway length. In the image at the beginning of this article, you can see the distance between the markers, and hence the length of Long Beach Airport's runway 25R/7L, is over 5,000 feet.
Version 1.0.0.0