DZone
Web Dev Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Web Dev Zone > Learning Angular 2: Tour of Heroes Tutorial, Dependency Injection

Learning Angular 2: Tour of Heroes Tutorial, Dependency Injection

The fifth installment of the Angular 2 tutorial focuses on dependency injection.

Brian Swartzfager user avatar by
Brian Swartzfager
·
Jul. 04, 16 · Web Dev Zone · Tutorial
Like (3)
Save
Tweet
3.54K Views

Join the DZone community and get the full member experience.

Join For Free

Lesson 5 of the Tour of Heroes tutorial introduces services.

On a recent episode of the Adventures in Angular podcast, guest Pascal Precht made the recommendation that developers should get in the habit of always applying the @Injectable decorator to a service. The reason behind that recommendation is because the decorators (@Component, @Injectable, etc.) cause the emission of metadata needed to work out the dependency injection hierarchy, and there are no negative side-effects to adding the @Injectable decorator to a service even if that service doesn't itself have any dependencies. The tutorial essentially makes the same recommendation.

Image title


The dependency injection (DI) mechanism described in the lesson involves three parts:

  • Using an import statement to import the code of the service module/file.
  • Using a constructor function in the component to assign the module variable defined with the import statement as a property of the component.
  • Adding the module variable defined with the import statement to the list of providers in the component's "providers" metadata property, "providing" a working instance of the service.

At first glance, it appears to be a more verbose process than the Angular 1 approach of listing the dependencies as arguments to the module (though if you wanted to do any minification you needed to document the dependencies in either an inline array or a separate $inject property statement). But you also had to load your modules properly, and of course, all of your JavaScript files containing the dependency modules had to be pulled in via <script> tag upfront. With this syntax, the import statements let you only load the dependent modules you need for this particular component.

I think it's a more explicit syntax that takes some of the mystery out of the DI process. As someone who does a lot of server-side coding, I'm familiar with constructor functions, so for me, it's a matter of thinking of the "providers" property of the component as the arguments that will become part of the call to the constructor function generated by the compiler. You can look in the ES5 output to see the resulting call to the constructor given a provider of "heroService":

var AppComponent = (function () {
    function AppComponent(heroService) {
        this.heroService = heroService;
        this.title = 'Tour of Heroes';
    }

Having hooks into the component lifecycle like ngOnInit provides developers with additional control over their components. With Angular 1 I would end up working with controllers where it was sometimes hard to distinguish the code that would be executed when the controlller loaded from the code that defined event handlers or watched for certain data changes. ngOnInit will provide a container for that initialization code, and run it at a point in the lifecycle where the component is "fully engaged."

Given the discussion in lesson 3 about how ngIf destroys/removes the content it contains rather than just hiding it, I was curious to see if that meant that any sub-component in that ngIf-wrapped content would fire off ngOnInit every time it was restored to the DOM. So I made a really simple HeroSubDetailComponent:

import { Hero } from './hero';
import { Component, Input, OnInit } from '@angular/core';

@Component({
    selector: 'my-hero-subdetail',
    template: `
        <div>
            <span>{{hero.name}} is kinda cool.</span>
        </div>
    `
})

export class HeroSubDetailComponent implements OnInit {
    @Input()
    hero: Hero;

    ngOnInit() {
        console.log( "sub-detail-component initialized" );
    } 
}

... and then added it to the existing HeroDetailComponent within an ngIf block that would only evaluate to true for the first hero:

import { HeroSubDetailComponent } from './hero-sub-detail.component';

@Component({
    selector: 'my-hero-detail',
    directives: [ HeroSubDetailComponent ],
    template: `
    <div>
      <h2>{{hero.name}} details!</h2>
      <div>
        <label>id: </label>
        {{hero.id}}
      </div>
      <div>
        <label>name: </label>
        {{hero.name}}
      </div>
      <div *ngIf="hero.id == 11">
        <my-hero-subdetail [hero]="hero"></my-hero-subdetail>
      </div>
  </div>
    `
})

... and as I suspected, every time the HeroSubDetailComponent was removed then re-added to the DOM as I clicked through different heroes, it would fire ngOnInit on the readd.

I wasn't aware that Promises were added as native constructs in ES2015 (and thus in the latest implementation of TypeScript), so that was something I learned during this lesson. I was momentarily confused by how it was used without instantiating an instance of it: apparently the resolve() method is a static method, so in this case where the data is hard-coded in the application and immediately available it makes sense to go this route. But a note about the fact that in a more traditional use case you would instantiate a Promise instance might be warranted.

Dependency injection AngularJS

Published at DZone with permission of Brian Swartzfager, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • A Simple Guide to Heaps, Stacks, References, and Values in JavaScript
  • Deployment of Low-Latency Solutions in the Cloud
  • Exporting and Importing Projects in Eclipse
  • Waterfall Vs. Agile Methodologies: Which Is Best For Project Management?

Comments

Web Dev Partner Resources

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo