ThreeAccents
ThreeAccents

Reputation: 1882

Dependency injection Angular 2

I'm trying to inject a service to my component but I keep getting an error.

This is my component:

import {Component, View} from 'angular2/angular2';
import {DisplayService} from '../../services/DisplayService';

@Component({
  selector: 'display'
})
@View({
  templateUrl: './components/display/display.html',
  styleUrls: ['./components/display/display.css']
})
export class Display {
  displays: Array<any>;

  constructor(public displayService: DisplayService){

  }
}

This is my service:

import {HTTP_BINDINGS, Http} from 'http/http';

export class DisplayService {
    displays: Array<any>;

    constructor(public http: Http){

    }

    getDisplays() {
        var path = 'http://localhost:8000/get';
        this.http.get(path)
    }
}

And this is my main component:

import {Component, View, bootstrap} from 'angular2/angular2';
import {HTTP_BINDINGS, Http} from 'angular2/http';

import {DisplayService} from './services/DisplayService';

@Component({
  selector: 'app',
  viewBindings: [DisplayService]
})
@View({
  templateUrl: './app.html',
  styleUrls: ['./app.css']
})
class App {}

bootstrap(App, [ROUTER_BINDINGS, HTTP_BINDINGS]);

EXCEPTION: Error during instantiation of Token(Promise<ComponentRef>)!.

ORIGINAL EXCEPTION: Cannot resolve all parameters for DisplayService(?). Make sure they all have valid type or annotations.

I tried passing in the Http package when I'm injecting the service into the component but also just threw an error.

Upvotes: 1

Views: 748

Answers (2)

ThreeAccents
ThreeAccents

Reputation: 1882

After reading the articles provided in the comments by @EricMartinez I realized what was wrong since the service class is so barebone it doesn't produce the meta data needed for the di framework to work. So here is how my code looks like now:

Component:

import {Component, View, NgFor} from 'angular2/angular2';

import {Subbar} from '../subbar/subbar';
import {DisplayCard} from '../display-card/display-card';

import {DisplayService} from '../../services/display_service';

@Component({
  selector: 'display'
})
@View({
  templateUrl: './components/display/display.html',
  styleUrls: ['./components/display/display.css'],
  directives: [Subbar, DisplayCard, NgFor]
})
export class Display {
    displays: Array<any>;

    constructor(public displayService: DisplayService){
        displayService.getDisplays()
            .toRx()
            .map(res => res.json())
            .subscribe(displays => this.displays = displays.screens);
    }
}

Service:

import {Http} from 'angular2/http';
import {Injectable} from 'angular2/di';

@Injectable()
export class DisplayService {
    constructor(public http: Http){

    }

    getDisplays() {
        var path = 'http://localhost:8000/getscreens';
        return this.http.get(path);
    }
}

As you can see adding the @Injectable() forces the meta data generation. Another option to set up your service is to do this:

import {Http} from 'angular2/http';
import {Inject} from 'angular2/di';

export class DisplayService {
    constructor(@Inject(Http) http: Http){

    }

    getDisplays() {
        var path = 'http://localhost:8000/getscreens';
        return this.http.get(path);
    }
}

Its up to taste I just found the first way to do it cleaner.

Upvotes: 2

kit
kit

Reputation: 4920

You have to import

import {Injectable} from 'angular2/core';

into your service and put @Injectable annotation at the top of DisplayService.

The last thing is to put DisplayService into bootstrap binding parameter.

Upvotes: 1

Related Questions