I am playing around with Angular2. As a basis, I used the quickstart project from the angular.io page.
Everything seems to work fine, but as soon as I try to inject
I had faced the same problem. Below were the resolution:
Check for couple of things:-
1) Make sure you are using the correct version of typescript (1.5.x) installed from your package location. () If you have previous versions of typescript installed then merely using "tsc" command could be pointing to the existing (< 1.5) location from the environment path.
2) Make sure you use --emitDecoratorMetadata
flag with the tsc command. It is necessary so the javascript output creates the metadata for the decorators.
3) Error - Cannot read property 'annotations' of undefined
Because AppComponent
directive has a dependency on DetailComponent
which has not been defined yet (by the time the synchronous __decorate(
function runs to resolve the dependencies) and the way TS compiles the hoisted variable DetailComponent
is undefined then (The IIFE for that below is yet to run). Try moving the declaration of DetailComponent
before AppComponent
. Or just move it to a different file and import it.
@Component({
selector: 'item-details',
properties: {
item: "item"
}
})
@View({
template: `<span>You selected {{item.name}}</span>`
})
class DetailComponent {
item:Item;
}
@Component({
selector: 'app',
injectables: [ItemService]
})
@View({
template: `<h1>Testing Angular2</h1>
<ul>
<li *for="#item of items">
{{item.id}}: {{item.name}} |
<a href="#" (click)="toggleSelected(item);">
{{selectedItem == item ? "unselect" : "select"}}
</a>
</li>
</ul>
<item-details *if="selectedItem" [item]="selectedItem"></item-details>`,
directives: [For, If, DetailComponent]
})
class AppComponent {
items:Item[];
selectedItem:Item;
constructor(itemService:ItemService) {
this.items = itemService.getItems();
}
toggleSelected(item) {
this.selectedItem = this.selectedItem == item ? null : item;
return false;
}
}
bootstrap(AppComponent);
Edit
As of angular a26 if you face issues with respect to following the current documentation (as of now) follow this link if it helps as there are some relevant changes.
My setup: I am running WebStorm 10.0.2 on Windows, using TypeScript 1.5 beta (compiled to ES5) and node/npm.
Thanks to PSL's help, I found several problems with my setup. They were not related to the code, e.g. not to the order of the class definitions, etc. Just for the record I would like to summarize the issues I had.. Most of them have been mentioned by PSL, but maybe other people have the same problems, e.g. related to the compiler in WebStorm.
Here are the problems I had:
Even though I configured WebStorm to use TypeScript 1.5 installed via npm, an old version (1.3) was used, as this was also installed on my system (I think together with Visual Studio) and registered in the %path%
variable
I configured WebStorm to use a "Custom Compiler Version" for TypeScript (in settings/Languages and Frameworks/TypeScript), with following arguments: -emitDecoratorMetadata -m commonjs -t es5 -sourceMap
. This some how doesn't work.. I'm not sure, if it is related to an issue in WebStorm. Without the -emitDecoratorMetadata
flag it compiled, but the injectables
didn't work.
[Update, 9. June 2015: Yes, it is related to an issue in WebStorm]
However I need the -emitDecoratorMetadata
-flag in order for the injectables
in Angular2 to work.
My solution was to add a custom "File Watcher" in WebStorm (instead of using the "builtin Compiler"-function) with following arguments: -emitDecoratorMetadata -m commonjs -t es5 --sourceMap $FilePath$
Lessons learned when working with Angular2, TypeScript 1.5 and WebStorm:
Ensure TypeScript 1.5 is really the version which is used to compile the ts files (e.g. in your IDE).
Ensure the -emitDecoratorMetadata
is specified.
It doesn't make a difference, if the classes are defined in a specific order or in own files, etc. -> Order does matter! Splitting the classes/components into different files solves the problem and generally leads to better maintanable files.
Thanks again to PSL for his valuable input!