Tag: angular

Using Google Analytics with your SPA Angular 2 Web App

Using Google Analytics with your SPA Angular 2 Web App

In order to track navigation in your Single Page Application, it takes a little more work up front. This article explains how to use Google Analytics with an Angular 2 Web App.

First you’ll need to register your web domain with Google. There a few different ways to verify your site. Once verified you’ll be able to download a JavaScript snippet to add to your site. With a traditional (non-SPA) site, you just drop this into your layout template and you’d be good to go.

The technical details of how tracking SPA navigation is detailed in this guide with Google. The key to grab the creating key from the snippet. We’ll use that later in the implementation.

ga('create', 'UA-69737250-1', 'auto');

First add this to your index.html. This will be the only modification to that page.

<script async src='https://www.google-analytics.com/analytics.js'></script>

Next modify your package.json include the autotrack library from Google. 1.0.3 is the version available when this post was written.

"autotrack": "~1.0.3",

Next we’re going to create a service. This will be a global service instantiated when our app first loads.

import {Injectable} from '@angular/core';
require('autotrack');

@Injectable()
export class AnalyticsService {
    constructor() {
        (window).ga=(window).ga||function(){((window).ga.q=(window).ga.q||[]).push(arguments)};(window).ga.l=+new Date;

        (window).ga('create', 'UA-69737250-1', 'auto');
        (window).ga('require', 'cleanUrlTracker');
        (window).ga('require', 'eventTracker');
        (window).ga('require', 'outboundLinkTracker');
        (window).ga('require', 'urlChangeTracker');
    }

    pageView(url: string) {
        (window).ga('set', 'page', url);
        (window).ga('send', 'pageview');
    }

    //to track clicks on html attributes
    //ga-on="click"
}

If you have a app.module.ts, or a similar file, where you’re bootstrapping your application, add your service there to the providers: [] array.

From your component where you want to track the navigation, import the reference and inject it into your component class. Then on the ngOnInit log the page navigation. (This is not a full component code sample. Just the pieces you need for it to work).

import {AnalyticsService} from './../services/analytics.service'; //path will likely differ

  constructor(private _analytics: AnalyticsService) {
  }

  ngOnInit() {
    this._analytics.pageView('/login.html');
  }

That’s all there is to it. If you want to see if it’s working you can view all network traffic from the Chrome Developer Console, or of course log into your Analytics account to see if the traffic is being captured.

Dynamic ng-controller with Angular

Dynamic ng-controller with Angular

If you’re dynamically pulling in views through frameworks like jQuery, or anything else that isn’t Angular, Angular won’t know you are referencing the controller on the page without re-compiling.  To let Angular know about your new HTML is pretty straight forward.  I have a method in my Main controller that I can access whenever I need to.

    $scope.activateView = function (elements) {
        $compile(elements.contents())($scope);
        $scope.$apply();
    };

I then have a common function I setup to be able to access anywhere I need in the application.

    function activateAngularController(controllerWrapperId) {
        var wrapperElement = angular.element(document.getElementById(controllerWrapperId));
        var mController = angular.element(document.getElementById("body"));
        mController.scope().activateView(wrapperElement);
    }

My Main controller is defined in the body tag, hence it’s getting it from body to populate the mController variable.

<body ng-app="coolApp" ng-controller="MainController">

And finally when you’re instantiating your HTML dynamically, just have it wrapped in a div you can reference.

<div id="myControllerWrapper">
 <div ng-controller="MyController as my">
     <!-- Your html and angular stuff -->
 </div>
</div>

<script>
activateAngularController('myControllerWrapper');
</script>

And that should do it. Angular now knows about the new HTML and directives within your controller wrapper. Alright Peter man, ouu ouu!

Dynamic form validation with ng-form

Dynamic form validation with ng-form

Validation with ng-form isn’t difficult, once you get the hang of it. But figuring out some of the advanced features isn’t that trivial. One pretty common scenario a web application needs to do is dynamic form validation. Dynamic meaning the HTML isn’t pre-defined, but is dependent on a condition, which is one of the things that make Angular so great in the first place!

Let’s say you have a ng-repeat and you include a ng-form within that loop. The ng-form needs a unique name.

Example:

<div ng-repeat=”arg in inputArray”>

<ng-form name=”form{{arg.Name}}”>

<div ng-show=”form{{arg.Name}}.$valid == false”>

{{arg.validationMessage}}

</div>

</ng-form>

</div>

The name is unique within the inputArray object collection. The validationMessage property is defined on the arg object, and when the validation isn’t met, the message will display.

For example when you’re iterating through the inputArray you can place a ng-required on an input tag.

<input ng-required=”arg.required()” />

Have required as a function works great because you can put logic in the function to support conditional logic. If there’s not conditonial logic you can simply return true.

Angular form validation works really well once you understand how it works. Give it some time and you’ll really like working with it.