Click here to Skip to main content
13,145,068 members (69,197 online)
Click here to Skip to main content
Add your own
alternative version

Stats

61K views
5.9K downloads
60 bookmarked
Posted 20 Nov 2014

Single Page Application using AngularJS and Web API and Responsive using Bootstrap.

, 20 Nov 2014
Rate this:
Please Sign up or sign in to vote.
This article describe the AngularJS JavaScript framework and shows how to use it to develop a Single Page Application.

This article describes on the following topics.

  • What is AngularJS?
  • Design Pattern used for AngularJS.
  • Two way data binding.
  • Routing.
  • Sample project and description.

What is AngularJS?

AngularJS is a structural JavaScript framework to build a Single Page Application (SPA). AngularJS is a complete client-side framework which provides almost all the services such as data binding, templating, routing, validation, testing, dependency injection and resource for CRUD operations etc.

Design Pattern used for AngularJS

AngularJS uses MVC design pattern to structure the code. In MVC data and code are separate in three components Model, View and Controller.

Model contains the application data. For example

var products = [
    {'name': 'Product 1',
     'description': 'Description of Product 1'},
    {'name': 'Product 2',
     'description': 'Description of Product 2'},
    {'name': 'Product 3',
     'description': 'The 'Description of Product 3'}
  ];

View contains the html with declarative data binding.

<ul>
    <li ng-repeat="product in products">
      <span>{{product.name}}</span>
      <p>{{product.description}}</p>
    </li>
</ul>

Controller is used as a mediator between Model and View. It contains data model and event handler. For example

productApp.controller('ProductListCtrl', function ($scope) {
  $scope.price=100;
  $scope.AddProduct= function(product)
  {
    //code goes here
  };
});

Two way Data binding in AngularJS

One of the powerful features of AngularJS is two way data binding. In two way data binding, if user changes the UI value then AngularJS automatically update the underlying data model. In the reverse way if underlying data model is changed then Angular automatically update the UI. It reduces the code writing to update the DOM.

The following picture shows the two way data binding.

Routing

Using Routing we can partition the Index page in multiple view templates and can bookmark the url in browser for different view template. For routing Angular uses it’s built in "ngRoute" module and $routeProvider provider. The configuration for routing for the sample project is shown below.

var productcatApp = angular.module('productcatApp', [
'ngRoute',
'productcatControllers',
'productcatServices'
]);
productcatApp.config(['$routeProvider',
function ($routeProvider) {
    $routeProvider.
    when('/products', {
        templateUrl: 'Home/ProductList',
        controller: 'ProductListCtrl'
    }).
    when('/products/:productId', {
        templateUrl: 'Home/ProductDetail',
        controller: 'ProductDetailCtrl'
    }).
    when('/productNew', {
        templateUrl: 'Home/ProductNew',
        controller: 'ProductNewCtrl'
    }).
    when('/productUpdate/:productId', {
        templateUrl: 'Home/ProductUpdate',
        controller: 'ProductUpdateCtrl'
    }).
    otherwise({
        redirectTo: '/products'
    });
}]);

For every route there is a Web API url to extract view template and a controller to bind data with the extracted template.

Sample project with description

Description: This sample project is about how to display, add, edit and delete product from a product list.

The database diagram from this sample project is shown below.

Index page

Index page is uses like a master page and contains a container which is always updated with the called template.

<div id="contentWrapper">
    <div class="container">
        <div ng-view></div>
    </div>
</div>

When user route to a new url then the content of the div with Angular directive ng-view is replaced with the new html template.

The sample project performs the following steps.

Step 1: Shows the list of products.

The html template to display the list of products is shown below. File ProductList.cshtml contains this template in server.

<div class="row">
    <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
        <button class="btn btn-primary btn-lg btn-block" ng-click="newProduct()">New</button>
    </div>
</div>
<div class="row" ng-repeat="product in products">
    <div class="col-xs-6 col-sm-8 col-md-8 col-lg-8">
        <a href="#/products/{{product.id}}">{{product.name}}</a>
    </div>
    <div class="hidden-xs col-sm-1 col-md-1 col-lg-1">
        <a href="#/products/{{product.id}}"><img class="img-thumbnail img-responsive" 

          ng-src="{{product.imageUrl}}"/></a>
    </div>
    <div class="col-xs-3 col-sm-2 col-md-2 col-lg-2">
        <a class="btn btn-large btn-success" href="#/productUpdate/{{product.id}}">Update</a>
    </div>
    <div class="col-xs-3 col-sm-2 col-md-2 col-lg-2">
        <button class="btn btn-large btn-success" ng-click="deleteProduct(product)">Delete</button>
    </div>
</div>

In the above template ng-repeat="product in products" is used to loop the products list and {{product.name}} syntax is used for two way data binding. And class="col-xs-6 col-sm-6 col-md-6 col-lg-6" syntax is used for bootstrap.

The Routing part to call this template is

when('/products', {
    templateUrl: 'Home/ProductList',
    controller: 'ProductListCtrl'
})

When url http://localhost/#/products is requested then Angular calls an ajax request to the Web API url 'Home/ProductList' for a new html template and after return Angular bound the Controller 'ProductListCtrl' with the new template for data.

The Controller for this Template is

var productcatControllers = angular.module('productcatControllers', []);
productcatControllers.controller('ProductListCtrl', ['$scope', '$routeParams', '$location', 
                                 '$route', 'productService',
function ($scope, $routeParams, $location, $route, productService) {
    productService.query(function (data) {
        $scope.products = data;
    });
    $scope.deleteProduct = function (product) {
        debugger;
        productService.delete({ id: product.id }, function () {
            $route.reload();
        });
    }
    $scope.newProduct = function () {
        $location.path('/productNew');
    }
}]);

Here Angular Resource module is used to extract data from server and delete a product from server. Here newProduct() function is used to redirect to the New Product add page.

The configuration for Resource module is

var phonecatServices = angular.module('productcatServices', ['ngResource']);
phonecatServices.factory("productService", function ($resource) {
    return $resource(
        "/api/Product/:id",
        { id: "@id" },
        {
            "update": { method: "PUT" }

        }
    );
});

The above statement creates a service with name productService and passes a $resource service as a parameter which is used for database operations.

The server side Web API code is

public HttpResponseMessage GetProducts()
        {
            var collection = db.Products.Select(x => new
            {
                id = x.id,
                name = x.name,
                imageUrl = x.imageUrl
            });
            var yourJson = new JavaScriptSerializer().Serialize(collection);
            var response = this.Request.CreateResponse(HttpStatusCode.OK);
            response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
            return response;
        }

Step 2: Add a new product.

ProductNew.cshtml page in server contains html template for this UI.

The Routing part to call this template is

when('/productNew', {
    templateUrl: 'Home/ProductNew',
    controller: 'ProductNewCtrl'
})

The Controller for this Template is

productcatControllers.controller('ProductNewCtrl', ['$scope', '$routeParams', '$location', 
                     'productService',
function ($scope, $routeParams, $location, productService) {
    $scope.product = { name: "", imageUrl: "", ProductDetail: { number: 0, price: 0.0, 
                       description: "", companyName: "" } };
    $scope.addNewProduct = function (product) {
        productService.save(product, function () {
            $location.path('/products');
        });
    }
    $scope.cancelNewProduct = function () {
        $location.path('/products');
    }
}]);

In the about controller, save function of productService service is used to save a product in database and after save it redirect to the product list page.

The server side Web API code is

public HttpResponseMessage PostProduct(Product product)
        {
            if (ModelState.IsValid)
            {
                db.Products.Add(product);
                db.ProductDetails.Add(product.ProductDetail);
                db.SaveChanges();
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }

Step 3: Edit a product.

ProductUpdate.cshtml page in server contains html template for this UI.

The Routing part to call this template is

when('/productUpdate/:productId', {
    templateUrl: 'Home/ProductUpdate',
    controller: 'ProductUpdateCtrl'
})

The Controller for this Template is

productcatControllers.controller('ProductUpdateCtrl', ['$scope', '$routeParams', 
                                 '$location', 'productService',
function ($scope, $routeParams, $location, productService) {
    productService.get({ id: $routeParams.productId }, function (data) {
        $scope.product = data;
    });
    $scope.updateProduct = function (product) {
        var post = productService.get({}, { id: product.id }, function (data) {
            debugger;
            post.name = product.name;
            post.imageUrl = product.imageUrl;
            post.ProductDetail.number = product.ProductDetail.number;
            post.ProductDetail.price = product.ProductDetail.price;
            post.ProductDetail.description = product.ProductDetail.description;
            post.ProductDetail.companyName = product.ProductDetail.companyName;
            productService.update(post, function () {
                $location.path('/products');
            });
        });
    }
    $scope.cancelUpdateProduct = function () {
        $location.path('/products');
    }
}]);

In the about controller, update function of productService service is used to update a product in database and after update it redirect to the product list page.

The server side Web API code is

public HttpResponseMessage PutProduct(int id, Product product)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
            if (id != product.id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
            Product productEntity = db.Products.Where(p => p.id == product.id).FirstOrDefault();
            productEntity.name = product.name;
            productEntity.imageUrl = product.imageUrl;
            productEntity.ProductDetail.number = product.ProductDetail.number;
            productEntity.ProductDetail.price = product.ProductDetail.price;
            productEntity.ProductDetail.description=product.ProductDetail.description;
            productEntity.ProductDetail.companyName = product.ProductDetail.companyName;
            db.Entry(productEntity).State = EntityState.Modified;
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        }

Step 4: Display the product details.

ProductDetail.cshtml page in server contains html template for this UI.

The Routing part to call this template is

when('/products/:productId', {
    templateUrl: 'Home/ProductDetail',
    controller: 'ProductDetailCtrl'
})

The Controller for this Template is

productcatControllers.controller('ProductDetailCtrl', ['$scope', '$routeParams', 
                                 '$location', 'productService',
function ($scope, $routeParams, $location, productService) {
    productService.get({ id: $routeParams.productId }, function (data) {
        $scope.product = data;
    });
    $scope.backToProduct = function () {
        $location.path('/products');
    }
}]);

In the about controller, get function of productService service is used to extract a product by id from database and assign the data with product Model.

The server side Web API code is

public HttpResponseMessage GetProduct(int id)
{
    var product = db.Products.Include("ProductDetail").Where(p => p.id == id).Select(x => new
    {
        id = x.id,
        name = x.name,
        imageUrl = x.imageUrl,
        ProductDetail = new { id = x.ProductDetail.id, number = x.ProductDetail.number, 
                        price = x.ProductDetail.price, description = x.ProductDetail.description,
                        companyName = x.ProductDetail.companyName }
    }).FirstOrDefault();
    var json = new JavaScriptSerializer().Serialize(product);
    var response = this.Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(json, Encoding.UTF8, "application/json");
    return response;
}

Conclusion

In conclusion I can say, now a day’s Angular is a popular JavaScript framework to develop a Single Page Application. Please download the attach zip file for sample project. It needs VS2012 and SQL Server 2008 to run.

 

 

 

License

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

Share

About the Author

Khademul Basher
Team Leader Brain Station-23
Bangladesh Bangladesh
I am a Software Engineer and expert in Windows platform both for Web and Device. I develop software both for Web and devices. I like the new technologies like NodeJS and some JavaScript frameworks like AngularJS, KnockoutJS, BackboneJS. I am a quick learner and like to research and innovate.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
Questionwant step by step explanation. Pin
Member 1304972214-Mar-17 4:27
memberMember 1304972214-Mar-17 4:27 
QuestionVery cool code sample about Bootstrap/AngularJS Pin
Pham Dinh Truong19-Oct-16 22:15
memberPham Dinh Truong19-Oct-16 22:15 
BugProductInfo-noexe.zip Pin
aoinal12-Jun-16 23:17
memberaoinal12-Jun-16 23:17 
QuestionMVC and Design Patterns Pin
tatran.eu@gmail.com24-May-15 11:40
membertatran.eu@gmail.com24-May-15 11:40 
GeneralMy vote of 5 Pin
Accioly26-Nov-14 15:55
memberAccioly26-Nov-14 15:55 
SuggestionYou just need to specify the smallest grid Pin
rtpHarry26-Nov-14 11:33
professionalrtpHarry26-Nov-14 11:33 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun21-Nov-14 1:08
memberHumayun Kabir Mamun21-Nov-14 1:08 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.170915.1 | Last Updated 21 Nov 2014
Article Copyright 2014 by Khademul Basher
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid