Click here to Skip to main content
15,392,813 members
Articles / Web Development / HTML
Article
Posted 9 Feb 2015

Stats

68.3K views
68 bookmarked

Introduction to AngularJS and WebAPI

Rate me:
Please Sign up or sign in to vote.
4.83/5 (21 votes)
9 Feb 2015CPOL6 min read
The article covers the basic architecture of AngularJS and how to connect it to a WebAPI.

Prerequisites

  • Javascript
  • C#
  • MVC
  • Visual Studio 2013 (Installed)

 

What is AngularJS? (Wiki)

AngularJS, commonly referred to as Angular, is an open-source web application framework maintained by Google and a community of individual developers and corporations to address many of the challenges encountered in developing single-page applications. Its goal is to simplify both development and testing of such applications by providing a framework for client-side model–view–controller (MVC) architecture.


Is Angular the right tool for your project?

  1. Do you have a lot of frontend data manipulation?
  2. Do you have less than 2000 records per page?
  3. You want to build a Single Page Application?

If your answer is yes, then I encourage you to use Angular.   The MVC architecture helps you write clean, maintainable, and reusable code.  When records exceed 2000, Angular becomes slow, so it’s discouraged to use it.

Where does Angular run?

Since Angular is a JavaScript framework, it runs on the client.  Let me say that again, it runs on the client NOT on the server.

Image 1

 

What about WebAPI?

This is what happened till now.

  1. Client requested your website
  2. Client got the related HTML,CSS, JavaScript (Including Angular)
  3. Angular is now running on Client listening and responding to events (click, state change etc..)

At this point life is beautiful, but we forgot to mention the small part where we fetch the data from the database.  That’s the job of no other than WebAPI!  Since Angular is a JavaScript Framework, naturally the most convenient way to read data is a JavaScript object (JSON, JavaScript Object Notation).  WebAPI is a RESTful web service that just happens to return JSON (the luck!), it runs on the Server and waits for HTTP request (POST,GET …).  Its job is to fetch data from the database and return it to the client as JSON (remember Angular wants the data as JSON).

Image 2

HTTP POST/PUT and GET

  • Use “GET” when you want to read (select) from the database.
  • Use “POST/PUT” when you want to write (insert, update) to the database.


POST and GET Security

POST is NOT more secure than GET.  Both are visible for an attacker…

 

The full picture

Image 3

 

The red arrow represents the first phase.

  1. As noted before, the user calls your website (1)
  2. Your server response with the related HTML, CSS, and JavaScript (2)
  3. Angular starts running on the client side


The blue arrow represents the second phase

  1. Angular realizes it needs data from the database so it asks the WebAPI to provide this data (3)
  2. WebAPI goes to the database and asks for the data (4)
  3. Database Return the data (5)
  4. WebAPI reformats that data as JSON and sends it to Angular (6)

 

Angular, Getting our Hands Dirty!

In Visual Studio 2013, click on

  1. Click on "File"
  2. New => "Project"
  3. Choose "Web" => ""ASP.NET Web Application" => "Ok"
  4. Choose "Empty" => "change authentication" and remove authentication
  5. click on "Ok"

Image 4Image 5

Now, create all the files and directories to have the below project structure.
Download the following libraries jQuery, Angular, Ui-Router, Bootstrap (not required) and add them to the project as seen in the below image.

Image 6

 

 

Note we have an HTML file called Index, this will act like a MasterPage in ASP.  Thus, Index.html will hold all the JavaScript and CSS references. So let’s dig into Index.html

/Index.html

<!DOCTYPE html>
<html ng-app="app"> <!-- this tell Angular to run -->
<head>
    <title>Angular + WebAPI</title>

    <script src="./Scripts/jquery.js"></script>
    <script src="./Scripts/angular.js"></script>
    <script src="./Scripts/angular-ui-router.js"></script>

    <script src="./App/app.js"></script>
    <script src="./App/controllers.js"></script>

    <script src="./Scripts/bootstrap.min.js"></script>

    <link rel="stylesheet" href="./Style/CSS/bootstrap.css" />
    <link rel="stylesheet" href="./Style/CSS/style.css" />

</head>
<body>
    <nav class="navbar navbar-default">
        <div class="container">
            <ul class="nav navbar-nav">
                <li>
                    <a href="#/">
                        Home
                    </a>
                </li>
                <li>
                    <a href="#/movies">
                        Movies
                    </a>
                </li>
            </ul>
        </div>
    </nav>

    <div class="container">
        <!--
            Note the below ui-view attribute, not the id.
            The content of the div will be replaces by
            the view that is stated inside app.js            
        -->
        <div id="ui-view" ui-view>
        </div>
    </div>
</body>
</html>

 

/App/app.js

// Declares how the application should be bootstrapped. See: http://docs.angularjs.org/guide/module
angular.module('app',
    [
        // Dependency Inject Goes inside this array
        'ui.router',  // we inject/load ui-router for routing
        'app.controllers', // we inject/load the controllers
    ]
)
    .config(['$stateProvider',
        function ($stateProvider) {
            // UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router

            // our routers, self explanatory
            $stateProvider
                .state('home', {
                    url: '/',
                    templateUrl: './View/Home.html'
                })
                .state('movies', {
                    url: '/movies',
                    templateUrl: './View/Movies.html',
                    controller: 'MoviesController'
                })
                .state('otherwise', {
                    url: '*path',
                    templateUrl: '/View/Error.html',
                    controller: 'ErrorCtrl'
                });
        }]

        );


/App/controllers.js

//we initialize the module name to 'app.controllers'
// app.js will search for a module called 'app.controllers' and will find this one and inject it
angular.module('app.controllers', [])

.controller('MoviesController', function ($scope)
{
    // this will do for now
});

 

/View/Movies.html

<div class="row">
    <h2>Movies</h2>
</div>

<div class="row">
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Director</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    1
                </td>
                <td>
                    Fight Club
                </td>
                <td>
                    David Fincher
                </td>
            </tr>
            <tr>
                <td>
                 2
                </td>
                <td>
                    Into The Wild
                </td>
                <td>
                    Sean Penn
                </td>
            </tr>
        </tbody>
    </table>
</div>

 

Adding the project to the IIS

 

Press the Windows Key and search for “IIS” which stands for (Internet Information Service). If you don’t have it you might need to install it.

  1. Expand “Sites”
  2. Right click on “Default Web Site” => and choose “Add Application”
  3. In the Alias, enter “angular”
  4. Point the physical path to your Project (not solution) directory.
    X:\ CodeProjectAngular\CodeProjectAngular

Image 7

Open your favorite browser and go to :
http://localhost/angular/#/movies

Image 8


As you might have noticed the Movies are hard coded inside the view.  Next, we will remove the hardcoding from the View and put it inside the controller.

/App/controllers.js

angular.module('app.controllers', [])

    .controller('MoviesController', function ($scope)
    {
        $scope.movies =
        [
            { Id: 1, Name: "Fight Club",Director: "David Fincher" },
            { Id: 2, Name: "Into The Wild", Director: "Sean Penn" },
            { Id: 3, Name: "Dancer in the Dark", Director:"Lars von Trier " }
        ];

    });

What’s with that $scope thingy?

Angular is more than MVC its MVVM as well.  Anything that starts with ‘$’ is an internal Angular object.  So $scope is an internal object, so you are wondering what does it do? Think of $scope as a public Static Class, there is one instance of it and if you change it in one place it will be changed in all the rest.  Since the Controller reads/writes inside the $scope and the View reads/writes inside the same $scope then any change will be available for both.

Image 9

 

As you noticed, there is a double binding between View<=>$scope and Controller <=> $scope.  Thus, when $scope is updated, both the Controller and View are updated.

 

How to read $scope in the View

Inside the controller, we initialized $scope.movies as an array and populated it.  Inside the View, we would like to loop the array and render the objects.  Angular extends HTML and allows us to write loop functions inside HTML.  When accessing the $scope inside the View, we omit the $scope.  So to access $scope.movies inside the view we just say “movies”.

/Views/Movies.html

<div class="row">
    <h2>Movies</h2>
</div>

<div class="row">
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Director</th>
            </tr>
        </thead>
        <tbody>          
            <!-- foreach movie, a new tr will be created -->
            <tr ng-repeat="movie in movies"> <!-- Similar to a foreach loop, C#: foreach(var movie in movies ){...} -->
                <td>
                    {{movie.Id}}
                </td>
                <td>
                    {{movie.Name}}
                </td>
                <td>
                    {{movie.Director}}
                </td>
            </tr>
        </tbody>
    </table>
</div>

What did we just do?

We moved the hardcoded movies from the View to the Controller, and added an Angular looping function to loop over the array and display the data.

WebAPI to the rescue!

Because Angular runs on the client, it’s not capable of fetching data from the database.  This is where WebAPI comes into play.  So the next step is to fetch the Javascript Object from WebAPI (database).

Creating a WebAPI Project

  1. Right click on the solution
  2. Add
  3. New Project
  4. Choose WebAPI
  5. Change Authentication => No Authentication
  6. Name it "CodeProjectAngular.WebAPI"

Image 10Image 11

Configure WebAPI to return JSON

Go to App_Start/WebApiConfig.cs and add the following code:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

The above code will not return a strict "application/json" response, if you want a strict "application/json" respond you can use the below.  

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
config.Formatters.Remove(config.Formatters.XmlFormatter);
json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;


Creating the return type object

Create a folder named DTO (data transfer object) and create a new class called “MoviesDTO”, place the following code to /DTO/MoviesDTO.cs

public class MoviesDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Director { get; set; }
}

You will notice that the MoviesDTO has the same structure as the JavaScript Object we hard coded earlier.  Thus, MoviesDTO has a property of Id, Name, and Director.  When we return this Object it will be automatically Serialized to JSON.  Next we will write the controller that returns this Object.

 

Adding the WebAPI Controller

  1. Right click on the Controller Folder
  2. Add  => Controller
  3. Choose Web API 2 Controller – Empty
  4. Call it MoviesController

Now Paste the Below Code to /Controllers/MoviesController.cs

public IEnumerable<MoviesDTO> Get()
{
    // this list should be fetched from the DB
    // you can use Entity Framework (EF)
    // for best practice, do not use EF inside the controller.
    // Instead use EF inside a class that implements an interface

    List<MoviesDTO> movies = new List<MoviesDTO>
        {
            new MoviesDTO { Id = 1, Name = "Fight Club", Director = "David Fincher" },
            new MoviesDTO { Id = 2, Name = "Into The Wild", Director = "Sean Penn" },
            new MoviesDTO { Id = 3, Name = "Dancer in the Dark", Director = "Lars von Trier" },
            new MoviesDTO { Id = 4, Name = "WebAPI", Director = "Cool!" }
        };

    return movies;
}

Adding the WebAPI to the IIS

Press the Windows Key and search for “IIS” which stands for (Internet Information Service). If you don’t have it you might need to install it.

  1. Expand “Sites”
  2. Right click on “Default Web Site” => and choose “Add Application”
  3. In the Alias, enter “angular-webapi”
  4. Point the physical path to your WebAPI directory.
    X:\ CodeProjectAngular\CodeProjectAngular.WebAPI

Image 12Image 13

 

Testing your WebAPI

Open your favorite browser and enter the following URL:
http://localhost/angular-webapi/api/movies

Image 14

 

Putting it all together!

All we have to do now is to call this WebAPI from Angular.  Note that we injected “$http” to the controller and we will be using that to call the WebAPI.

/App/controllers.js

angular.module('app.controllers', [])

    .controller('MoviesController', function ($scope, $http)
    {
        $http({
            method: 'GET',
            url: 'http://localhost/angular-webapi/api/movies'
        })
         .success(function (data)
         {             
             $scope.movies = data;
         });       

    });

 

Voilà! We are done!

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Serge Jerkezian
Software Developer (Senior)
Lebanon Lebanon
Passionate Software Developer with over 3 years of experience in the field. In love with the girl next door and the MVC architecture.

Comments and Discussions

 
QuestionMy vote of 5 Pin
Member 116832514-Aug-17 5:33
MemberMember 116832514-Aug-17 5:33 
QuestionConfused about text/html Pin
Scott Fraley26-Mar-15 12:02
MemberScott Fraley26-Mar-15 12:02 
AnswerRe: Confused about text/html Pin
Serge Jerkezian3-Apr-15 23:02
MemberSerge Jerkezian3-Apr-15 23:02 
QuestionGreat Work Pin
Member 446753720-Feb-15 8:46
MemberMember 446753720-Feb-15 8:46 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun9-Feb-15 21:29
MemberHumayun Kabir Mamun9-Feb-15 21:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.