Reputation: 2945
See the plunker: http://plnkr.co/edit/ifJzVKJTmnTZ4madWDK7
We're using Typescript on an Angular2 project that's currently on Angular2-beta.12. We have a directory structure that looks something like the following
├── feature1
| ├── feature1.component.ts
| ├── feature1.service.ts
| ├── feature1.action.ts
| └── feature1.model.ts
├── feature2.ts
├── feature2
| └── feature2.service.ts
feature2.ts contains:
export * from './feature1/feature2.service';
feature1/feature1.service looks like:
import {Injectable} from "angular2/core";
import {Feature2Service} from "../feature2
@Injectable()
export class Feature1Service {
constructor(protected _feature2Service:Feature2Service) {
}
}
feature1/feature1.component looks like:
import {Component, OnInit} from "angular2/core";
import {Feature1Service} from "./feature1.service";
@Component({
selector: "my-feature1",
templateUrl: "./feature1.html",
providers: [Feature1Service]
})
export class Feature1Component implements OnInit {
constructor() {
}
ngOnInit() {
}
}
feature2.service.ts looks something like:
import {Injectable} from "angular2/core";
@Injectable()
export class Feature2Service {
constructor() {
}
}
When referencing feature2 from feature1 using just the feature2.ts
file the resulting transpiled code seems to think feature2
is what should be provided but if we directly reference the feature2/feature2.service
file in the import the transpiled code sets it up correctly.
Transpiled code when using import {Feature2Service} from "feature2.ts";
:
setters:[
function (feature2_1_1) {
feature2_1 = feature2_1_1;
}
]
transpiled code when using import {Feature2Service} from "../feature2/feature2.service"
:
setters:[
function (feature_2_service_1_1) {
feature_2_service_1 = feature_2_service_1_1;
}
]
I've played with lots of different ways of structuring a providers block in the feature1.ts file (based on the node_modules/angular2/ts/http.ts file) without any luck.
In the browser and our Unit tests all of this yields errors that look like:
EXCEPTION: Cannot resolve all parameters for 'Feature1Service'(undefined). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'Feature1Service' is decorated with Injectable.
This seems pretty basic but what am I missing? I'd like to be able to simplify our imports by having these single export files for features, this is an overly simplified example but we have many features that have lots of components and different models so cleaning up the imports so all our developers don't need to know the intricacies of all the directory structures would be nice.
Thanks!
Upvotes: 0
Views: 69
Reputation: 123
The first problem: In your feature1.service.ts you are importing FeatureService from feature2.service, but your feature2.service is exporting Feature2Service, so you should change that.
Instead of:
import {Injectable} from "angular2/core";
import {FeatureService} from "../feature2/feature2.service";
@Injectable()
export class Feature1Service {
constructor(protected _feature2Service: Feature2Service) {}
}
You should use:
import {Injectable} from "angular2/core";
import {Feature2Service} from "../feature2/feature2.service";
@Injectable()
export class Feature1Service {
constructor(protected _feature2Service: Feature2Service) {}
}
The second problem: A service must be registered as a provider before it can be used, so you have two options - or register it as a provider in your base app.component, this meaning that your service will be shared across all of your components, or you can register it only in the component that needs it. Be aware that all subcomponents will inherit it. So in your feature1.component you should do the following:
...
import {Feature2Service} from "../feature2/feature2.service";
@Component({
selector: "my-feature1",
template: `
<span>THIS IS MY FEATURE 1</span>
`,
providers: [Feature1Service, Feature2Service]
})
...
See the working plunker: http://plnkr.co/edit/xNuZdKgT5XDbWKVhjpUZ
Upvotes: 2
Reputation: 2135
Have you tried with @Inject ?:
import {Injectable,Inject} from "angular2/core";
import {Feature1Service} from "../feature1";
@Injectable()
export class Feature2Service {
constructor(@Inject(Feature1Service) protected _feature1Service: Feature1Service) {
}
}
Upvotes: 0