Nick Wilkins Nick Wilkins - 6 days ago 5
Javascript Question

Angular 2 dependancy injection (DI) just not working?

I'm got a couple of (beginner?) problems with my Angular2 app. Firstly a DI works for one component, but not another, and I cant see any problem.

I've got a cocktail component that includes a starring functionality, and a list of ingredients. All code below is stripped down, and it all runs fine (no console errors) - I'm just not getting the desired output

Heres the cocktail.component.ts:

import { Component } from '@angular/core'
import { CocktailService } from './cocktail.service'
import { HttpModule } from '@angular/http';
import { Observable } from 'rxjs/Rx';

@Component({
selector: 'cocktails',
templateUrl: 'app/cocktail.template.html',
providers: [CocktailService, HttpModule]
})
export class CocktailsComponent {
title: string = "Sunday Brunch Specials";
cocktails;
isStarred = false;
numLikes = 10;
ingredient_json = "Bob"; // for testing

constructor(private _cocktailService: CocktailService) {
this.cocktails = _cocktailService.getCocktails();
}

}


And the cocktail.template.html....

<h2>{{title}}</h2>
<input type="text" autoGrow />
<ul>
<li *ngFor="let cocktail of cocktails | async">
<h3>{{cocktail.name}}</h3>
<star [is-starred]="isStarred" [num-likes]="numLikes" (change)="onStarredChange($event)"></star>
<ingredients [ingredient-json]="ingredient_json"></ingredients>
<li>





The star component is getting passed isStarred and numLikes properly - all good.

Now in the ingredient component:

import {Component, Input} from '@angular/core';
import {IngredientService} from './ingredient.service';
@Component({
selector: 'ingredients',
template: '
<h4>Ingredients</h4>
<ul>
<li *ngFor="let ingredient of ingredients">{{ingredient}}</li>
</ul>'
)}
export class IngredientsComponent {
@Input('ingredient-json') ingredient_json = "Hello";

title: 'Ingredients';
ingredients;

constructor() {
// Why isn't ingredient_json outputting anything but hello? Ie nothing is going into input
console.log("Ingredient JSON = " + this.ingredient_json);
}
}


The problem I've stated in comments. The ingredient_json variable just isn't instantiated from the @Input. I'm not getting any errors, the console just always prints out 'Hello' - ie the default. The @Input isn't grabbing anything from its parent (cocktail.component.ts).

I havent included all the app, as I feel as though something is amiss in these 3 files. Like I said, the DI works on the component, so I know that the DI works, but I can't see whats wrong in my code below.

Thanks a lot

Answer

Constructor is invoked before the @input() params are passed to a component.

Implement the method ngOnChanges() in your IngredientsComponent and move your console.log() there.

Details here: https://angular.io/docs/ts/latest/api/core/index/OnChanges-class.html

Comments