Please enable Javascript to correctly display the contents on Dot Net Tricks!

CRUD Operations with AngularJS, RequireJS and WebAPI

  Author : Shailendra Chauhan
Updated On : 23 Nov 2016
Total Views : 27,519   
 

AngularJS is most popular MVW Javascript framework for single page application development. Also, Visual Studio is the best IDE in world to develop your app using JavaScript framework which you love.

This article will demonstrate you how to use visual studio to develop SPA using AngularJS, RequireJS and Web API.

Defining AngularJS SPA Folder Structure within VS

There are so many ways to organize your code files in SPA. Here, I have created the folder structure based on file types. This structure also help me to take the advantage of Visual Studio intellisense. To enable JavaScript code intellisense just add _references.js file into script folder as shown in given folder structure.

Setup RequireJS

RequireJS is javascript module and files loader. It help you to manage dependencies and make your code well organized and structured. It can be downloaded from www.requirejs.org.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>AngularJS SPA</title>
 <link href="css/bootstrap.css" rel="stylesheet" />
 <script data-main="scripts/main.js" src="scripts/libs/require.js"></script>
</head>
<body>
 <div ng-include="'views/shared/_header.html'"></div>
 <ui-view></ui-view>
</body>
</html>

Here, I have added a reference to require.js file and others js files will be loaded by requirejs asynchronously by using data-main attribute scripts/main.js file. The main.js file is used to define your application JavaScript modules and files dependencies.

require.config({
 baseurl: '/scripts/',
 paths: {
 'angular': 'libs/angular',
 'ngStorage': 'libs/ngStorage',
 'ngCookies': 'libs/angular-cookies',
 'ui-router': 'libs/angular-ui-router',
 'jquery': 'libs/jquery-1.10.2',
 'bootstrap': 'libs/bootstrap',
 'service': 'services/service',
 'homeCtrl': "controllers/homeCtrl",
 'accountCtrl': "controllers/accountCtrl",
 'filter': "filters/filter",
 },
 shim: {
 ngStorage: {
 deps: ['angular'],
 exports: 'angular'
 },
 ngCookies: {
 deps: ['angular'],
 exports: 'angular'
 },
 'ui-router': {
 deps: ['angular'],
 exports: 'angular'
 },
 angular: {
 exports: 'angular'
 },
 bootstrap: {
 deps: ['jquery']
 }
 },
 deps: ['app']
});

require([
 "app",
 "filter",
 "bootstrap",
 "homeCtrl",
 "accountCtrl"
],
 function (app) {
 //bootstrapping app
 app.init();
 }
);

How it works..

Defining AngularJS App Components using RequireJS

To make your javascript code an AMD module just warp your code inside define() method of requirejs.

define() method takes two arguments - first an optional array of defined module dependencies and second a callback function. All the modules inside the array will be loaded before this module.

Defining AngularJS Module and Routes (app.js)

define(['ui-router', 'ngStorage', 'ngCookies'], function () {

 //defining angularjs module
 var app = angular.module("app", ['ui.router', 'ngCookies', 'ngStorage']);

 //global service
 app.constant("utility",
 {
 baseAddress: "http://localhost:5100/api/"
 });

 //manual bootstrap
 app.init = function () {
 angular.bootstrap(document, ['app']);
 };

 //defining routes
 app.config(function ($stateProvider, $urlRouterProvider) {

 $urlRouterProvider.otherwise("/");

 $stateProvider
 .state("home", {
 url: "/",
 templateUrl: 'views/home/home.html',
 controller: 'homeCtrl'
 })
 .state("about", {
 url: "/about",
 templateUrl: 'views/account/about.html',
 controller: 'aboutCtrl'
 });
 });
 return app;
});

Defining AngularJS Service (service.js)

define(['app'], function (app) {
 //defining service using factory method
 app.factory('userService', function ($http, utility) {
 var serviceurl = utility.baseAddress + "UserService/";
 return {
 getUsersList: function () {
 var url = serviceurl + "GetUsersList";
 return $http.get(url);
 },
 getUser: function (user) {
 var url = serviceurl + "GetUser/" + user.UserId;
 return $http.get(url);
 },
 addUser: function (user) {
 var url = serviceurl + "AddUser";
 return $http.post(url, user);
 },
 deleteUser: function (user) {
 var url = serviceurl + "DeleteUser/" + user.UserId;
 return $http.delete(url);
 },
 updateUser: function (user) {
 var url = serviceurl + "ModifyUser/" + user.UserId;
 return $http.put(url, user);
 }
 };
 });
});

Defining AngularJS Controller (homeCtrl.js, accountCtrl.js)

//homeCtrl.js
define(['app', 'service'], function (app) {
 app.controller("homeCtrl", function ($scope, userService) {
 $scope.users = [];
 $scope.user = null;
 $scope.editMode = false;

 //get User
 $scope.get = function () {
 $scope.user = this.user;
 $("#viewModal").modal('show');
 };

 // initialize your users data
 (function () {
 userService.getUsersList().success(function (data) {
 $scope.users = data;
 }).error(function (data) {
 $scope.error = "An Error has occured while Loading users! " + data.ExceptionMessage;
 });
 })();

 // add User
 $scope.add = function () {
 var currentUser = this.user;
 if (currentUser != null && currentUser.Name != null && currentUser.Address && currentUser.ContactNo) {
 userService.addUser(currentUser).success(function (data) {
 $scope.addMode = false;
 currentUser.UserId = data;
 $scope.users.push(currentUser);

 //reset form
 $scope.user = null;
 // $scope.adduserform.$setPristine(); //for form reset

 angular.element('#userModel').modal('hide');
 }).error(function (data) {
 $scope.error = "An Error has occured while Adding user! " + data.ExceptionMessage;
 });
 }
 };

 //edit user
 $scope.edit = function () {
 $scope.user = this.user;
 $scope.editMode = true;

 $("#userModel").modal('show');
 };

 //update user
 $scope.update = function () {
 var currentUser = this.user;
 userService.updateUser(currentUser).success(function (data) {
 currentUser.editMode = false;

 $('#userModel').modal('hide');
 }).error(function (data) {
 $scope.error = "An Error has occured while Updating user! " + data.ExceptionMessage;
 });
 };

 // delete User
 $scope.delete = function () {
 currentUser = $scope.user;
 userService.deleteUser(currentUser).success(function (data) {
 $('#confirmModal').modal('hide');
 $scope.users.pop(currentUser);

 }).error(function (data) {
 $scope.error = "An Error has occured while Deleting user! " + data.ExceptionMessage;

 angular.element('#confirmModal').modal('hide');
 });
 };

 //Model popup events
 $scope.showadd = function () {
 $scope.user = null;
 $scope.editMode = false;

 $("#userModel").modal('show');
 };

 $scope.showedit = function () {
 $('#userModel').modal('show');
 };

 $scope.showconfirm = function (data) {
 $scope.user = data;

 $("#confirmModal").modal('show');
 };

 $scope.cancel = function () {
 $scope.user = null;
 $("#userModel").modal('hide');
 };
 });
});
//accountCtrl.js
define(['app'], function (app) {
 app.controller("aboutCtrl", function ($scope) {
 $scope.Message = "About Us"; 
 });
});

Defining Views/Templates

Now defines the view for CRUD operation on user entity. Here, I am using bootstrap modal popups for Create, Edit and Delete operations.

<!-- home.html -->
<div class="container">
 <div ng-app="userApp" class="container">
 <div ng-show="error" class="alert alert-danger alert-dismissible" role="alert">
 <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
 <p>{{ error }}</p>
 </div>

 <p><a data-ng-click="showadd()" href="javascript:;" class="btn btn-primary">Add New User</a></p>

 <div class="modal fade" id="userModel" tabindex="-1" role="dialog" aria-hidden="true">
 <div class="modal-dialog">
 <div class="modal-content">
 <div class="modal-header">
 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button>
 <h4 class="modal-title" id="myModalLabel" ng-hide="editMode">Add User</h4>
 <h4 class="modal-title" id="myModalLabel" ng-show="editMode">Edit User</h4>
 </div>
 <div class="modal-body">
 <form class="form-horizontal" role="form" name="adduserform">
 <div class="form-group">
 <label for="title" class="col-sm-2 control-label">Name</label>
 <div class="col-sm-10">
 <input type="text" data-ng-model="user.Name" class="form-control" id="title" placeholder="Your Name" required title="Enter your name" />
 </div>
 </div>
 <div class="form-group">
 <label for="title" class="col-sm-2 control-label">Address</label>
 <div class="col-sm-10">
 <input type="text" data-ng-model="user.Address" class="form-control" id="title" placeholder="Your Address" required title="Enter your address" />
 </div>
 </div>
 <div class="form-group">
 <label for="title" class="col-sm-2 control-label">ContactNo</label>
 <div class="col-sm-10">
 <input type="text" data-ng-model="user.ContactNo" class="form-control" id="title" placeholder="Your ContactNo" required title="Enter your contactno" />
 </div>
 </div>
 <div class="form-group">
 <div class="col-sm-offset-2 col-sm-10">
 <span data-ng-hide="editMode">
 <input type="submit" value="Add" ng-disabled="adduserform.$invalid" data-ng-click="add()" class="btn btn-primary" />
 </span>
 <span data-ng-show="editMode">
 <input type="submit" value="Update" ng-disabled="adduserform.$invalid" data-ng-click="update()" class="btn btn-primary" />
 </span>
 <input type="button" value="Cancel" data-ng-click="cancel()" class="btn btn-primary" />
 </div>
 </div>
 </form>
 </div>
 </div>
 </div>
 </div>

 <h1>Users List</h1>
 <table class="table table-hover">
 <tr>
 <th>User ID</th>
 <th>Name</th>
 <th>Address</th>
 <th>Contact No</th>
 <th>Actions</th>
 </tr>

 <tr data-ng-repeat="user in users">
 <td><strong>{{ user.UserId }}</strong></td>
 <td>
 <p>{{ user.Name }}</p>

 </td>
 <td>
 <p>{{ user.Address}}</p>

 </td>
 <td>
 <p>{{ user.ContactNo }}</p>

 </td>
 <td>
 <p>
 <a data-ng-click="get(user)" href="javascript:;">View</a> |
 <a data-ng-click="edit(user)" href="javascript:;">Edit</a> |
 <a data-ng-click="showconfirm(user)" href="javascript:;">Delete</a>
 </p>

 </td>
 </tr>
 </table>
 <hr />

 <div class="modal fade" id="viewModal" tabindex="-1" role="dialog" aria-hidden="true">
 <div class="modal-dialog">
 <div class="modal-content">
 <div class="modal-header">
 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button>
 <h4 class="modal-title" id="myModalLabel">View User</h4>
 </div>
 <div class="modal-body">
 <form class="form-horizontal" role="form" name="viewuser">
 <div class="form-group">
 <label for="Name" class="col-sm-2 control-label">Name</label>
 <div class="col-sm-10">
 {{user.Name}}
 </div>
 </div>
 <div class="form-group">
 <label for="Address" class="col-sm-2 control-label">Address</label>
 <div class="col-sm-10">
 {{user.Address}}
 </div>
 </div>
 <div class="form-group">
 <label for="ContactNo" class="col-sm-2 control-label">ContactNo</label>
 <div class="col-sm-10">
 {{user.ContactNo}}
 </div>
 </div>
 </form>
 </div>
 <div class="modal-footer">
 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
 </div>
 </div>
 </div>
 </div>

 <div class="modal fade" id="confirmModal" tabindex="-1" role="dialog" aria-hidden="true">
 <div class="modal-dialog">
 <div class="modal-content">
 <div class="modal-header">
 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button>
 <h4 class="modal-title" id="myModalLabel">Confirm Action</h4>
 </div>
 <div class="modal-body">
 Are you sure to delete?
 </div>
 <div class="modal-footer">
 <button type="button" class="btn btn-default" data-ng-click="delete()">Ok</button>
 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
 </div>
 </div>
 </div>
 </div>
 </div>
</div>

Also, create a view about.html to display information about youself.

<!-- about.html -->
<div class="container">
 <div class="col-xs-12 col-sm-12 col-lg-12">
 <h2>{{Message}}</h2>
 <p>
 Hey!, I'm an entrepreneur, founder and chief editor of <a href="http://www.dotnet-tricks.com" class="link">www.dotnet-tricks.com</a> and <a href="http://www.dotnettricks.com" class="link">www.dotnettricks.com</a> - <code>“Coding is Rhyme”</code>.
 </p>
 <p>
 I have more than 6 years of hand over Microsoft .NET technologies and other web technologies like AngularJS, JavaScript, Hybrid Mobile Apps Development. A number of articles of myself has become <code>articles-of-the-day</code>, selected in <code>daily-community-spotlight</code> and listed in <a href="http://www.asp.net/mvc/overview/getting-started/recommended-resources-for-mvc" class="link" target="_blank">Recommended Resources for MVC</a> section on the Official <code>Microsoft ASP.NET Community Site.</code>
 </p>
 </div>
</div>

Creating Data Model and DataContext using Entity Framework

public class User
{
 public int UserId { get; set; }

 [Required]
 [MaxLength(50)]
 [Column(TypeName = "varchar")]
 public string Name { get; set; }

 [Required]
 [MaxLength(200)]
 [Column(TypeName = "varchar")]
 public string Address { get; set; }

 [Column(TypeName = "varchar")]
 [MaxLength(15)]
 public string ContactNo { get; set; }
}

public class DataContext : DbContext
{
 public DataContext():base("DefaultConnection")
 {

 }

 public DbSet User { get; set; }
}

Creating REST Service using Web API

[EnableCors("*", "*", "*")] //allow cross-origin request
public class UserServiceController : ApiController
{
 DataContext context = new DataContext();

 [HttpPost]
 public int AddUser(User user)
 {
 context.User.Add(user);
 context.SaveChanges();
 return user.UserId;
 }

 [HttpGet]
 public User GetUser(int id)
 {
 User user = context.User.Find(id);
 return user;
 }

 [HttpGet]
 public List GetUsersList()
 {
 return context.User.ToList();
 }

 [HttpPut]
 public void ModifyUser(User user, int id)
 {
 if (user.UserId == id)
 {
 context.Entry(user).State = EntityState.Modified;
 context.SaveChanges();
 }
 }

 [HttpDelete]
 public void DeleteUser(int id)
 {
 User user = context.User.Find(id);
 if (user != null)
 {
 context.User.Remove(user);
 context.SaveChanges();
 }
 }
}

How it works..

What do you think?

I hope you will enjoy the article while developing AngularJS SPA using ASP.NET WebAPI and RequireJS. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

ABOUT AUTHOR

Shailendra Chauhan
Author, Architect, Corporate Trainer and Microsoft MVP

He is the author of some of most popular e-books which encompass technical Interview on Node.js Interview Questions and Answers, ASP.NET MVC Interview Questions and Answers, AngularJS Interview Questions and Answers and LINQ Interview Questions and AnswersKnow more...

YOU MIGHT LIKE
Free Interview Books
 
COMMENTS (0)
14 DEC
ASP.NET MVC with AngularJS Development (online)

MON-FRI 07:30 AM- 09:00 AM IST

Know More
5 DEC
AngularJS Development (online)

Mon - Fri     6:30 AM-7:30 AM IST

3 DEC
AngularJS Development (offline)

SAT,SUN     11:00 AM-12:30 PM IST

3 DEC
MEAN Stack Development (offline)

Sat, Sun     (09:30 AM-11:00 AM IST)

26 NOV
ASP.NET MVC with AngularJS Development (offline)

(SAT,SUN)     03:30 PM-05:00 PM IST

24 NOV
ASP.NET MVC with AngularJS Development (online)

MON-FRI     09:30 PM-11:00 PM IST

12 NOV
ASP.NET MVC with AngularJS Development (offline)

SAT,SUN     08:00 AM-09:30 AM

3 NOV
ASP.NET MVC with AngularJS Development (online)

MON-FRI     07:30 AM-09:00 AM IST

25 OCT
.NET Development (offline)

Mon-Fri     9:00 AM-11:00 AM IST

BROWSE BY CATEGORY
 
RECENT ARTICLES
SUBSCRIBE TO LATEST NEWS
 
LIKE US ON FACEBOOK
 

Professional Speaks

+