Share via


Visual Studio: Create Web API With Angular JS

In this article we will learn about CRUD operations in Web API using Angular JS. We will use Visual Studio 2015 to create a Web API and performs the operations. In this project we are going to create a *database *and a table  tbl_Subcribers which actually contains a list of data. Here we will use Angular JS for all of our client side operations. If you are new to Web API, please read how to retrieve the data from database using Web API here. I am going to explain the complete process in a step by step manner. I hope you will like this.

Download the source code

You can always download the source code here: Web API and Angular JS

Background

Yesterday I have got a call from one of my follower. He asked me about Web API, I have explained him what are all the things I know about the Web API. But he was not convinced with the information I shared through phone. At last he asked me to write an article about Web API in a simple manner. So I agreed to do the same. Here I am dedicating this article to him. I hope he can find this useful.

What is a Web API?

A Web API is a kind of a framework which makes building HTTP services easier than ever. It can be used almost everywhere including wide range of clients, mobile devices, browsers etc. It contains normal MVC features like Model, Controller, Actions, Routing etc. Support all HTTP verbs like POST, GET, DELETE, PUT.

http://sibeeshpassion.com/wp-content/uploads/2015/10/Why-Web-API.png

Why Web API

Image Courtesy : blogs.msdn.com

http://sibeeshpassion.com/wp-content/uploads/2015/10/Why-Web-API1-e1446290457816.png

Why Web API

Image Courtesy : forums.asp.net

Using the code

We will create our project in Visual Studio 2015. To create a project click File-> New-> Project. And select Web API as template.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Web-API-Template-1024x576.png

Web API Template

Once you have created a new project, your solution explorer will look like this.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Web-API-With-Angular-JS-Solution-Explorer.png

Web API With Angular JS Solution Explorer

As I said, we are going to use Angular JS for all of our client side operations. So the next thing we need to do is, installing the Angular JS from NuGet packages.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Installing-Angular-JS-1024x576.png

Installing Angular JS

Install Angular JS

Now we will create a control in our project.

http://sibeeshpassion.com/wp-content/uploads/2015/08/CRUD_in_MVC_Using_Web_API_Adding_Control.png

CRUD_in_MVC_Using_Web_API_Adding_Control

Now will create a database. Here I am using SQL Server Management Studio With SQL Server Express.

Create Database

Below is the query to create a database.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 USE [master] GO   /****** Object:  Database [SibeeshPassion]    Script Date: 06-02-2016 08:18:42 PM ******/ CREATE DATABASE [SibeeshPassion]  CONTAINMENT = NONE  ON  PRIMARY ( NAME = N, FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\SibeeshPassion.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )  LOG ON ( NAME = N'SibeeshPassion_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\SibeeshPassion_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO   ALTER DATABASE [SibeeshPassion] SET COMPATIBILITY_LEVEL = 120 GO   IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) begin EXEC [SibeeshPassion].[dbo].[sp_fulltext_database] @action = 'enable' end GO   ALTER DATABASE [SibeeshPassion] SET ANSI_NULL_DEFAULT OFF GO   ALTER DATABASE [SibeeshPassion] SET ANSI_NULLS OFF GO   ALTER DATABASE [SibeeshPassion] SET ANSI_PADDING OFF GO   ALTER DATABASE [SibeeshPassion] SET ANSI_WARNINGS OFF GO   ALTER DATABASE [SibeeshPassion] SET ARITHABORT OFF GO   ALTER DATABASE [SibeeshPassion] SET AUTO_CLOSE OFF GO   ALTER DATABASE SET AUTO_SHRINK OFF GO   ALTER DATABASE [SibeeshPassion] SET AUTO_UPDATE_STATISTICS ON GO   ALTER DATABASE [SibeeshPassion] SET CURSOR_CLOSE_ON_COMMIT OFF GO   ALTER DATABASE [SibeeshPassion] SET CURSOR_DEFAULT  GLOBAL GO   ALTER DATABASE [SibeeshPassion] SET CONCAT_NULL_YIELDS_NULL OFF GO   ALTER DATABASE [SibeeshPassion] SET NUMERIC_ROUNDABORT OFF GO   ALTER DATABASE [SibeeshPassion] SET QUOTED_IDENTIFIER OFF GO   ALTER DATABASE [SibeeshPassion] SET RECURSIVE_TRIGGERS OFF GO   ALTER DATABASE [SibeeshPassion] SET  DISABLE_BROKER GO   ALTER DATABASE [SibeeshPassion] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO   ALTER DATABASE [SibeeshPassion] SET DATE_CORRELATION_OPTIMIZATION OFF GO   ALTER DATABASE [SibeeshPassion] SET TRUSTWORTHY OFF GO   ALTER DATABASE [SibeeshPassion] SET ALLOW_SNAPSHOT_ISOLATION OFF GO   ALTER DATABASE [SibeeshPassion] SET PARAMETERIZATION SIMPLE GO   ALTER DATABASE [SibeeshPassion] SET READ_COMMITTED_SNAPSHOT OFF GO   ALTER DATABASE [SibeeshPassion] SET HONOR_BROKER_PRIORITY OFF GO   ALTER DATABASE [SibeeshPassion] SET RECOVERY SIMPLE GO   ALTER DATABASE [SibeeshPassion] SET  MULTI_USER GO   ALTER DATABASE [SibeeshPassion] SET PAGE_VERIFY CHECKSUM  GO   ALTER DATABASE [SibeeshPassion] SET DB_CHAINING OFF GO   ALTER DATABASE [SibeeshPassion] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GO   ALTER DATABASE [SibeeshPassion] SET TARGET_RECOVERY_TIME = 0 SECONDS GO   ALTER DATABASE [SibeeshPassion] SET DELAYED_DURABILITY = DISABLED GO   ALTER DATABASE [SibeeshPassion] SET  READ_WRITE GO

Now we can create a table and insert few data into it.

Create table in database

Below is the query to create table in database.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 USE [SibeeshPassion] GO   /****** Object:  Table [dbo].[tbl_Subscribers]    Script Date: 06-02-2016 08:21:06 PM ******/ SET ANSI_NULLS ON GO   SET QUOTED_IDENTIFIER ON GO   CREATE TABLE [dbo].[tbl_Subscribers](     [SubscriberID] [int] NOT NULL,     [MailID] [nvarchar](50) NOT NULL,     [SubscribedDate] [datetime2](7) NOT NULL, PRIMARY KEY CLUSTERED (     [SubscriberID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]   GO

Insert data to table

1 2 3 INSERT INTO [dbo].[tbl_Subscribers] ([SubscriberID], [MailID], [SubscribedDate]) VALUES (1, N'sibikv4u@gmail.com', N'2015-10-30 00:00:00') INSERT INTO [dbo].[tbl_Subscribers] ([SubscriberID], [MailID], [SubscribedDate]) VALUES (2, N'sibeesh.venu@gmail.com', N'2015-10-29 00:00:00') INSERT INTO [dbo].[tbl_Subscribers] ([SubscriberID], [MailID], [SubscribedDate]) VALUES (3, N'ajaybhasy@gmail.com', N'2015-10-28 00:00:00')

Our database seems to be ready now. Then we can go ahead and create entity in our project.

Creating entity model

To create an entity, please follows the steps shows in the below images.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-1-1024x576.png

Creating Entity Model 1

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-2-1024x576.png

Creating Entity Model 2

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-3-1024x576.png

Creating Entity Model 3

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-4-1024x576.png

Creating Entity Model 4

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-5-1024x576.png

Creating Entity Model 5

http://sibeeshpassion.com/wp-content/uploads/2016/02/Creting-Entity-Model-6-1024x576.png

Creating Entity Model 6

Now it is time to create a API controller.

Select Empty API Controller as template.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Web-API-Contoller-With-Actions-1024x713.png

Web API Contoller With Actions

Read Operation

Now you can see some actions are already created for you by default. Cool right? Now as of now we will concentrate only in retrieving the data. So please change the method Get as follows.

1 2 3 4 public IEnumerable<tbl_Subscribers> Get()         {             return myEntity.tbl_Subscribers.AsEnumerable();         }

Before the please do not forget to create an instance for your entity.

1 private SibeeshPassionEntities myEntity = new SibeeshPassionEntities();

And make sure you have added the needed namespaces with the model.

1 2 using System.Data.Entity; using WebAPIAndAngular.Models;

As you can notice that we have selected Empty API Controller instead of selecting a normal controller. There are few difference between our normal controller and Empty API Controller.

Controller VS Empty API Controller

A controller normally render your views. But an API controller returns the data which is already serialized. A controller action returns JSON() by converting the data. You can get rid of this by using API controller.

Find out more: Controller VS API Controller

Now our API is ready for action. So it is time to create an another controller and a view. Here I am creating a normal controller with Index view.

Once the view is created, we will created three JS files in the script folder.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Angular-JS-Operation-FIles.png

Angular JS Operation FIles

Now we will start our Angular JS part. If you are new to Angular JS, I strongly recommend you to check here.Angular JS Basics

Open the file Module.js and create an app.

1 2 3 4 var app; (function () {     app = angular.module("APIModule", []); })();

Here APIModule is the name of our module. Check here for more information.

Open the file Service.js and create a service as follows.

1 2 3 4 5 app.service("APIService", function ($http) {     this.getSubs = function () {         return $http.get("api/Subscriber")     } });

Here APIService is our service name which we will call from our controller. The api/Subscriber will call the Get method in our API controller.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Get-Operation-In-API-Controller-e1454772443988.png

Get Operation In API Controller

Now Open our Controller.JS and write code as below.

1 2 3 4 5 6 7 8 9 10 11 12 app.controller('APIController', function ($scope, APIService) {     getAll();     function getAll()     {         var servCall = APIService.getSubs();         servCall.then(function (d) {             $scope.subscriber = d.data;         }, function (error) {             $log.error('Oops! Something went wrong while fetching the data.')         })     } })

We are calling the getSubs function which we created in our service. Once we get the data we are assigning it to the $scope.subscriber, so that we can use it in our view.

Now the angular JS part for retrieving all data is done. Can we do the needed changes in the view now?

Updating View

Open the Index.cshtml view and change it as below.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @{     ViewBag.Title = "Welcome"; } <style>     table, tr, td, th {         border: 1px solid #ccc;         padding: 10px;         margin: 10px;     } </style>   <h2>Welcome to Sibeesh Passion's Email List</h2> <body data-ng-app="APIModule">         <div id="tblSubs" ng-controller="APIController">             <table>                 <tr>                     <th>ID</th>                     <th>Email ID</th>                     <th>Subscribed Date</th>                 </tr>                 <tbody data-ng-repeat="sub in subscriber">                     <tr>                         <td>{{sub.SubscriberID}}</td>                         <td>{{sub.MailID}}</td>                         <td>{{sub.SubscribedDate}}</td>                     </tr>                 </tbody>             </table>         </div> </body> <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script> <script src="~/Scripts/APIScripts/Module.js"></script> <script src="~/Scripts/APIScripts/Service.js"></script> <script src="~/Scripts/APIScripts/Controller.js"></script>

Please don'r forget to load the needed scripts. Here we have set body as our data-ng-app and table as our ng-controller. We are looping through the data using data-ng-repeat.

If everything is done, we can build the application and see the output.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Wep-API-Get-All-Record-1024x576.png

Wep API Get All Record

So far our READ operation is done. Now We will move into CREATE part.

Create Operation

First we will concentrate on the view part as of now. Just add the below codes to your view.

1 2 3 4 5 <div class="form-group">            <label for="email">Sbscribe here</label>            <input type="email" class="form-control" id="email" placeholder="Enter email" [required="string" ] data-ng-model="mailid" />        </div>        <button type="button" class="btn btn-default" data-ng-click="saveSubs();">Submit</button>

This will give you an output as follows.

http://sibeeshpassion.com/wp-content/uploads/2016/02/View-Design-For-Create.png

View Design For Create

As you can see, we are firing the function saveSubs() in data-ng-click. So let us see what we need to write in it.

In the Controller.js you need to create a function as below.

1 2 3 4 5 6 7 8 9 10 11 12 $scope.saveSubs = function () {         var sub = {             MailID: $scope.mailid,             SubscribedDate: new Date()         };         var saveSubs = APIService.saveSubscriber(sub);         saveSubs.then(function (d) {             getAll();         }, function (error) {             console.log('Oops! Something went wrong while saving the data.')         })     };

Did you see that we are calling an another function which is in our APIService. So now we need to create a function saveSubscriber in Service.js. Shall we?

1 2 3 4 5 6 7 this.saveSubscriber = function (sub) {         return $http({             method: 'post',             data: sub,             url: 'api/Subscriber'         });     }

So all set, the rest is to create a function in our API Controller.

1 2 3 4 5 6 7 8 9 // POST: api/Subscriber         public void Post(tbl_Subscribers sub)         {             if (ModelState.IsValid)             {                 myEntity.tbl_Subscribers.Add(sub);                 myEntity.SaveChanges();             }         }

That's cool, now you will be able to create data through our API with the help of Angular JS. Now shall we move into UPDATE operation.

Update Operation

Before going to the code part we will do some changes in our table design. We are going to make one field (Mail ID field) editable when ever user double clicks in it. And of course we will update the edited data to the database when ever user leaves that field. Sounds cool? Now please change the view as follows.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <div id="tblSubs" ng-controller="APIController">     <table>         <tr>             <th>ID</th>             <th>Email ID ( Double click to update)</th>             <th>Subscribed Date</th>             <th></th>         </tr>         <tbody data-ng-repeat="sub in subscriber">             <tr>                 <td>{{sub.SubscriberID}}</td>                 <td ng-blur="updSubscriber(sub,$event)" ng-dblclick="makeEditable($event)">{{sub.MailID}}</td>                 <td>{{sub.SubscribedDate}}</td>             </tr>         </tbody>     </table>     <div class="form-group">         <label for="email">Sbscribe here</label>         <input type="email" class="form-control" id="email" placeholder="Enter email" [required="string" ] data-ng-model="mailid" />     </div>     <button type="button" class="btn btn-default" data-ng-click="saveSubs();">Submit</button> </div>

The below is the main change we did.

1 <td ng-blur="updSubscriber(sub,$event)" ng-dblclick="makeEditable($event)">{{sub.MailID}}</td>

In ng-blur we are calling the function updSubscriber with parameter $event and the current subscriber details. And in ng-dblclick we are calling the function makeEditable with parameter $event which actually holds the UI details and current events.

Below is the code for the function makeEditable in Controller.js

1 2 3 4 $scope.makeEditable = function (obj) {         obj.target.setAttribute("contenteditable", true);         obj.target.focus();     };

As you can see we are setting the attribute contenteditable to true using setAttribute function. Now we will look into the function updSubscriber.

Add a function in Controller.js

1 2 3 4 5 6 7 8 9 $scope.updSubscriber = function (sub, eve) {         sub.MailID = eve.currentTarget.innerText;         var upd = APIService.updateSubscriber(sub);         upd.then(function (d) {             getAll();         }, function (error) {             console.log('Oops! Something went wrong while updating the data.')         })     };

Add a relative function in Service.js

1 2 3 4 5 6 7 this.updateSubscriber = function (sub) {         return $http({             method: 'put',             data: sub,             url: 'api/Subscriber'         });     }

Now we need to add a function in our Web API controller.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // PUT: api/Subscriber/5        public void Put(tbl_Subscribers sub)        {            if (ModelState.IsValid)            {                myEntity.Entry(sub).State = EntityState.Modified;                try                {                    myEntity.SaveChanges();                }                catch (Exception)                {                    throw;                }            }        }

Now you will be able to update your record. What is pending now? Yes, DELETE operation.

Delete Operation

Make some changes in the view as follows.

1 2 3 4 5 6 7 8 9 10 <tbody data-ng-repeat="sub in subscriber">                 <tr>                     <td>{{sub.SubscriberID}}</td>                     <td ng-blur="updSubscriber(sub,$event)" ng-dblclick="makeEditable($event)">{{sub.MailID}}</td>                     <td>{{sub.SubscribedDate}}</td>                     <td>                         <input type="button" id="Delete" value="Delete" data-ng-click="dltSubscriber(sub.SubscriberID)" />                     </td>                 </tr>             </tbody>

Now add the new function in Controller.js

1 2 3 4 5 6 7 8 $scope.dltSubscriber = function (subID) {         var dlt = APIService.deleteSubscriber(subID);         dlt.then(function (d) {             getAll();         }, function (error) {             console.log('Oops! Something went wrong while deleting the data.')         })     };

Create a service in Service.js now.

1 2 3 4 5 6 7 8 this.deleteSubscriber = function (subID) {         var url = 'api/Subscriber/' + subID;         return $http({             method: 'delete',             data: subID,             url: url         });     }

Now it is time to create our delete method in Web API controller.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // DELETE: api/Subscriber/5         public void Delete(int id)         {             tbl_Subscribers dlt = myEntity.tbl_Subscribers.Find(id);             if (dlt != null)             {                 try                 {                     myEntity.tbl_Subscribers.Remove(dlt);                     myEntity.SaveChanges();                 }                 catch (Exception)                 {                     throw;                 }             }         }

That is all. We did it. Now build your application and see an output as follows.

http://sibeeshpassion.com/wp-content/uploads/2016/02/Web-API-With-Angular-JS1-e1454928109942.png

Web API With Angular JS