Angular 2 Single Page Apps using Routing – Part 3

If you have not gone through my first two blogs, this might be the right time to go through them: `Angular 2 Single Page Apps using Routing – Part 1′ and `Angular 2 Single Page Apps using Routing – Part 2′.

In this blog, I will show the process for updating app.component.html.

<nav class="navbar navbar-default">
 <div class="container">
 <div class="navbar-header">
 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
 <span class="sr-only">Toggle navigation</span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 </button>
 <a class="navbar-brand" href="#"><i class="glyphicon glyphicon-briefcase"></i> Pet Care</a>
 </div>
 <div id="navbar" class="navbar-collapse collapse">
 <ul class="nav navbar-nav">
 <li [routerLink]="['/home']" [routerLinkActive]="['active']"><a [routerLink]="['/home']">Home</a></li>
 <li><a href="#">Cats</a></li>
 <li><a href="#">Dogs</a></li>
 </ul>

</div><!–/.nav-collapse –>
</div>
</nav>
<div class=”container page”>
<router-outlet></router-outlet>
</div>

When the browser URL for this application becomes /home, the router matches that URL to the route path /home and displays the HomeComponent after a RouterOutlet (router-outlet) that is placed in the host view’s HTML.

The RouterLink directives on the anchor tags give the router control over those elements. The navigation paths are fixed, so you can assign a string to the routerLink.

The RouterLinkActive directive on each anchor tag helps visually distinguish the anchor for the currently selected “active” route. The router adds the active CSS class to the element when the associated RouterLink becomes active.

Now run ‘npm start’ in the command prompt and see the Home page looks as expected.

PetCare Service to Get Pet Data

 Create pet.service.ts file under app folder. Put the following code.

import { Injectable } from '@angular/core';
 import { Jsonp, URLSearchParams } from '@angular/http';
 import 'rxjs/add/operator/map';

@Injectable()
export class PetService {

constructor(private jsonp: Jsonp) { }

private petsUrl = ‘http://api.petfinder.com/’;

findPets(animal : string) {

// http://api.petfinder.com/pet.find?key=[API_KEY]&animal=[ANIMAL]&format=json&location=texas
const endPoint = ‘pet.find’

let params = new URLSearchParams();
params.set(‘key’, ‘[API_KEY]’);
params.set(‘location’, ‘texas’);
params.set(‘animal’, animal);
params.set(‘format’, ‘json’);
params.set(‘callback’, ‘JSONP_CALLBACK’);

return this.jsonp
.get(this.petsUrl + endPoint, { search: params })
.map(response => <string[]> response.json().petfinder.pets.pet);
}

findPetById(id: string) {

const endPoint = ‘pet.get’

let params = new URLSearchParams();
params.set(‘key’, ‘[API_KEY]’);
params.set(‘id’, id);
params.set(‘format’, ‘json’);
params.set(‘callback’, ‘JSONP_CALLBACK’);

// Return response
return this.jsonp
.get(this.petsUrl + endPoint, { search: params })
.map(response => <string[]> response.json().petfinder.pet);
}
}

Here class is decorated with an @Injectable decorator which tells Angular that this class is meant to be used as a provider to other components. Because of Cross-Origin Resource Sharing (CORS) issue JSONP (JavaScript Object Notation with Padding) is used instead of HTTP to make API request. JSONP supports cross-domain JavaScript requests.

The class has 3 members:

  1. Private property which holds the base Url of the API
  2. Method (findPets) to retrieve list of pets based on type (cat/dog)
  3. Method (findPetById) to get details of a pet by it’s Id

URLSearchParams makes it easier to set query parameters and construct URL rather than manually concatenating.

Replace [API_KEY] with key available in the source code. You can also sign-up at https://www.petfinder.com/developers/api-key and get an API key.

AngularJS with SharePoint

In the recent past, web apps have taken on an extremely important role with a prerequisite that they be fast and appealing. More importantly they need to be user friendly. While there are several good technologies to create such apps, I believe that there is one good technology AngularJs, which is extremely useful for creating the structural framework for dynamic web apps. From the client side, AngularJs helps make web apps faster and provides the support required for best user interface. It can be used with any technology including MVC and MVVM frameworks.

Why AngularJs?

We can develop any web application with DOM Manipulation, Data binding etc. However, AngularJS makes this easier. Some key advantages of AngularJs are:

  1. AngularJs supports cross-browser JavaScript code in applications
  2. It is a rich internet application
  3. It is Open Source technology
  4. It has awesome flexibility and makes it easy for developers to code
  5. Increases the business for apps and works with cross technologies.
  6. MVW Framework(Model View What Ever)
  7. Bootstrap

How AngularJS works

Integrating Angular with SharePoint:

SharePoint has the ability to use client-object-model JavaScript and Rest API to create web parts. The advantage of this is, we can use it in .Net, Silver Light etc in JavaScript libraries. Although, SharePoint has server-side code with which we can accomplish a lot of things, there is the off chance that we may not be able to achieve rich user interface and performance – although for this, we could use JQuery or other similar frameworks. When comparing these frameworks, AngularJS is the best way to modify Document-Object-Model (DOM).

Before integrating SharePoint we should know a few things about Angular:

  • Controller – JavaScript functions that are bound to a particular scope.
  • Scope – Objects that refer to the model. They act as a glue between controller and view.
  • Directives – Markers on DOM elements, these can be used to create custom HTML tags that serve as new, custom widgets. AngularJS has built-in directives (ngBind, ngModel, ngBind, etc.)
  • Data-binding – It is the automatic synchronization of data between model and view components.
  • Factory– Factory come with several built-in services for example $http to make an XMLHttpRequests.

Controller:

A Controller is a JavaScript object which contains attributes and functions. A Controller is defined using the AngularJS built-in directive ng-controller. A Controller handles all the operations related to a view to which it has been associated.

A Controller is defined as follows:

angular.module(rootApp, []).controller(home.controller, function($scope) {
 });

And the above controller can be declared as follows:

<div id="myDiv" ng-app="rootApp" ng-controller="home.controller">
 ......
 </div>

Built-in Directives

As the name itself indicates, Directive is an indicator to the angular compiler. It directs the angular compiler that what to do when it comes across a Directive. AngularJS provides such built-in directives to ease the developer work. Some of the important directives necessary to build an AngularJS app are-

  • ng-app – This directive defines and links an AngularJS application to HTML.
  • ng-controller – This directive associates a controller to a view.
  • ng-model – This directive binds the values of AngularJS application data to HTML input controls.
  • ng-bind – This directive binds the AngularJS Application data to HTML tags.
  • ng-repeat – This directive is used to iterate through a list and generate elements dynamically.

There are many other built-in directives which you can refer from the AngularJS documentation as and how you come across different requirements.

Custom Directives

Custom directives are used to extend the HTML functionality. Custom directives are defined using the “directive” function. A custom directive replaces an element to which it has been applied. Let’s understand this with an example.

I want to define a custom tag as follows, which has an attribute called “title”.

&lt;announcements title=""&gt;&lt;/announcements &gt;

To handle above custom tag a custom directive has to be written

var app = angular.module(‘rootApp’, []);
 app.directive(‘announcements’, function() {
 var directive = {};
 directive.template = "Title: <b>{{ title}}</b> “;
 directive.scope = {
 title: "=title"
 }
 directive.compile = function(element, attributes) {
 element.css("background", "blue");
 }
 return directive;
 });

Scope:

It is JavaScript object and it contains the properties and functions although it will interact the controller and view.

$scope.getUser() {
 $scope.User = userInfo;
 }

Factory:

This is a simple function. Add some logic and it will return the object. And we can call in controller,service,directive, etc. Create common or helper function in factory to refer in app.

angular.module(rootApp, []).controller(home.factory, function($scope, $http) {
 Var homefactory = {};
 homefactory.getAnnouncements = function() {
 $http.get("url");
 }
 return homefactory;
 });

Create sample in SharePoint with Angular.

  1. Download the angular.min.js
  2. The following folder structure need to be create to step Angular with SharePoint.
    a) Map folder site assets module in visual studio.
    b) Inside site assets need to following structure.
  3. Create home.factory.js inside the factory – Home and add the below code.
    angular.module('home.factories', [])
     .factory('HomeFactory', ['$q', '$http', function($q, $http, ) {
     var homefactory = {};
     var date = new Date();
     var urlHomeSiteCollection = ""; //pass the url here.

    homefactory.getAnnouncements = function() {
    var currentDate = date.getFullYear() + “-” + (date.getMonth() + 1) + “-” + date.getDate();
    var queryUrl = urlHomeSiteCollection + “/_api/web/lists/GetByTitle(‘Announcements’)/items?$Select=Title,Body,Expires,CategoryLookup/Title,CategoryLookup/BackgroundColor,CategoryLookup/TextColor,CategoryLookup/CategoryIcon&$expand=CategoryLookup&$filter=Expires ge datetime'” + currentDate + “T00:00:00’&$orderby=Expires+asc,Modified+desc&$top=10”;
    return $http.get(queryUrl);
    },
    return homefactory;
    }]);

  4. Create home.controller.js inside the controllers- Home and add the below code.
    angular.module('home', [home.controllers ','
     home.factories ']);
     angular.module("home.controllers", ['home.factories']).controller('HomeController', function($scope, HomeFactory) {
     $scope.Announcements = [];

    function initHome() {
    loadAnnouncements();
    }
    // load announcements and binding
    function loadAnnouncements() {
    HomeFactory.getAnnouncements().then(function(result) {
    if (result.data.d.results && result.data.d.results.length > 0) {
    bindAnnouncements(result.data.d.results)
    }
    }, function(error) {
    console.log(“Error fetching announcements. ” + error.data);
    })
    };

    function bindAnnouncements(results) {
    if (results.length > 0) {
    $.each(results, function(key, value) {
    var announcement = {
    Title: value.Title,
    Description: Description
    };
    $scope.Announcements.push(announcement);
    });
    }
    };
    initHome();
    });

  5. Add the below code in rootapp.js. The rootapp.js for inject multiple controllers and make a one app to refer in application.
    var rootApp = angular.module('rootApp', ['home'], function() {});
     angular.module("home", [], function() {});
     angular.module('home').run(function($http) {
     $http.defaults.headers.common["Accept"] = "application/json;odata=verbose";
     });
    Note: if want to refer multiple controllers in page we have to follow as shown as above code.
  6. Add downloaded angular js, jquery inside the lib – Framework folder
  7. Add custom CSS inside the lib – css folder.
  8. Refer angular.js, jquery and rootapp.js sharepoint master page.
  9. Applications that have any CSS, JavaScript function related to the header, footer or any load function should be added to the app.js and refer to the SharePoint master page.
  10. Create the application page and the below scripts and html code.
    <script type="text/javascript" src="/SiteAssets/Content/app/controllers/Home/home.controller.js"></script>
     <script type="text/javascript" src="/SiteAssets/Content/app//factory/Home/home.factory.js"></script>
     <div id="hero-background-image" ng-controller="HomeController">
     <div class="item" ng-repeat="announce in Announcements">
     <div class="carousel-caption">
     <div class="row">
     <div class="col-sm-4 col-md-2 announcement-category">{{announce.Title}}</div>
     <div class="col-sm-8 col-md-10 announcement-body">{{announce.Description}}</div>
     </div>
     </div>
     </div>
     </div>
     </div>
     </div>
  11. Deploy the application.

Happy Coding!

Basic AngularJS with Routing [Part 3]

In my first blog, Basic AngularJS with Routing [Part 1], I discussed AngularJS Controllers with examples. In the second blog, Basic AngularJS with Routing [Part 2] I delved into Directive and Services. In this blog, I will deep dive into Routing.

What is Routing?

At a high level, here is what Routing is all about. You are building an application and you cannot put all the functionality that you need into a single controller in a single view. You have different features and you need different areas inside the application. That is going to require multiple views, multiple controllers. Each view and controller is responsible for a specific feature or area of functionality, and now that you have functionalities spread around, how do you know where the user is located in your application, how do you know what is supposed to be on the page, what are they seeing? Are they trying to view the details about a user, or are they trying to view the details about a repository for some user? And the first question is; how do I know the location of the user?

While the browser does have the concept of a URL, a Uniform Resource Location that is what appears in the address bar. We usually think of the URL as a way to reach some resource on the server, but when building an application with Angular, you can also start thinking of a URL as being able to locate the resource on the client too.

Routing with Angular

Here is how Routing works with Angular. First, we are going to need another script from the Angular code base; it’s called angular-route.js. This will give us access to a new module, a module that our application module will need to take a dependency on; this new module is called ng-route. Using a component in ng-route, we will configure our routing rules into the routing engine. Remember, this is where you describe the URLs for your application. You have to tell the routing engine how it should respond to a particular URL that appears in the browser. With ng-route, this is done using a component known as $routeProvider. It has an API where you describe what the URL looks like and then what to do for that URL. For each URL you can specify a templateUrl that is the HTML that Angular has to go and find and load up for that route, and then optionally a Controller that should be used to manage that template. And because the routing engine has to take that template and load it into the display, we are going to need to reorganize our application and our default.html file.

Our default.html file will become what some people call a layout view, or a shell view. A layout view is a view that contains the markup you will use on every page of your application. It might include some common features, like a navigation menu at the top that’s going to appear everywhere in your application, and perhaps a foot at the bottom that contains links to contact you and a copyright, but there will be space somewhere in that layout view, where the routing engine can load a template that corresponds to the current URL.

So let’s say we have two templates available; one to display userDetails and one to display repository details. We will tell the routing engine where to place these templates using a new directive, an ng-view directive. We will use that directive on an HTML element and it is that HTML element where Angular will insert the template when we’re at the right URL. And now, as the user clicks and navigates and enters information and saves information, the routing engine will swap out one template with another template inside the shell view, and our application is now scalable; it can support any number of templates and controllers. The routing engine is going to swap them in and out. When it does that, it will also coordinate with the browser history, so that if the user hits the Back button or the Forward button, they will still be navigating just inside of your application. So we have a little bit of work cut out for ourselves, but let’s try this out now.

Step1: provide link to angular-route.js in layout page

Configure routing

The first thing I will do is make sure I go out and add, that angular–route script that I can find if I do a Search for angular-route. Now you notice I get a couple Search results here, angular-route and angular-router. It’s angular-route that I want, it has the most up-to-date version of angular-route. I’ll just click the button, and that will add an additional script file for me in my page. This one going to code.angular.js, and it’s picking up angular-route.js. And now that we have that script included, the next step would be to set ourselves up so that we can configure the routing engine. One place we could do that, is inside of script.js where we create a githubViewer module, but script.js is already a little bit full. It’s really where we have MainController defined. So I would like to remove the creation of this githubViewer module from script.js and move it to the new file where we will create that module and also add the configuration. So, create a new file, this one I’ll call app.js because this is really what’s going to define the application, and it’s inside of here where I can have an IIFE, where I can have a line that will define the module, and what we’re going to find is that we can run and register configuration functions against our application, and inside of this configuration function where we can define our routes. And now that’s cleanly separated out from script.js, which is just going to get a reference to githubViewer.

Step2: Define the user for different controllers and views

Step3: On search of username, route to another controller “UserController”

Step4: In UserController define the logic to get the user details.

Output:

Summary

In the three blogs, we saw how Angular is a framework for building applications with HTML and we took a look at the primary components involved, including Controllers, Models, and Services. In this last blog of the series, we looked at Routing in detail. The primary takeaways for Routing are that Routing allows you to build navigation into your application and it also allows you to build an application from smaller pieces. You can divide responsibility for your features amongst multiple controllers, models, views, and services.

AngularJS – A Structural Framework for Dynamic Web Applications [Part 1]

AngularJS is an open source web application framework to build large scale and high performance web applications while keeping them easy to maintain. It provides developers options to write client-side application in a clean Model View Controller (MVC) architecture. AngularJS automatically handles JavaScript code suitable for different browsers and so, the developer does not have to make his JavaScript application cross-browser compliant.

Building blocks of AngularJS:

Controller – JavaScript functions that are bound to a particular scope.

Scope – Objects that refer to the model. They act as a glue between controller and view.

Directives – Markers on DOM elements, these can be used to create custom HTML tags that serve as new, custom widgets. AngularJS has built-in directives (ngBind, ngModel, ngBind, etc.)

Data-binding – It is the automatic synchronization of data between model and view components.

Services – AngularJS come with several built-in services for example $http to make a XMLHttpRequests. These are singleton objects which are instantiated only once in an app.

Dependency Injection – AngularJS has a built-in dependency injection sub-system that helps the developer by making the application easier to develop, understand, and test.

In this blog, I will focus on Controller and Directives.

Controller

A Controller is a JavaScript object which contains attributes and functions. A Controller is defined using the AngularJS built-in directive ng-controller.  A Controller handles all the operations related to a view to which it has been associated.

A Controller is defined as follows:

angular.module('myApp', []).controller('myController', function($scope) {
 });

And the above controller can be declared as follows:

<div id="myDiv" ng-app="myApp" ng-controller="myController">
 ......
 </div>

Built-in Directives

As the name itself indicates, Directive is an indicator to the angular compiler. It directs the angular compiler that what to do when it comes across a Directive. AngularJS provides such built-in directives to ease the developer work. Some of the important directives necessary to build an AngularJS app are-

  • ng-app – This directive defines and links an AngularJS application to HTML.
  • ng-controller – This directive associates a controller to a view.
  • ng-model – This directive binds the values of AngularJS application data to HTML input controls.
  • ng-bind – This directive binds the AngularJS Application data to HTML tags.
  • ng-repeat – This directive is used to iterate through a list and generate elements dynamically.
  • There are many other built-in directives which you can refer from the AngularJS documentation as and how you come across different requirements.

Sample Application

Let’s build a sample application which will give you a clear picture about how AngularJS application works. And then I shall introduce you to other AngularJS features.

What do you need to build an AngularJS app?

All you need is AngularJS framework JavaScript file, which you can download from https://angularjs.org/ or simply include the following script tag in your application template.

<script src=”http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js”>

You can use any text editor to create a AngularJS application.

Step-1: Create a template

<div id="myDiv">
 <p>Type your name in the input field:</p>
 <p><input type="text"></p>
 <p>Hello <span></span></p>
 </div>

Step-2: Create a Module

<script>
 angular.module('myApp', []);
 </script>

Step-3: Create a Controller

<script>
 angular.module('myApp', []).controller('myCtrl', function($scope) {
 $scope.name = "";
 });
 </script>

Step-4: Update the HTML template to attach Module and Controller

<div id="myDiv" ng-app="myApp" ng-controller="myCtrl">
 <p>Type your name in the input field:</p>
 <p><input type="text" ng-model="name"></p>
 <p>Hello <span ng-bind="name"></span></p>
 </div>

Result

In the above example you can see $scope model variable “name” has been associated to an input box. As the user types a name in the input box the same value will be reflected below the input box. This is called two-way data binding. In two-way data binding a model value updated in controller will be reflected in the view automatically and vice-versa.

Custom Directives

Custom directives are used to extend the HTML functionality. Custom directives are defined using the “directive” function. A custom directive replaces an element to which it has been applied. Let’s understand this with an example.

I want to define a custom tag as follows, which has an attribute called “name”.

<employee name=””></employee>

To handle above custom tag a custom directive has to be written

var app = angular.module('myApp', []);
 app.directive('employee', function() {
 var directive = {};
 directive.template = "Employee: <b>{{ name }}</b> “;
 directive.scope = {
 name : "=name"
 }
 directive.compile = function(element, attributes) {
 element.css("background", "lightgreen");
 }
 return directive;
 });

Result

This directive will be called as soon as any employee element is encountered in the HTML, and that element will be replaced with the directive’s template wherein it displays the employee name in bold letter with a light green background color.

Don’t miss my next blog where I discuss Dependency and Injection Services!