Series: Introduction to the MEAN Stack
After the last time we saw AngularJS only superficially, I want to introduce you today how you can use AngularJS to use a REST API.
For this purpose we use the REST API, which we have created in the article about Baucis. We add only a static file server to the example in the penultimate line so that we can output HTML, CSS, and JavaScript:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var mongoose = require ( ‘mongoose’ ) ;
var baucis = require ( ‘baucis’ ) ; var express = require ( ‘express’ ) ; mongoose. connect ( ‘mongodb: // localhost: 27017 / todo-db’ ) ; var TodoSchema = new mongoose. Schema ( { baucis. rest ( { express ( ) |
Remember to install Mongoose, Baucis and Express, as well as launch the Node server and MongoDB. Also AngularJS should you again with Bower install.
After this preparation we can now begin with the example. Like Node, AngularJS is also divided into several modules. One of these is $ http, which allows you to perform HTTP requests, which is part of the core modules of AngularJS. This means that it is automatically installed with AngularJS. Another module with which you can perform HTTP requests is $ resource. It is based on $ http and is directly for use with REST APIs. It is also developed by the AngularJS team, but must be installed additionally. I would like to introduce you to another AngularJS module as a $ resource: Restangular, Restangular is very similar to $ resource, but offers more comfort and flexibility. It is not developed by the AngularJS team, but by Martin Gontovnikas. You install it with the following command:
1
|
$ bower install restangular
|
If you have watched the terminal carefully or bower_components
look in your folder, you will find that you have downloaded another framework called Lo-Dash in addition to Restangular . Here we see one of the reasons why we use Bower: Sometimes different frameworks (or modules / components) depend on each other. With package managers like Bower and npm, we do not have to worry about these dependencies and save on work. I will not explain Lo-Dash at this point, since we will not use it, but it is a very useful little framework that simplifies the use of objects, arrays, strings, and the like. You may want to sniff the documentation of Lo-Dash to find out more.
You may smoke your head with the many frameworks and you see it as a bad practice to use and install too many frameworks. Something worry is, of course, appropriate, but these are really useful and very small frameworks. AngularJS may initially be a very large framework, but on the other hand it reduces your own self-written code considerably. If the file size of the frameworks disturb, then you are told that the biggest file size problems are still caused by pictures on web pages. As long as you do not optimize your images synonymous and thoroughly compressed, you should not yet (or few) thoughts about JavaScript files make. The later you all your code minified and packaged in a file – of which I go now
Now that we have all the necessary resources for our webapp, I show you in one go our client, which I owed the better readability owed completely in a single index.html
:
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 |
<! doctype html>
< html ng-app = “todoApp” > < head > <! – loadscripts -> < script src = “./bower_components/angular/angular.js” > < / script > < script src = “./bower_components/lodash/dist/lodash.js” > < / script > < script src = “./bower_components/restangular/dist/restangular.js” > < / script > <! – create angular app – > $ scope.todos = []; $ scope.create = function () { $ scope.delete = function (todo, index) { }); <! – add style for completed todos -> <- create view: first a form to create new todos, then show a list of existing todos -> < ul > </ body > |
Let’s go through the code step by step. In the html
element, we ng-app
used the attribute as in the last article . This time we added the value todoApp
. If we want to use additional modules like Restangular, then we need to assign a module directly to an AngularJS app. This is done at a later time with the string todoApp
.
In the next section, we include AngularJS, Lo-Dash, and Restangular. As far as nothing unknown. In productive use I would put the scripts to the end of the HTML document, but for reasons of explanation I have brought the whole logic forward. Now begins the exciting section.
With the following code lines we create an AngularJS app called todoApp
and tell her that it depends on Restangular:
1
2 |
angular
. module ( ‘todoApp’ , [ ‘restangular’ ] ) |
This is followed by a configuration section in which individual modules can be configured before their use. In this case, we change a setting for Restangular. Restangular assumes that the REST API data has a id
field per document . However, as we know, this field is called MongoDB _id
. So we have to change this setting. At this point, we also see dependency injection for the first time. RestangularProvider must be called RestangularProvider! If the parameter is different, we do not get the RestangularProvider
object! For AngularJS the names of parameters are important!
1
2 3 4 5 |
, config ( function ( RestangularProvider ) {
RestangularProvider. setRestangularFields ( { id : ‘_id’ } ) ; } ) |
We then create a controller. The controller receives a name so that it can be assigned to a view later. We also inject a $scope
– and a – Restangular
object. Dependency injection is used again here. If we write the parameters with a different name, we do not get our desired objects. In addition, the order of the parameters does not matter. Whether we write $scope
or Restangular
write is irrelevant. Restangular makes us easier to use our REST API. But what is it $scope
? $scope
is the link between View and Controller, which allows two-way data binding. All data that is $scope
assigned to the object is accessible in the controller and the view. In other words, the $scope
object holds our model.
1
|
, controller ( ‘TodoController’ , function ( $ scope , Restangular ) {
|
We now know that the $scope
object gets our model and that we get the data of our model with Restangular via our REST API. This realization will be implemented in the next step. First, we name our model as a todos
field on the $scope
object. It is initially an empty array. The array is now filled with real data. We say Restangular the URL to our REST API and the Collection ( ) and then request with all available Todos. Then you see the function , which is a special feature. The object which/api/todos
getList()
then()
getList()
is not our actual data. This is not possible because HTTP requests are asynchronous. If you know AJAX, you already know this, after all, the “A” is asynchronous. What we are back is a so-called promise . This is a widely used concept in AngularJS. However, it is not specific to AngularJS and can, for example, also be used in a node. A promise helps us to write asynchronous code more literally. In this case is part of the Promise API. The callback is received as soon as the promise has been met. In other words, the callback is executed when we receive our Todos. The Todos are handed over to the callback, so we get themthen()
then()
then()
$scope.todos
Array. But beware: The Todos we receive are not exactly our Todos. When you look at them, you see that they have much more fields and functions. These are Restoudangular extended versions of our Todos! This allows us to better deal with the data later.console.log
1
2 3 4 5 6 7 |
$ scope. todos = [ ] ;
Restangular . all ( ‘api / todos’ ) . getList ( ) . then ( function ( todos ) { $ scope. todos = todos ; } ) ; |
Since we now have our Todos, let us change them. Our client offers the possibility to create new Todos and delete existing ones. For this reason, we create a function for this task in our controller: create
and delete
. We also assign these to the $scope
object so that they can be called later from the view. In the create
function we take our existing Todos and add a new Todo. (Remember that our Todos have been expanded by Restangular , which is an extension that allows us to create new Todos quickly.) You see a new model named on thepost()
post()
newTodo
$scope
, which we have not mentioned so far. This is a single string from a text input field, which we later define in the view. We get a promise from the function again, after all, the creation of new data via the REST API is asynchronous as is the retrieval of existing data. If our new Todo was successfully transferred, the promise is fulfilled and the callback is called by, in which we add our new Todo . This step is necessary for AngularJS to know that the data has changed. The function is very similar, but it refers to a single Todo and not to the entire array. The function also has a second parameterpost()
then()
$scope
delete
index
, which however only serves to make deleted Todo in the array easier to find.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ scope. create = function ( ) {
$ scope. todos . post ( { title : $ scope. newTodo } ) . then ( function ( todo ) { $ scope. todos . push ( todo ) ; } ) ; } ; $ scope. delete = function ( todo , index) { todo . remove ( ) . then ( function ( ) { $ scope. todos . splice ( index , 1 ) ; } ) ; } ; |
A short CSS section follows, in which only one style has been fixed. Elements with the class completed
are to receive a green text. So we can distinguish between completed and unsolved deaths.
Now just follow our view. The view sits in an div
element, which we TodoController
assign to ours . In this way, we can use the data and functions that the controller exposes over $scope
in the view. The view consists of two parts: a form for creating new Todos and a list for displaying and editing existing Todos. The form consists essentially of a text field whose value newTodo
is bound to the model , and a button that create
calls the controller’s function at a click.
The list looks a bit more complicated. A single li
element has been defined in the list that ng-repeat="todo in todos"
begins with . It is a directive which provides theli
Element as many times as there are entries in the model todos
. Within li
, a single Todo can be todo
referenced. In addition, the li
element contains the section ng-class="{ completed: todo.completed }"
. This automatically sets the CSS class completed
to the li
element, if the corresponding one has todo
the value true
in the field completed
! If this is not the case, the class is not set. Through two-way data binding this check happens at any time if the value changes! In the li
element, we {{todo.title}}
first display the actual Todo via the placeholder . This is followed by a button, which delete
calls the function of the controller at a click . You see here the use of a special variable called$index
, It is generated automatically by AngularJS and describes the index of todo
within the todos
array. The following is a check box whose value is directly completed
linked to the field . If the checkbox is used, the value changes true
to false
and vice versa. The directive ng-change
allows us to be informed about a change so that we todo.put()
can store it with our REST API.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
< Div ng-controller = “TodoController” >
< form > New Todo: < input type = “text” ng-model = “newTodo” > < button ng-click = “create ()” > Add < / button > < / form > < ul > < li ng-repeat = “todo in todos” ng- class = “{completed: todo.completed} ” > {todo.title}} < button ng-click = “delete (todo, $ index)” > Remove < / button > or mark as completed: < input type = “checkbox” ng-model = “todo.completed” ng -change = “todo.put ()” > < / li > < / ul > < / div > |
Now test the app at http://127.0.0.1:1337/index.html . Set Todos on, kill Todos, mark them as done. You see that every action in the GUI is reflected. Look between again and again on http://127.0.0.1:1337/api/todos and you see that the data are equally reflected in the REST API. Opens between another browser and you can see the latest data.
This ends my introduction to the MEAN stack. It was certainly incomplete and incomplete, but you could quickly gain experience in a variety of different technologies. They should serve as inspiration and a basic understanding. However, it takes much more effort to gain a deeper understanding of the MEAN stack. If you need further information or questions, just write in the comments.
I hope I could provide you with my article series a small overview of the MEAN stack.
0 Comments