user1176058
user1176058

Reputation: 676

Angular 2 - DI not working

I created 2 implementations for an interface and provided those implementations as providers for two different components. I get this error Error: Can't resolve all parameters for ChildComponent: (?).

Where am I doing it wrong?

interface MyInterface {
    log(msg: string): void
}

class DebugService implements MyInterface {
    public log(msg:string) {
        console.debug(msg);
    }
}

class ErrorService implements MyInterface {
    public log(msg: string) {
        console.error(msg);
    }
}


import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<div (click)="log()">Root Component</div><my-child></my-child><my-child></my-child>' //app/app.component.html
    , providers: [DebugService]
})
export class AppComponent {
    private dummy: MyInterface;
    constructor(d: MyInterface) {
        this.dummy = d;
    }
    log() {
        this.dummy.log("Root");
    }
}


@Component({
    selector: 'my-child',
    template: `<h4 (click)="log()"> Hello Child</h4>`,
    providers: [ErrorService]
})
export class ChildComponent {
    private dummy: MyInterface;
    constructor(d: MyInterface) {
        this.dummy = d;
    }
    log() {
        this.dummy.log("Child");
    }
}

Upvotes: 0

Views: 203

Answers (2)

user1176058
user1176058

Reputation: 676

According to Angular website, "The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. The JavaScript language doesn't have interfaces. Angular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript."

For this very reason, we cannot use an interface to request a concrete implementation.

@Injectable() is not a required decorator for DI to work. It is adorned on a service class only if that service depends on some other service.

Upvotes: 0

nickspoon
nickspoon

Reputation: 1397

To use Dependency Injection, you need to mark the services with the @Injectable decorator. Also, you won't be able to inject the interface, you'll need to inject the class you've provided.

@Injectable()
class ErrorService implements MyInterface {
    public log(msg: string) {
        console.error(msg);
    }
}
@Component({
    selector: 'my-child',
    template: `<h4 (click)="log()"> Hello Child</h4>`,
    providers: [ErrorService]
})
export class ChildComponent {
    constructor(private dummy: ErrorService) {}
    log() {
        this.dummy.log("Child");
    }
}

Upvotes: 2

Related Questions