Category Archives: Angular

Lifecycle hooks in Angular 2

If you haven’t already read this post LIFECYCLE HOOKS, I would highly recommend you go and read that first.

This is a really short post on just getting up and running with lifecycle hooks.

What are lifecycle hooks?

Angular 2 offers ways for our class/components to be called when certain key parts of a lifecycle workflow occur. The most obvious would be after creation, some form of initialization phase and ofcourse conversely when a class/component is cleaned up and potentially disposed of.

These are not the only lifecycle hooks, but this post is not mean’t to replicate everything in Angular 2’s documentation, but instead highlight how we use the hooks in our code.

How do we use a lifecycle hook

Let’s look at implementing a component with the two (probabaly) most used hooks, OnInit and OnDestroy, as these are obviously especially useful in situations where, maybe state needs to be loaded and stored.

As usual, we need to import the two interfaces, hence we need the line

import { OnInit, OnDestroy } from '@angular/core';

OnInit and OnDestroy look like this

export interface OnInit {
   ngOnInit() : void;
}

export interface OnDestroy {
   ngOnDestroy(): void;
}

Our component would then implement these interfaces, thus

@Component({
})
export class DetailsComponent 
      implements OnInit, OnDestroy {

   ngOnInit(): void {
   }

   ngOnDestroy(): void {
   }
}

and that’s all there is to it.

Note: In the above I said we need to import the interfaces. In reality this is not true, interfaces are optional (as they’re really a TypeScript construct to aid in type checking etc.). What Angular 2 is really looking for is the specially named methods, i.e. ngOnInit and ngOnDestroy in our case.

See LIFECYCLE HOOKS or more specifically the section on Lifecycle sequence for an understand when different parts of the life cycle hooks get called.

For completeness, I’ll list the same here, but without all the descriptions.

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

Service Injection with Angular 2

Note: This post is based heavily on the Angular 2 tutorial, Services, hopefully I can add something useful to this.

We all know what dependency injection is about, right?

Let’s see how we create and inject services using Angular 2.

Naming convention

With components, the convention is to create a TypeScript component class suffixed with the work Component, hence our detail component class would be named DetailComponent and likewise the convention with regards to the file naming is to name file detail.component.ts (all lower case).

We use a similar convention for services. The TypeScript class might be named MyDataService therefore our file would be my-data.service.ts

Note: the hyphen between word boundaries and ofcourse replacing component with service.

Creating our service

Let’s create a simple data service. As per our naming convention, create a file named my-data.service.ts and here’s the code

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

@Injectable()
export class MyDataService {
   // methods etc. omitted
}

To quote the Angular 2 documentation

The @Injectable() decorator tells TypeScript to emit metadata about the service. The metadata specifies that Angular may need to inject other dependencies into this service.

Using the service

In the code that uses the service we still need to import the service (as obviously we need a reference to the type) but instead of our component/code creating the service, we leave this to Angular 2. So the usual would be to create a constructor and allow Angular 2 to inject our service via the constructor. For example here’s the bare bones for a DetailsComponent that uses the previously implemented service

// other imports omitted
import { MyDataService } from './my-data.service';

@Component({
   // selector etc. 
   providers: [MyDataService];
})
export class DetailsComponent {
   constructor(private myDataService: MyDataService) {
   }
}

Notice we also need to register our service in the providers array either within the component or within the app.modules.ts inside the @NgModule.

If the service is registered with providers in a component, then an instance is created when the component is created (and is available for any child components), whereas registering within @NgModule would be more like creating a singleton of the service as the service would be created when the module is created and then available to all components.

Creating an Angular 2 component

An Angular 2 component (written using TypeScript) is a class with the @Component decorator/attribute.

For example

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

@Component({
   // metadata properties
})
export class MyComponent {
   // methods, fields etc.
}

In it’s simplest form we might just supply an inline template to the metadata properties, to define the component’s HTML. Although we can create multiline HTML encased in back ticks `<multiple line HTML>`. We can also store the HTML in a separate file and reference it using templateUrl. Let’s look at some examples.

Single line HTML

@Component({
   template: '<p>Hello</p>'
})
// class definition

Multiline HTML (using the backtick)

The backtick ` is used for multiline strings.

@Component({
   template: `
   <p>Hello</p>
   <p>World</p>
   `
})
// class definition

External Template HTML

@Component({
   templateUrl: 'my-template.html'
})
// class definition

Ofcourse, the equivalent of an HTML component wouldn’t be so useful if we couldn’t also define styles. So, as you’d expect we also have the metadata property for style that works in the same way as the template.

The main thing to note is that the stylesUrls is plural and expects and array of styles, i.e.

@Component({
  selector: 'my-app',
  templateUrl: 'my-app.html',
  styleUrls: ['my-app1.css', 'my-app2.css']
})
// class definition

Referring to class fields

At this point, the class itself might seem a little pointless, but by adding fields etc. to it we can reference these from the @Component template itself.

For example

@Component({
   template: '<p>{{greeting}}</p>'
})
export class MyComponent {
   greeting: string = 'Hello';
}

The {{ }} is Angular 2’s expression syntax, meaning it can contain code to access fields, or actual expressions, such as 2 + 3 or method calls such as max(a, b).

Cannot GET / in Angular

I was playing with the quick start tutorial from Angular’s setup page on their web site.

Using the file/folder layout on their THE HERO EDITOR I removed all folders/files not listed in their diagram.

For completeness I’ll duplicate the information here

angular-tour-of-heroes
|—src
|—|—app
|—|—|—app.component.ts
|—|—|—app.module.ts
|—|—index.html
|—|—main.ts
|—|—styles.css
|—|—systemjs.config.js
|—|—tsconfig.json
|—node_modules …
|—package.json

I then ran npm start from the command prompt in the root angular-tour-of-heroes and up pops the browser with Cannot GET /, looking at the output from npm I could see index.html was not found by npm.

I also noticed npm couldn’t find a file bs-config.json, so I located that from the quick start and placed it in the root angular-tour-of-heroes folder and all worked correctly, no more 404.

Here’s why, the bs-confog.json gives the baseDir of the “website”, here’s the file context

{
  "server": {
    "baseDir": "src",
    "routes": {
      "/node_modules": "node_modules"
    }
  }
}