The complete source code for this AngularJS App can be downloaded from the following GitHub repository:
https://github.com/CarmelSoftware/AngularJS_OData_HTTPPOST
You can learn this step-by-step tutorial as a standalone, or you can see the previous lessons of the series. This is the Lesson #15 in the "AngularJS: From 0 To 100" articles written for Beginners. This lessons start at Lesson #1 .
<<<< PREVIOUS LESSON NEXT LESSON >>>>
Because here we're using the "Brackets" open source web Editor , optimized for AngularJS , we prepared a short tutorial about it in this post.
This is the AngularJS App that we'll develop from scratch here, in 20 minutes :
Make POST Requests to an OData Web API RESTful service using $http AngularJS
You can copy-paste all pieces of source code as you move forward through this Tutorial, or elsewhere you can download the entire AngularJS web site from the following URL:
https://github.com/CarmelSoftware/AngularJS_OData_HTTPPOST/archive/master.zip
First, let's add the references to the scripts and styles to use, via CDN(content delivery network), instead of downloading all files to our app. Also, we are defining the HTML5 file as an data-ng-app Angular App:
As you see, we add 2 AngularJS scripts, and 2 Bootstrap CSS3 files. Also, we create directories for "Content" and "Controllers".
<!doctype html>
<html data-ng-app="OrchidsApp">
<head>
<title>AngularJS SPA App
</title>
<link href="Contents/Style.css" rel="stylesheet" />
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular-route.js"></script>
<script src="/App/Controllers/SPAControllers.js" type="text/javascript"></script>
</head>
Next, copy-paste the following CSS3 style to your style.css file:
body {background:rgba(255, 238, 238, 0.5);
}
img {width:100px;height:100px;
}
.select
{
width:100px;
padding:5px 5px 5px 25px;
margin:10px 15px 15px 25px;
font:900 12px Comic Sans MS;
opacity:0.9;
background:#f0f0f0;
border:5px solid #ddd;
border-radius: 10px;
box-shadow:10px 10px 2px #c0c0c0;
}
.centered
{
text-align:center;
}
In the same HTML file, add a <div> bound to an data-ng-view:
<body class="container">
<div class="jumbotron">
<h1>Orchids SPA</h1>
</div>
<div id="container">
<div data-ng-view=""></div>
</div>
</body>
</html>
This <div> will be replaced by 2 Template Views, that we're going to design next.
The first one is for the List of flowers. Create an "/App/Views/OrchidsList.html" file, and paste the following code inside it:
<div class="jumbotron" >
<h2>List of my Favorite Orchids</h2>
</div>
<div class="jumbotron">
<ul class="list-group">
<li data-ng-repeat="Orchid in OrchidsList" class="list-group-item">
<div >
<img src="/Contents/Images/{{Orchid.MainPicture}}" alt="{{Orchid.Title}}" title="{{Orchid.Title}}" > <br />
<span >{{Orchid.BlogID}} . {{Orchid.Title | uppercase}} <br />
{{Orchid.Text}} {{Orchid.DatePosted | date }}
</span>
</div>
</li>
</ul>
<div class="panel panel-default">
<div class="panel-body | centered">
<button data-ng-click="fnShowOrchids(-1)" class="btn btn-default btn-lg" ><<<<</button>
<input type="number" data-ng-model="pageSize" max="4" min="1" value="2" class="select"/>
<button data-ng-click="fnShowOrchids(1)" class="btn btn-default btn-lg" >>>>></button>
</div>
</div>
<a href="#/add">Add your Favorite Flowers</a>
</div>
I've remarked the more relevant code in red. The two buttons are for paging the items forward and backwards. The Input type=number is for setting the size of every page while paging. Also, we just display all the flowers by showing all the OrchidsList that we will prepare at the Controller.
We explained using AngularJS collections and the data-ng-repeat in a previous lesson .
Create a javascript SPAControllers.js file, and add a module with a Controller , as follows:
We use an Angular $routeProvider to bind each View with a Controller. When the default "/" is required, the user will be faced with the "All" template. If the "/add" page is required, then the "Add" template will be displayed.
Remember, this is always the same HTML web page that is browsed here. This is a SPA application: all is done in THE SAME WEB PAGE: there are no reloads of the HTML page!!!
That's why we referenced the angular-route.js javascript at the <head>: to use the $routeProvider at the Module, and enabling an SPA application.
Now add to the Module, the following Controller:
oOrchidsApp.controller('OrchidsAllCtl', ['$scope', '$http', '$log', function ($scope, $http, $log) {
$scope.angularClass = "angular";
$scope.OrchidsList = [];
$scope.pageSize = 2;
var iCurrentPage = -1;
$scope.fnShowOrchids = function (direction) {
iCurrentPage = iCurrentPage + direction;
iCurrentPage = iCurrentPage >= 0 ? iCurrentPage : 0;
var sURL = "http://carmelwebapi.somee.com/WebAPI/OrchidsWebAPI/" +
"?$skip=" +
iCurrentPage * $scope.pageSize
+ "&$top=" +
$scope.pageSize;
$http.get(sURL).success(function (response) {
$scope.OrchidsList = response;
$log.info("OK");
},
function (err) { $log.error(err) }
)
}
$scope.fnShowOrchids(1);
}
]);
This HTTP GET Ajax request code is explained in the Lesson #14. In short, here we just build the URL for using the OData protocol, and sending a REST request.
The "direction" parameter, as explained in the previous tutorial, is for paging backwards and forward.
Notice that we made a Dependency Injection for three services : $scope, to get the variables, $http for sending HTTP REST requests to the web server, and $log for logging and making easy to debug our app.
In case you don't have an OData RESTful web service working on your environment, i developed and deployed one that you can use. It can be found at this URL:
http://carmelwebapi.somee.com/WebAPI/OrchidsWebAPI
You can use it at your own. An example of using this OData Web API:
http://carmelwebapi.somee.com/WebAPI/OrchidsWebAPI/?$skip=2&$top=3
If you have an OData service working, just replace the URLs at the Controllers.
We're going to fetch the data from an OData RESTful service, by using the Ajax Service called $http in Angular. This service provide all kinds of HTTP functionality, like sending POST, PUT or DELETE requests. Here we will use both the HTTP GET and the HTTP POST verbs.
The official documentation for the $http AngularJS service can be learned at the Angular official web site:
Now let's design the AngularJS Template View for adding a new item to the collection.
The "Add" Template will be as follows:
<div class="container">
<div class="jumbotron">
<div class="" >
<h2>Add your Favorite Orchid</h2>
</div>
<form name="addOrchid" class=""
data-ng-submit="fnAdd()">
<input type="text" class="form-control"
placeholder="Title"
data-ng-model="Orchid.Title"
required>
<input type="text" class="form-control"
placeholder="Text"
data-ng-model="Orchid.Text"
required>
<select data-ng-model="Orchid.MainPicture" title="Select a Picture"
data-ng-options="Img for Img in Flowers" class="form-control">
</select>
<input type="submit" class="btn btn-default btn-lg"
value="Add"
data-ng-disabled="addOrchid.$invalid">
<span>{{msg}}</span>
</form>
<a href="#/">See All Flowers</a>
</div>
</div>
At the Module, add a new Controller to enable the NEW ITEM capabilities of our SPA:
oOrchidsApp.controller('OrchidsAddCtl',
['$http', '$scope', '$location', '$log',
function ($http, $scope, $location, $log) {
$scope.Flowers = ["haeckel_orchidae", "Bulbophyllum", "Cattleya",
"Orchid Calypso", "Paphiopedilum_concolor",
"Peristeria", "Phalaenopsis_amboinensis", "Sobralia"];
$scope.fnAdd = function () {
var oFlower = { "Title": $scope.Orchid.Title,
"Text": $scope.Orchid.Text,
"MainPicture": $scope.Orchid.MainPicture + '.jpg'
};
$http({
url: 'http://carmelwebapi.somee.com/WebAPI/OrchidsWebAPI/',
method: "POST",
data: oFlower,
headers: { 'Content-Type': 'application/json' }
}).success(function (data) {
$scope.msg = "New Orchid saved";
}).error(function (err) {
$log.log(err);
});
}
}
]);
Save and run the SPA:
Provided everything went OK , you can click the "Add" button to be prompted with the "Add" View , which will look something like this:
This is the looks of the selected list for the pictures:
Enter some data and click the "Add" button, to see how it works:
If everything went ok, you will see the "New orchid saved" message.
Return to the "See all flowers" View (remember, all the time we are inside the SAME HTML5 file: that's why this is called a SPA Application):
Here we can see the new item added to the collection.
Remember to widely use the $log service functionality in your SPA, to log to yourself messages , and giving you some feedback about your AngularJS app.
Enjoy AngularJS.....
by Carmel Schvartzman
<<<< PREVIOUS LESSON NEXT LESSON >>>>
כתב: כרמל שוורצמן