Debugging Angular 2 Apps with Augury

Angular 2 helpful debugging with Augury

Free Course

Getting Started with Angular 2

Angular 2 is the shiny new framework that comes with a lot of new concepts. Learn all the great new features.

Introduction

Augury is a Google Chrome extension for debugging Angular 2 applications, just like Batarang is for debugging Angular 1.* Apps, and is accessible via the Chrome Dev Tools.

Augury helps us debug our applications by letting us see Component trees, Router Trees and Component Class properties:

Features of Augury

Component Tree

Angular 2 Apps are built with the component structure. It's usually components within components, which eventually form a Component tree. Augury enables you to visualize and inspect the component tree, while accessing the various properties of these components, all within the Chrome Dev Tools. Augury Kitchen Sink Component Tree In the kitchen sink example provided by augury, we can see the component tree. Selecting a component withing the tree highlights and selects the componet's view/template within the browser (the same way dev tools' inpect element usually works).

You can also edit some of these properties in the Chrome Dev Tools and see their effect in your component view.

An injector graph is also provided for components that gives a visual representation of the component hierarchy. Component Hierarchy

Router Tree

Augury can give you a tree view of all the routes in your application. You can see which routes come from which parts of your application. Augury Kitchen Sink Router Tree Selecting the route in the router tree, show's more info about the route.

Installation and Set Up

Install Augury by clicking on the install button in the website. You have to be using Chrome to add it as a Chrome Extensions. You should see a tab for Augury when you open your Chrome Dev Tools.

Augury on Chrome

I've set up an Angular Template app, with webpack based on webpack introduction instructions from the Angular Site.

You can find the Angular Webpack repo here. Instructions to get started with the repo are:

# clone the repo
git clone git@github.com:gangachris/ng2-webpack.git

# go into the directory
cd ng2-webpack

# install dependencies
npm install

# start everything
npm start

After webpack builds, the application should be running in localhost:8080, and should live reload when you edit the code.

Default Webpack App wih Augury

I've annotated key parts of Augury that we'll be looking into:

  • Left side: Component tree
  • Right side: Component properties

Here is something interesting, on the right pane, where the properties of the AppComponent are displayed, there's a link at the top written view source. Click it, and you will be taken to where the source code of the component is.

View Source Augury

Awesome right?

Augury in Action

To see augury in action, let's make the big title on our page bound to a property in the Component Class.

src/app/app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Title will be bound to the page template
  title: string = "Angular 2 Webpack Template"

  // Reverse the page title
  reverseTitle() {
    return this.title.split('').reverse().join('');
  }
}

We've added a title property to the class and a method that rerturns the reverse of the title.

src/app/app.component.html

<main class="row">
  <h1>{{ title }}</h1>
  <h2>{{ reverseTitle() }}</h2>
</main>

We then bind the property and method we added to the template.

When we select the component in Augury, and on the properties on the right hand side, view the state, we can quickly tell that properties in components are represented as state. Double click and change the state, and press enter, you will see both the title and the reversed title changing.

Augury in Action

Setting up Forms

We'll go through understanding the effects of Form Directives, using Augury.

To use the Form Directives in Angular 2, you need to have them provided application wide. For this reason, we will add the Form Providers when the app starts. Edit the main.ts file to bring in and use the form directives.

src/main.ts

import { bootstrap } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { provideForms } from '@angular/forms';

import { AppComponent } from './app/app.component';

if (process.env.ENV === 'production') {
  enableProdMode();
}

bootstrap(AppComponent, [
  provideForms()
])
.catch((err: any) => console.log(err));

This simply adds the FORM_DIRECTIVES application wide so we can use them anywhere in our code. The form Directives we'll look at are:

  1. NgForm, which is usually bound to a form tag.
  2. NgModel, which is usually used in form elements, such as input and textarea.

Angular 2 Forms

For more information on Angular 2 forms, check out our form articles:


NgForm

From the Definition, If NgForm is bound in a component, <form> elements in that component will be upgraded to use the Angular form system. Angular 2 however adds this directive behind the scene to every <form> tag when the FORM_DIRECTIVES are available.

We'll create a simple form to see this in action. Before we do this, notice that in your Augury panel in the Chrome Dev Tools, We only have the App Component listed and it's empty with AppComponent(a-id="0").

src/app/app.component.html

<main class="row">
  <h1>Webpack Template Up n Running</h1>

  <form></form>
</main>

Adding the Form Tag, adds ngForm directive to the form automatically, and it's added to the component tree of our AppComponent. If you look at the Augury panel, you should see two changes.

The AppComponent has a child component, and it's properties have changed. AppComponent Children We have a Children property added, and it consits of an array of the children of the app component, which in this case is a form.

When we select the added form child component, we see that we have two providers added. NgForm and ControlContainer. NgForm Notice we did not explicitly write NgForm anywhere.

What this means is that if we add a spy/custom variable in the view, and assign it to ngForm, it will represent the form. Let's do that.

src/app/app.component.html

<main class="row">
  <h1>Webpack Template Up n Running</h1>

  <form #f="ngForm" (ngSubmit)="onSubmit(f)">

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</main>

We've created a varibale local to the component called f with #f="ngForm", and added an ngSumbit, which is also provided by NgForm directive, and listens on the submit event of the form. We pass in the value of f to the OnSubmit function.

src/app/app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  onSubmit(form: any) {
    console.log(form);
    console.log(form.value) 
  }
 }

We can then view the value of ngForm in the console when we click on the submit button. For now, since the form does not have any input fields, the form.value is just an empty object. The console.log we are doing to see the value of the form is an unneccesarry step which we will tackle using NgModel.

NgModel

From Definition, NgModel binds a domain model to a form control. This means that if we add an input to our form, it woun't be part of the form's value, unless we have an ngModel directive in there. Let's add an input type to see this.

src/app/app.component.html

<main class="row">
  <h1>Webpack Template Up n Running</h1>

  <form #f="ngForm" (ngSubmit)="onSubmit(f)">

    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" name="name" placeholder="Name">
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</main>

We've just added a field. Made a few changes to the src/app/app.component.css by removing the center alignment, and added a class="container" to the body tag in arc/index.html just for styling.

If we look into Augury in Chrome Dev Tools, notice nothing changes. Typing in the name input field does not change anything. This is because our form does not know about the control we have, until we add ngModel.

src/app/app.component.html

<!-- HTML commented out for brevity -->
      <input type="text" class="form-control" id="name" name="name" placeholder="Name" ngModel>
<!-- HTML commented out for brevity -->

We've added ngModel at the end. Now, if we check Augury, we should see some changes.

We have an input component as a child of the form component. This means that on the right side, we should have a children property added. Form with child component Notice that the value of the form now is a an object with a key value pair of the input we added.

Note. ngModel uses the name property of the input field to add as a key in the form's value. In this case the name of the input is name, so the form value is an object with name as one of the keys.

When we select the input listed, we see it's properties. The value changes as we type. ngModel input field.


So, should we have 3 input fields, it's really easy to tell the value of the form while in the browser.

src/app/app.component.html

<main class="row">
  <h1>Webpack Template Up n Running</h1>

  <form #f="ngForm" (ngSubmit)="onSubmit(f)">

    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" name="name" placeholder="Name" ngModel>
    </div>

    <div class="form-group">
      <label for="Email">Email</label>
      <input type="email" class="form-control" id="email" name="email" placeholder="Email" ngModel>
    </div>

    <div class="form-group">
      <label for="Phone">Phone</label>
      <input type="text" class="form-control" id="phone" name="phone" placeholder="Phone Number" ngModel>
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</main>

Notice below that the value of the form in Augury, in Chrome Dev Tools far right is changing as we type in the different values of the form.

Angular Real Time Form Gif

We therefore do not need to console log in our code just to check the value of the form before it is submitted.

Conclusion

If you are into Angular 2 and haven't used Augury before, this is the right time get into it. It provides rich debugging and visualization features for your angular app. We only tackled Component Tree, and the properties, but there's a lot more to angular apps than forms.

You can follow the github repo for Augury to keep up to date with it.

Ganga Chris

I'm a Full Stack Developer (Mostly JavaScript, PHP & Go).