1

Using Angular 5 and TypeScript, in the following inheritance scenario, is it possible to not have to include MyService as an argument to the constructor of MyComponent?

export class CBasic {
    // properties and methods
}

export class CAdvanced extends CBasic {

    // constructor
    constructor(
        public myService: MyService
    ) {
        // call constructor of super-class (required)
        super();
    }

    // more properties and methods
}

export class MyComponent extends CAdvanced {

    // constructor
    constructor() {
        // call constructor of super-class (required)
        super(); // Error: [ts] Expected 1 arguments, but got 0.
    }
}

The error I am getting is [ts] Expected 1 arguments, but got 0. in MyComponent.

The point is I want to include MyService in CAdvanced to avoid code-duplication in classes that inherit from it, e.g. MyComponent.

4
  • 2
    Does the constructor in MyComponent do anything else? If not, you can just remove it. Commented Jul 29, 2018 at 16:36
  • 3
    This has nothing to do with "multiple inheritance". Commented Jul 29, 2018 at 16:45
  • @torazaburo Thanks, I have removed it from the title. Commented Jul 29, 2018 at 21:12
  • @ConnorsFan It may do something else. Commented Jul 29, 2018 at 21:12

1 Answer 1

4

You can make the injectable service a property.

export class CAdvanced {
    @Inject(MyService)
    public myService: MyService;

    constructor() {
    }
}

export class MyComponent extends CAdvanced {
    constructor() {
         super(); // no more error
    }
}

Angular will inject the service to the base class via the @Inject decorator.

Alternatively, you can make the parameter optional.

This will silence the error, but the value will be undefined.

export class CAdvanced {
    constructor(public myService?: MyService) {
        console.log(this.myService);
        // above will print undefined
    }
}

export class MyComponent extends CAdvanced {
    constructor() {
         super(); // no more error
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

The first solution is great, but what's the point of making it optional, since that will result in the service which I need not being injected?
@torazaburo I have no idea. The OP said he was getting a TypeScript error that the parameter was missing. Making it optional suppresses the error, and I do clarify that it becomes undefined. It's up to the OP to decide if that's how he/she wants to fix the error. Maybe there are some derived classes that have the parameter and others that don't. Who knows.
Are there any downsides or gotchas in doing your own @Inject(), compared to having Angular do it for your in the regular way? I seem to recall there's some way to specify injection directly in the constructor's parameter list--is that an option here?
@torazaburo The @Inject decorator is a standard Angular feature. It can be used in both the properties or constructor parameters. Ex constructor(@Inject(MyService) my:MyService). It is used where the DI type can not be inferred via the parameter type (i.e. injecting strings). You don't see inject done on properties because all the examples are via parameters, but there is nothing wrong with doing it that way. From JavaScript code it's basically the same thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.