Off the Ridge Code Newsletter

Search

Monthly Archives: May 2015

How to Angular – Part 6 – Routing in AngularJS

Published May 18, 2015 in AngularJS - 1Comments

Routing in AngularJS

In this post, I’m going to talk a little bit about routing in AngularJS and add a new route to our existing application. As a reminder: This is a sample application that we’ve been creating since Part 1 of How to Angular. The current version runs inside WebStorm. If you don’t own a copy of WebStorm, I highly encourage you to download a 30 day trial.

Why do we need Routing in AngularJS?:

As the application grows, we may to need to provide multiple views and send the user to a different page with details. AngularJS is a SPA (Single Page Application) centric framework and such all the calls to the server should be done for the purpose of retrieving data or messaging. Therefore, we need to map each http request or route to a particular view. This will logically divide our SPA into parts and keep it maintainable. Notice that each ‘view’ is actually a partial view a not a full html page.

Steps to add routing to the existing application:

Step 1.

Open app.js file and modify as follows:

var app = angular.module('myfirstangularapp', ['ngRoute']).
    config(function($routeProvider){
      console.log("here");
      $routeProvider.when('/view',
          {
            templateUrl:'app/templates/view.html',
            controller:'MyFirstController'
          });

      $routeProvider.otherwise({redirectTo: '/view'});
    });
We injected a dependency on the ngRoute module which includes the $route service and will provide routing services for our application.
In turn, the $route service includes the $routeProvider that is used to configure the routes.

There are two methods on the $routeProvider:

1. when(path, route) – takes the path that is matched against $location.path and route that will be assigned to $route.current.

2. otherwise(params) – executes if no route definition is matched.

Step 2.

1. Create a ‘templates’ directory under the ‘app’ directory.
2. Create the view.html file under the ‘templates’ directory.

Routing-in-AngularJS

Step 3.

Cut out the entire code fragment between

<div class="container"></div> 
out of index.html and paste it inside the view.html file under the templates directory.

Step 4.

Remove the ‘ng-controller=”MyFirstController”‘ directive from the div inside the index.html page.

Step 5.

Add ng-view directive to index.html. It basically replaces the fragment of that html that you’ve removed in step 3 as follows:

  <div class="container">
    <ng-view></ng-view>
  </div>

ngView is a directive that complements the $route service by including the rendered template of the current route into the main layout (index.html) file.

After you perform Steps 3 and 5. This is what your View.html partial page should look like:

<div>
    <p class="text-muted">
        1. Lower case filter:</p>
    <p class="text-info">First Name : {{data.firstName | lowercase}}</p>
    <hr />
    <p class="text-muted">
        2. Upper case filter</p>
    <p class="text-info">First Name : {{data.firstName | uppercase }}</p>
    <hr />
    <p class="text-muted">
        3. Date filter: (mm)</p>
    <p class="text-info">Start Month : {{data.startDate | date:'MM'}}
    </p>
    <hr />
    <p class="text-muted">
        4. Custom filter to remove all spaces:
    </p>
    <p class="text-info">{{data.dashes | removeAllSpaces}}</p>
    <p></p>
    <hr />
    <div>
        <img ng-src="{{getGravatar(data.email)}}" />
    </div>
    <hr/>
    <div>
        <my-input/>
        <label>Github return code:
            <h4 ng-bind="status"></h4>
        </label>
    </div>
    <div>
        <pre>{{user | json}}
        {{error}}
    </div>
</div>

This is what your index.html partial page should look like:

<!DOCTYPE html>
<html ng-app="myfirstangularapp">

<head>
    <meta charset="utf-8"/>
    <title>AngularJS - Sebastian Brukalo</title>
    <link data-require="bootstrap@*" data-semver="3.3.2" rel="stylesheet"
          href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
    <script data-require="bootstrap@*" data-semver="3.3.2"
            src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css"/>
</head>
<body>

<div class="container">
 <ng-view></ng-view>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
<script src="app/app.js"></script>
<script src="app/controllers/controllers.js"></script>
<script src="app/filters/filters.js"></script>
<script src="app/services/services.js"></script>
<script src="app/directives/directives.js"></script>
</body>

Step 6.

Notice that I’ve added an angular-route.min.js library reference to the index.html page. The reason is that ngRoute is not included inside the angular.min.js library.

If we’ve done everything correctly, then, the application should still work and function as before with the difference that now the main view is encapsulated into its own partial view.

Full code example in WebStorm.

Happy coding!
-Sebastian

How to AngularJS – Part 5 – Built-in Directives and custom Directives

Published May 4, 2015 in AngularJS - 0Comments

In this post I’d like to talk about directives, both built-in directives that ship as part of AngularJS as well as how to create your own custom directives.

So, what are directives in AngularJS:

Directives in AngularJS, in short, are a way to teach HTML new tricks, they are markers on DOM elements. For example: The way we make data show on the screen is through the use of binding expressions  {{ scope.property  }} which is a type of Data binding directive.

However there are many other directives that ship with AngularJS, some of which you’ve already seen:

  • ngController
  • ngApp
  • ngBind
  • ngClick

and, many others, The full list can be found here: AngularJS API

There are 4 ways that directives can be applied.

1. As a tag form: <ng-bind>

2. As an attribute: <div ng-bind>

3. As a class: <div class=”ng-bind”>

4. As an HTML Comment.

Let’s look at ngModel and ngClick, and how we can incorporate those into our application.

Step by Step:

1.First, I’m going to turn the JavaScript function expression into an AngularJS function on the scope.

i.e. this:

var getGitHubUser = function(username) {
         gitHubUserLookup.lookupUser(username).then(onLookupComplete, onError);
};
into:
$scope.getGitHubUser = function(username) {
        gitHubUserLookup.lookupUser(username).then(onLookupComplete, onError);
};
and remove the explicit call inside the MyFirstController.js to getGitHubUser(userData.user.username);

2. We’re going to allow the user to type in a user name they wish to lookup. We’ve already removed the ‘automatic’ call to the getGitHubUser(…) function; now, we’re going to add a text input box and button click.
The text input box will have the ngModel directive associated with it.
ngModel directive binds input controls to a property on the scope or, in other words binds our view to the model.

Notice the dash inside the ng-model directive. Directives inside the AngularJS source code are defined using camelCase i.e. in this case ngModel. However, when we use them inside the HTML we need to use spinal-case. i.e. ng-model; hence, ngModel and ng-model refer to the same thing.

 
<a name="userinputwithclick"></a>
 <label>User:<input type="text" /></label>
  <button>GO</button>

These are all the changes required to enable the user to type in and lookup any user they wish to. No custom JavaScript or jQuery is necessary to grab the user name and execute the call. This is the AngularJS way!

Now, let’s see how we can write a custom directive and create a custom element.

I’m going to turn our input box and button click into a directive.

Step by Step:

1. I’m going create a new file called directives.js. To register a custom directive with AngularJS we use a keyword: ‘module.directive‘. It’s very similar to how we registered custom filters.
We pass a name of the directive as a first parameter. What we need to return from the directive is a directive definition object.

I’m going to replace the entire markup inside the index.html page:

  <div><label>User: <input type="text" /></label>
  <button>GO</button></div>

with a single element directive .

Custom directive

I’m going to use the ‘template’ property here:

app.directive('myInput', function() {

    return {
      restrict: 'E',
       template: "<label>User:<input type="text" /></label><button>GO</button>"
      };
  });

The restrict ‘E’ means that we are using this directive as an element.

That’s all, everything should work as before.

Looking up AngularJS team in Github

Full example and happy coding!

-Sebastian