Posts on this Category



AngularJS Internationalization Example

Today I’m going to give you a very simple example of how to translate a AngularJS page with the module angular-translate. To illustrate how to do that, I’m going to create a login screen with 3 or 4 labels, then I’ll make them available in two different languages: English and French. If you need more languages you just have to follow the same principle.

The first thing we need to do is to provide the texts in both languages to our application, we can easily do that in the module.config function, let’s take a look at the code, this will be our app.js file:

var app = angular.module('angularjs_internationalization',['pascalprecht.translate']);
 
app.config(function($translateProvider) {
  $translateProvider.translations('en_US', {
    TITLE: 'Login Form',
    USERNAME: 'Username',
    PASSWORD: 'Password',
    LOGIN: 'Login'
  });
 
  $translateProvider.translations('fr_CA', {
    TITLE: 'Formulaire de login',
    USERNAME: 'Identifiant',
    PASSWORD: 'Mot de passe',
    LOGIN: 'Connexion'
  });
  $translateProvider.determinePreferredLanguage();
});

I just declared the two languages using the function translations() from the translateProvider service, it receives the language key as the first argument and an object containing the texts as the second, note that related texts have same ID in both objects, it won’t work if you use different IDs. After that I called the function determinePreferredLanguage() which tells AngularJS to choose the most suitable language for each user, you can also pick a language by hand, I’ll tell you how to do that in a moment.

Next, we need to create the HTML page, just copy the following code and paste into your index.html file:

<html ng-app="angularjs_internationalization">
<head>
	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js" />
	<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.9.0/angular-translate.min.js" />
	<script src="app.js" />
	<link href="style.css" rel="stylesheet" type="text/css"  />
	<title translate>TITLE</title>
</head>
<body>
	<div class="loginpanel">
	  <div class="txt">
	    <input id="user" type="text" placeholder="{{'USERNAME' | translate}}" />
	    <label for="user" class="entypo-user"></label>
	  </div>
	  <div class="txt">
	    <input id="pwd" type="password" placeholder="{{'PASSWORD' | translate}}" />
	    <label for="pwd" class="entypo-lock"></label>
	  </div>
	  <div class="buttons">
	    <input type="button" value="{{'LOGIN' | translate}}" />
	  </div>
	</div>
<span class="resp-info"></span>
</body>
</html>

You don’t need to be concerned about every single line of this code, what matters here is just how we call our texts from the angular module, which is very simple, as you can see in the placeholder attribute of both inputs, you just need to call your text ID followed by the filter translate.

Now if you run you project you should see the page in your browser’s default language:

Login Form in English
Login Form in English

If you want to test the other language as well, instead of calling the determinePreferredLanguage() function at the end of the config() method, you have to call preferredLanguage() passing the language you want:

$translateProvider.preferredLanguage('fr_CA');

And this should be the result:

Login Form Translated
Login Form Translated

That’s it guys! Thanks for reading this tutorial, just leave a comment if you have any problems, I’ll be glad to help!

AngularJS Tutorial: Conditional Render Example

As a web developer I can say that everyone that works with web development, no matter the language, comes across conditional rendering very often (almost every day), it’s pretty much impossible to see a project that doesn’t have a UI component that cannot be shown if a specific condition isn’t true. And that is not different for AngularJS developers, so today we’re going to learn how to do it with AngularJS, this will be a very simple and easy tutorial, if you are just getting started with angularjs this is the right tutorial for you.

So let’s get started, the example I’m going to give consists in an application with a button that will be responsible for showing and hiding a div that contains some content, to make that content visible and invisible we’re going to use conditional rendering, pretty straightforward, right?

We’re going to start by creating the app.js file, here is how it should look like:

var app = angular.module('renderExample',[]);
app.controller('renderExampleController', function($scope){
	$scope.showContent= true;
	$scope.label= 'Hide Text';
 
	$scope.switch = function(){
		if($scope.showContent){
			$scope.showContent= false;
			$scope.label= 'Show Text';
		}else{
			$scope.showContent= true;
			$scope.label= 'Hide Text';			
		}
	}
});

As you can see, I’ve declared two variables in my controller: showContent and label. The first one, as the name suggests, is the condition to render the content, it will only appear on the page when this variable is set to true, and the second one is the text that will appear in the button, when the content is visible the label will be 'Hide Text', and when it’s invisible it’ll be 'Show Text'. Lastly, we have the function switch() which will be called by the button and will be responsible for switching the content visibility by changing the two variables values.

Now the last thing we need to do is to create the index.html file:

<!DOCTYPE html>
<html ng-app="renderExample">
   <head>
      <title>Conditional Render Example</title>
      <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
      <script src="app.js"></script>
   </head>
   <body>
      <div ng-controller="renderExampleController">
         <input type="button" value="{{label}}" ng-click="switch()"/>
         <br />
         <div ng-if="showContent">
            Some content.
         </div>
      </div>
   </body>
</html>

You should be familiar with most of this code, what really matters here is the directive ng-if, this is the directive that controls if the component will be rendered or not, you just need to pass the condition, which in this case is the variable showContent.

That’s it!! Now if you execute your project you should be able to show/hide the text by pressing the button.

Tutorial: Integrating AngularJS with NodeJS

Integrating AngularJS with NodeJS
Integrating AngularJS with NodeJS

I know this tutorial may seem a little bit too basic for a lot of you, but these are two of the most popular javascript frameworks at the moment, as a result of that there are lots of people just getting started with NodeJS and AngularJS, and it’s a very common to see people asking how to integrate both, so this will be a very simple beginner level tutorial in which I’ll give an example to demonstrate how AngularJS and NodeJS can work together.

I’m assuming you have already set your enviroment, so we are going to start by creating our NodeJS project, to do that I’m going to use express, if you don’t have it yet just install via npm with the following command line:

npm install express-generator -g

With express installed simply navigate via terminal to the folder you want your project to be located and execute the command express passing your project name as a parameter, like this:

express myNodeProject

Now that your project is created, you can open it with the text editor of your choice, I’m going to use Sublime Text for this tutorial. When you do it you’ll see that express has already created the basic project structure for you:

Folder Structure
Folder Structure

By default, express uses Jade as the view engine, as you can see in the views folder we already have some jade files, which we are not going use, you can get rid of them later if you want. We’ll need to make some changes here to be able to use angularjs. Let’s begin by opening the file routes/index.js, it contains the following code:

var express = require('express');
var router = express.Router();
 
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});
 
module.exports = router;

That’s the code responsible for rendering and redirecting to the index.jade file, what we need to do here is to change it a little bit and make it redirect to our angularjs index.html file (which we are going to create in a moment). After the changes the code should look like this:

var express = require('express');
var router = express.Router();
var path = require('path');
 
/* GET home page. */
router.get('/', function(req, res, next) {
  res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});
 
module.exports = router;

Now we need to create our index.html file, I’m going to put it in the views folder with the jade files. This is how my HTML code looks like:

<!DOCTYPE html>
<html ng-app="angularjsNodejsTutorial">
    <head>
        <title>Integrating AngularJS with NodeJS</title>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
        <script src="javascripts/app.js" type="text/javascript"></script> <!-- not created yet -->
    </head>
    <body >
        <div ng-controller="myController">
        </div>
    </body>
</html>

In this file you can use not only AngularJS, but any javascript library you want, if you run your project you’ll see that nodejs is already redirecting to this file, you can now create you angularjs module and start writing some angularjs code as usual.

At this point you are already using angular and node in your application, but they are kind of independent from each other, there are no communication between them. To finish up this tutorial I’m going to show how AngularJS can make a request to NodeJS. But before we do that, we need to come back to the index.js file (the one we just modified) and create a function to return some data, which will be called when we make the request from our angularjs controller, just copy the following code and paste it right above the module.exports on your index.js.

router.get('/data', function(req,res){
	res.json([{"id": 1, "name": "Mymm", "city": "Pantano do Sul"},
        {"id": 2, "name": "Skyble", "city": "Guilmaro"},
        {"id": 3, "name": "Tagfeed", "city": "Gnosjö"},
        {"id": 4, "name": "Realcube", "city": "Jrashen"},
        {"id": 5, "name": "Bluejam", "city": "Zhangjiawo"},
        {"id": 6, "name": "Jayo", "city": "Obonoma"},
        {"id": 7, "name": "Cogidoo", "city": "Sungsang"},
        {"id": 8, "name": "Avavee", "city": "Diawara"},
        {"id": 9, "name": "Tagtune", "city": "Monywa"},
        {"id": 10, "name": "Centimia", "city": "Retkovci"}]);
});

What is happening here is that the router.get function is assigning a function to the url ‘/data’, so when the user types ‘/data’ in the browser, node will call this function, which is doing nothing more than returning a json, it could be getting and handling data from the database, but as I want to keep it simple, a static json will do the job.

Now let’s create our app.js file, as you can see in the HTML code, it’s already referenced there. I’m going to put it on the public/javascript folder.

var app = angular.module('angularjsNodejsTutorial',[]);
app.controller('myController', function($scope, $http) {
    $scope.data = [];
    var request = $http.get('/data');    
    request.success(function(data) {
        $scope.data = data;
    });
    request.error(function(data){
        console.log('Error: ' + data);
    });
});

This is also a very straightforward code, I’m using the function $http.get with the argumentet ‘/data’ to make the request, then I’m assigning the result to $scope.data.

Now we just need to modify a little bit our HTML to make it iterate over our data and show it on the screen, just add this to the div with the ng-controller:

<ul ng-repeat="item in data">
	<li>Name: {{item.name}}, City: {{item.city}}</li>
</ul>

That’s it!! Now just run your project by executing npm start on the terminal and you’ll be able to access the application on your browser by typing localhost:3000, if you did everything right you should see a page with the data from our json.

Hope this tutorial was helpful, till the next one!!

Understanding and Creating AngularJS Factories

Factories are very similar to AngularJS Services, lots of people struggle to understand the difference between them, if you are one of those, I ensure you’ll clearly understand the difference after reading this tutorial in which I’ll explain the concepts behind AngularJS services and factories, after that I’ll give you a simple example of how to create a factory.

Let’s start with the services, they are basically objects containing the business logic related to an specific entity or feature of your project, for example: your application will have users, right? These users can probably perform some actions like sign up, log in, log out, etc. You could create a service to group all the user related business logic, it would have these three functions I just mentioned: signin() login() and logout(). If you want more details about services, just click on this link.

Factories are a little bit different, instead of performing actions, factories, as the name suggests, are more appropriate to generate and return objects of an specific type. To make it easier to understand let’s come back to the user example, besides the actions I mentioned above, a user has also attributes, like name, login, password, etc. We could create a factory to generate and return objects with these three attributes, it would be a users factory.

Now let’ me show you how to create factories:

var app = angular.module('factoryExample',[]);
 
app.factory('User', function(){
    return function(name, login, password){
        return {
            name : name,
            login : login,
            password : password
        }
    }
});

This is a very straightforward code, it’s the simplest factory I can create, it returns a function that creates a user object according to the parameters passed to it, now you can inject it on your controller and use it like this:

app.controller('myController', function($scope, User){
	var user1 =  new User('Kate','jhpa','urej2232js');
	console.log(user1.name);
	console.log(user1.login);
	console.log(user1.password);
});

If you run your project you should see the attributes printed on your console.

Now you must be wondering, why didn’t I put the user actions and attributes on the same object instead of creating a service and a factory for it? Well, this was just an example, you could totally do it if you prefer, there is countless ways to do it, it’s up to you to choose the most suitable for your project.

That’s it for today guys!! Leave a comment if you have any doubts or suggestions.
Till next tutorial!!

Tutorial: Creating AngularJS Services

Imagine that you have a project with countless features responsible for performing a huge variety of tasks, if you don’t do as much as you can to organize it, how would the code look like? It would be nearly impossible to maintain this project if everything is mixed together in the code, no one would understand it. To make things easier we make whatever we can to keep our code as readable and clean as possible, and that’s what AngularJS Services are good for.

Let’s suppose your project has a lot of features related to products management, you wouldn’t put that together with the code related to employees management, right? Of course not, they have nothing to do with each other, in this case AngularJS allows you to create a service for products and another one for employees, this way all the business logic would be organized in its appropriate service. If someone in the future needs to develop a new product related feature, he/she will know where to find the business logic related to it.

Now let’s see how that looks like in code, I’m going to create 2 services (productService and employeeService), each one will have it’s specific functions, which of course will be different from each other, the productService will allow us to get information and check the availability of an specific product, as the employeeService will only have a function to update the employee profile.

At this point, if you still don’t have an AngularJS module declared just declare one with a name of your choice, I’m going to use ‘angularjsServicesExample':

var app = angular.module('angularjsServicesExample',[]);

With our module created we can now start adding services to it:

app.service('productService', function($http, $q){
    this.isAvailable = function(productId){
        console.log('productService.isAvailable called!!');
    }
    this.getInfo = function(){
        console.log('productService.getInfo called!!');
    }
});
 
app.service('employeeService', function($http, $q){
    this.updateProfile = function(newInfo){
        console.log('employeeService.updateProfile called!!');
    }
});

Really simple, right? But how do we use these services? Using them is even easier, you just need to add them to your controller, then you can just call your functions:

app.controller('myController', function($scope, productService, employeeService){
    productService.isAvailable('1');
    productService.getInfo();
    employeeService.updateProfile('test');
});

That’s it!! If you run your project you’ll see the texts printed on the console.

Thanks for reading this tutorial, hope it was helpful for you, if you have any doubt just leave a comment.
Till the next one!!

AngularJS Tutorial: Consuming Java EE Web Services

It’s very common to see people asking how to integrate Java EE applications with some of the popular JavaScript frameworks, specially with AngularJS. In most cases developers already have an application (or a great portion of it) written in Java EE containing all the business logic, and since it’s not feasible to rewrite everything in JavaScript, they look for ways to integrate and add new technology to the project without losing any existing code.

That’s when Web Services comes in handy!! They allow your AngularJS application to send and receive data from the Java EE module in a very easy way. Of course there are more sophisticated ways to do this communication, but that is a subject for another post.

The first step is to expose the Web Service in your Java EE project, I’m assuming that you already have this project ready, but if you don’t, just create one by following the instructions in this link.

Now that you already have your web service, make sure it’s working before you continue, to do that, open your browser and call your service by typing it’s URL, it should follow this pattern:

1
2
3
{domain}:{port}/{projectName}/{webServicePath}
 
//example: http://localhost:8080/WebServiceEJB-war/test

If everything is right the browser will display the data returned by your web service, if it doesn’t you’re probably missing something, make sure you followed every instruction in the example I mentioned above.

Now we can start writing some AngularJS code, after setting up the project let’s create the app.js file like this:

1
2
3
4
5
6
7
var app = angular.module('angularWS',[]);
app.controller('myController', function($scope, $http){
	$http.get('http://localhost:8080/WebServiceEJB-war/test')
		.success(function(data){
			$scope.text = data;		
		});	
});

This is the simplest way to consume a web service with angular, the $http.get function will make the request to the Java EE application, all you need to do is to pass the web service URL, when it receives the data, it will execute the callback passed to the success() function, there you can do anything you want with the data, in my case I’m just assigning it to the $scope.text variable. When your Angular application make the request, it’ll probably get an Cross-Origin Request Blocked error, in this case just follow the steps in this link to fix it.

Tutorial: ng-table with infinite scroll

I’ve already showed in this blog how to create a basic datatable with ng-table, for those who didn’t see it yet, just click on the link. This tutorial will just be a complement to the previous one, the difference is that instead of using pagination I’m going to use infinite scroll, and don’t worry, I’ll also keep the sorting and filtering features.

So before we start let’s just put the links to every script we need, your index.html should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html ng-app="ngTableTutorial">
    <head>
        <title>ng-table with infinite scroll</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
        <script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
        <script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script>
        <script src="https://raw.githubusercontent.com/BinaryMuse/ngInfiniteScroll/1.0.0/build/ng-infinite-scroll.min.js"></script>
        <link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css">
        <link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" media="screen">
 
        <script src="app/resources/js/app.js" type="text/javascript"></script>
        <link href="app/resources/css/style.css" rel="stylesheet" type="text/css"/>
    </head>
    <body style="padding: 50px">
        <div ng-controller="tableController">
        </div>
    </body>
</html>

As you can see I just put the links to: JQuery, Angular, bootstrap, ng-table and ngInfiniteScroll. There’s also the app.js and style.css, which I created to put my code on them.

Note that the body is still empty for now, let’s leave it like this and open our app.js, the first thing we need to do is to create our angular module and controller, just copy the following code to your app.js:

1
2
3
4
angular.module('ngTableTutorial', ['ngTable','infinite-scroll'])
        .controller('tableController', function ($scope, $filter, ngTableParams) {
        }
);

Don’t forget to declare the ngTable and infinite-scroll as dependencies, we’re going to use them later. This code is still very simple, I just created a module called ngTableTutorial, if you go back to the index.html code you’ll see that the ng-app=”ngTableTutorial” is already there in the html tag, and I also created a controller called tableController, again if go to the index.html there will be a div inside our body with the attribute ng-controller=”tableController”.

Now we need some data to be displayed to the table, I personally like mockaroo to generate random data, but feel free to generate it as you like, you’ll need about 1000 rows for this tutorial, after you generate it, just put it in a variable inside you controller, like this:

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
$scope.users =
        [{
                "id": 1,
                "first_name": "Theresa",
                "last_name": "Morris",
                "email": "tmorris0@myspace.com",
                "country": "Indonesia",
                "ip_address": "143.220.154.199"
            }, {
                "id": 2,
                "first_name": "Steve",
                "last_name": "Gray",
                "email": "sgray1@nytimes.com",
                "country": "Norway",
                "ip_address": "163.199.165.94"
            }
           .
           .
           .
            {
                "id": 1000,
                "first_name": "Gloria",
                "last_name": "West",
                "email": "gwest2@go.com",
                "country": "China",
                "ip_address": "16.171.225.220"
            }
];

Now that we have the data we’re ready to create our table, copy the table bellow inside your div with the ng-controller attribute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<table infinite-scroll="getMoreData()" ng-table="tableParams" show-filter="true" class="table table-striped">
    <tr ng-repeat="user in data">
        <td data-title="'Id'" sortable="'id'">
            {{user.id}}
        </td>
        <td data-title="'First Name'" sortable="'first_name'" filter="{ 'first_name': 'text' }">
            {{user.first_name}}
        </td>
        <td data-title="'Last Name'" sortable="'last_name'" filter="{ 'last_name': 'text' }">
            {{user.last_name}}
        </td>    
        <td data-title="'e-mail'" sortable="'email'">
            {{user.email}}
        </td>    
        <td data-title="'Country'" sortable="'country'">
            {{user.country}}
        </td>    
        <td data-title="'IP'" sortable="'ip_address'">
            {{user.ip_address}}
        </td>    
    </tr>
</table>

Each column is displaying one attribute of our JSON, I put the attribute sortable and filter in some of them to add the sorting and filtering features to the datatable (to show the filter you also have to put show-filter=”true” in your table). But what is important here is the attributes ng-table=”tableParams” and infinite-scroll=”getMoreData()” from the table, the first is binding the table to the tableParams variable in our controller (I’m still going to create this variable), and the second attribute receives the method that will be called when the user reaches the bottom of the page, that’s the method that will make our infinite scroll work.

Now the only thing left for us to do is to create our tableParams and implement the getMoreData() method, copy the following code bellow our JSON in your controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$scope.tableParams = new ngTableParams({
    page: 1,
    count: $scope.users.length
}, {
    counts: [],
    total: 1,
    getData: function ($defer, params) {
        $scope.data = params.sorting() ? $filter('orderBy')($scope.users, params.orderBy()) : $scope.users;
        $scope.data = params.filter() ? $filter('filter')($scope.data, params.filter()) : $scope.data;
        $scope.data = $scope.data.slice(0, 20);
        $defer.resolve($scope.data);
    }
});
 
$scope.getMoreData = function () {
    $scope.data = $scope.users.slice(0, $scope.data.length + 20);
}

In this code we are instantiating the ngTableParams, the fist object it receives as a parameter is just defining that the current page is 1 and setting the row count, but what really matters here is the function getData, it will be called on the table initialization and also every time we sort or filter it, the lines 8 and 9 contains the logic to sort and filter the data, note that in line 10 I’m getting only the first 20 rows of our data, I’m doing this because every time this method is called, or the user will be filtering the data or he’ll be sorting it, both actions require him to be on the top of the page, thus I don’t need to show more than 20 rows.

Ok, now we just need to load more rows when he reaches the bottom of the pages, take a look at line 16, it’s just adding 20 more rows to our data, note that I’m using 2 variables here: $scope.data and $scope.users. The last one contains our original data, we cannot modify it, otherwise we’ll lose the data, that’s why we need an auxiliary variable, just to manipulate the data.

That’s it, now if you run your project you should see the following result:

ngTable with Infinite scroll
ng-Table with infinite scroll

As you scroll down you’ll see that the scroll bar will get smaller and smaller.

AngularJS Tutorial: ui-router example

Since ui-router is one of the most useful features that angular can provide I decided to write this tutorial just to show how to use it, I’m going to create a very simple application that illustrates how to create templates using ui-router states.

After donwloading angular.min.js and angular-ui-router.min.js let’s create our index.html and include both:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html ng-app="uiRouterExample">
    <head>
        <title>ui-router example</title>
        <script src="js/angular.min.js" type="text/javascript"></script>
        <script src="js/angular-ui-router.min.js" type="text/javascript"></script>
        <script src="js/app.js" type="text/javascript"></script>
    </head>
    <body>
        <div ui-view></div>
    </body>
</html>

This file will be our template, it will be the same no matter the state, note that inside the body I have a div with the ui-view attribute, that’s where our states will be included.

With the index.html ready let’s create the app.js:

1
2
3
4
5
6
7
8
9
10
11
var app = angular.module('uiRouterExample', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
    $stateProvider.state("state1", {
        url: "/state1",
        templateUrl: "states/state1.html"
    }).state("state2", {
        url: "/state2",
        templateUrl: "states/state2.html"
    });
    $urlRouterProvider.otherwise("/state1");
});

I tried to make this code as simple as possible, I’ve just created 2 states named ‘state1′ and ‘state2′, each one of them receives an object containing the attributes ‘url’ and ‘templateUrl’, the first one is the path we’re going to type on our browser to call the states, and the second is the html file that will be displayed when the state is called.

Lastly I’m making state1 the default state by passing its path to $urlRouterProvider.otherwise function, this way when the application is first loaded the state1 will be called by default.

Now let’s take a look at out state1.html and state2.html:

1
2
3
4
5
6
7
8
9
<!--state1.html-->
This is the State1
<br />
<a ui-sref="state2">Go to state2</a>
 
<!--state2.html-->
This is the State2
<br />
<a ui-sref="state1">Go to state1</a>

If you run your project, since state1 is your default state, you’re going to see the state1.html rendered on your screen, and if you click on the link you’re going to be redirected to state2.

Tutorial: Creating Reusable Code with AngularJS Directives

AngularJS Directives

I know this may not be new for most of you, but when it comes to directives a lot of people still get really confused, so let’s start by looking at its definition, according to AngularJS documentacion:

Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.

In other words, they allow us to create our own DOM elements that can be reused all over the place, imagine that you have a block of HTML code that you know you’re going to use in several places, instead of just coping and pasting it everywhere, you can create a directive and use it wherever you need, it’ll be a lot easier for you to maintain your code, if something changes in this HTML block you just have to modify your directive, and the changes will reflect across your application.

It will be easier to understand with an example, let’s create a project containing the following files:

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html ng-app="directivesTutorial">
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
        <script src="app/resources/js/app.js" type="text/javascript"></script>
    </head>
    <body >
        <div ng-controller="directivesTutorialController">
            <div ng-repeat="company in companies">
                <p>Company: {{company.name}} - City: {{company.city}}</p>
            </div>
        </div>
    </body>
</html>

app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
var app = angular.module('directivesTutorial', []);
app.controller('directivesTutorialController', function ($scope, $http) {
    $scope.companies = [{"id": 1, "name": "Mymm", "city": "Pantano do Sul"},
        {"id": 2, "name": "Skyble", "city": "Guilmaro"},
        {"id": 3, "name": "Tagfeed", "city": "Gnosjö"},
        {"id": 4, "name": "Realcube", "city": "Jrashen"},
        {"id": 5, "name": "Bluejam", "city": "Zhangjiawo"},
        {"id": 6, "name": "Jayo", "city": "Obonoma"},
        {"id": 7, "name": "Cogidoo", "city": "Sungsang"},
        {"id": 8, "name": "Avavee", "city": "Diawara"},
        {"id": 9, "name": "Tagtune", "city": "Monywa"},
        {"id": 10, "name": "Centimia", "city": "Retkovci"}];
});

Nothing different for now, we’ve seen this a million times, it’s just a ng-repeat iterating over a JSON (in this case a list of campanies), note that inside the ng-repeat div we have a small block of code that displays the company information, of course this block would be more complex in a real scenario, but let’s suppose we need to reuse it to display the same data in other parts of the application, to achieve that we’re going create a directive called ‘company’ which will be responsible for displaying the company data.

Copy the code bellow to another js file, let’s call it ‘campany.js':

1
2
3
4
5
6
7
8
var companyDirective = angular.module('directives.company', []);
companyDirective.directive('company', function () {
    return{
        retrict: 'E',
        scope: {object: '='},
        templateUrl: "templates/company.html"
    };
});

That’s our directive’s code, you can see that it returns an object containing 3 attributes, the first one is the “retrict: ‘E'”, it means that our directive will be restricted to elements, in other words it will be a DOM element.

The second one is the “object: ‘='”, by declaring this ‘object’ variable we’re saying that our directive will have an attribute called ‘object’, we’re going to use this attribute to pass the company we want the data to be displayed.
And lastly we have our templateUrl that receives the path to an html file containing the directive’s html code.

Our company.html should look like this:

1
<p>Company: {{object.name}} - City: {{object.city}}</p>

Note that it’s the same code as before, the only difference is that instead of using the variable ‘company’ we’re using ‘object’ which is the name of the attribute we defined before.

We’re almost done, now you just have to add to your index.html a reference to company.js:

1
<script src="{YOUR_PATH}/company.js" type="text/javascript"></script>

and also put the directive as a dependency in your app.js:

1
var app = angular.module('directivesTutorial', ['directives.company']);

That’s it! Now our ng-repeat can be rewritten using our new directive:

1
2
3
<div ng-repeat="company in companies">
    <company object="company"></company>
</div>

You now have the ‘company’ element that can be reused anywhere in your application.

Related Posts:
Tutorial: Basic DataTable (sorting, filtering and pagination) with AngularJS and ng-Table
Tutorial: Implementing Infinite Scroll with AngularJS and ngInfiniteScroll

Tutorial: Implementing Infinite Scroll with AngularJS and ngInfiniteScroll

Over the past few years the infinite scroll has became very popular across the web, developers are increasingly choosing to use infinite scroll over the conventional paginator. The advantage is that it doesn’t require the user to manually go to the next page when he reaches the end of the page, it automatically loads and display more data without the user intervention.

In this tutorial I’m going to show how to implement infinite scroll using ngInfiniteScroll for AngularJS.

First create the js and html file:

app.js

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
angular.module('infiniteScrollTutorial', ['infinite-scroll'])
        .controller('infiniteScrollController', function ($scope, $http) {
            $scope.users =
                    [{
                            "id": 1,
                            "first_name": "Kimberly",
                            "last_name": "Grant",
                            "email": "kgrant0@ebay.co.uk",
                            "country": "Bolivia",
                            "ip_address": "93.77.148.179"
                        }, {
                            "id": 2,
                            "first_name": "Elizabeth",
                            "last_name": "Lewis",
                            "email": "elewis1@so-net.ne.jp",
                            "country": "Indonesia",
                            "ip_address": "39.187.159.25"
                        },
                        .
                        .
                        .
 
                        {
                            "id": 100,
                            "first_name": "Shawn",
                            "last_name": "Ellis",
                            "email": "sellis2r@diigo.com",
                            "country": "Portugal",
                            "ip_address": "121.250.152.235"
                        }];
});

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
<!DOCTYPE html>
<html ng-app="infiniteScrollTutorial">
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
        <script src="https://raw.githubusercontent.com/BinaryMuse/ngInfiniteScroll/1.0.0/build/ng-infinite-scroll.min.js"></script>
        <script src="app/resources/js/app.js" type="text/javascript"></script>
        <style>
            .userContainer{
                width:500px;
                height:110px;
                background: #f9f9f9;
                padding: 5px;
                font-family: verdana;
                margin-bottom: 7px;
                box-shadow: 0px 0px 2px 1px;
            }
            .userContainer p{
                font-size: 12px;
            }
        </style>
    </head>
    <body>
        <div ng-controller="infiniteScrollController">
            <div >
                <div ng-repeat="user in users" class="userContainer">
                    <h4>{{user.first_name}} {{user.last_name}}</h4>
                    <p>
                        <b>Email:</b> {{user.email}}  -   
                        <b>Country:</b> {{user.country}}  -  
                        <b>IP:</b> {{user.ip_address}} 
                    </p>
                </div>
            </div>
        </div>
    </body>
</html>

Nothing special for now, except that I’ve already added the dependency ‘infinite-scroll’ in the angular module declaration, besides that we just have a regular ng-repeat iterating over a JSON (you should make this JSON as big as you can, it will be easier for you to see the results, you can use mockaroo to gerenate some JSON data).

Now let’s change the code a little bit to make the infinite scroll work, we’re going to add the attribute ‘infinite-scroll’ in the div above the one with the ng-repeat, after the modification it should look like this:

1
2
3
4
5
6
7
8
9
10
<div infinite-scroll="getMoreData()">
    <div ng-repeat="user in data" class="userContainer">
        <h4>{{user.first_name}} {{user.last_name}}</h4>
        <p>
            <b>Email:</b> {{user.email}}  -   
            <b>Country:</b> {{user.country}}  -  
            <b>IP:</b> {{user.ip_address}} 
        </p>
    </div>
</div>

Note that the new attribute is referencing the function getMoreData(), which will be called every time the bottom of the element approaches the bottom of the browser window, in this function we’ll have to write the code to get more data, also note the I’m not using the variable ‘users’ anymore in the ng-repeat, instead I’m using the auxiliary variable ‘data’.

Let’s take a look at the getMoreData() code, add this bellow the JSON in your app.js:

1
2
3
4
$scope.data = $scope.users.slice(0, 5);
$scope.getMoreData = function () {
    $scope.data = $scope.users.slice(0, $scope.data.length + 5);
}

I’m initializing the $scope.data with the 5 first elements of the $scope.users, and the function getMoreData is just adding five more elements every time it gets called.

Now if you run you application you’ll see the following result:

AngularJS infinite Scroll
AngularJS infinite Scroll

That’s it! At first it’ll have only 5 elements loaded and as you scroll down it will start loading more.

Related Posts:
Tutorial: Basic DataTable (sorting, filtering and pagination) with AngularJS and ng-Table
Tutorial: Creating Reusable Code with AngularJS Directives