3

I am new to Angular. I am trying to inherit a base class by a component class. The base class looks like this.

export class QuestionBase<T>{
  value?: T;
  key?: string;
  label?: string;
  required?: boolean;
  order?: number;
  controlType?: string;


  constructor(options: {
      value?: T,
      key?: string,
      label?: string,
      required?: boolean,
      order?: number,
      controlType?: string
    } = {}) {
    this.value = options.value;
    this.key = options.key || '';
    this.label = options.label || '';
    this.required = !!options.required;
    this.order = options.order === undefined ? 1 : options.order;
    this.controlType = options.controlType || '';
  }
}

My component looks like this.

    import { Component, Input, forwardRef, Inject, Injectable, Optional  } from '@angular/core';
    import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
    import { QuestionBase, controlMetaData } from './question-base';

    @Component({
      selector: 'checkbox-control',
      templateUrl: './question-checkbox-component.html',
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => CheckboxControlComponent),
          multi: true
        }
      ]
    })

    export class CheckboxControlComponent extends QuestionBase<string> implements ControlValueAccessor { 
      controlType = 'checkbox';
      checkboxState = false;
      constructor(options: {} ={})  { 
         super(options);

      }
     writeValue(value: boolean ){
       this.checkboxState = value;    
     }
    registerOnChange(fn: any){

    }
    registerOnTouched(fn: any){

   }
}

This is throwing error: Can't resolve all parameters for CheckboxControlComponent: (?).

But it works fine when i try to inherit the baseclass by another class like below.

import { QuestionBase } from './question-base';

export class TextboxQuestion extends QuestionBase<string> {
  controlType = 'textbox';
  type: string;

  constructor(options: {} = {}) {
    super(options);
    this.type = options['type'] || '';
  }
}

Please let me know what is going wrong here.

rajesh
  • 2,354
  • 1
  • 12
  • 15
  • How do you provide `options` in your component? It should be token of DI mechanism. Angular reads information about types of constructor parameters – yurzui Jul 12 '17 at 13:38
  • If you are using barrels please remove barrels. Please see this [question](https://stackoverflow.com/questions/37997824/angular-2-di-error-exception-cant-resolve-all-parameters). – Prathmesh Dali Jul 12 '17 at 14:12

1 Answers1

1

If the subclass has a constructor, it needs to repeat all constructor parameters of the superclass and forward them to the superclass constructor. TypeScript or Angular DI doesn't automatically merge them.

Also the types of the parameters need to be known to Angulars DI. You don't instantiate component instances yourself in Angular, DI does that for you. For that DI needs to be able to come up with values for the parameters.

This therefore isn't a valid component constructor parameter type:

{
  value?: T,
  key?: string,
  label?: string,
  required?: boolean,
  order?: number,
  controlType?: string
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • sorry for my limited knowledge. But if i want to retain the baseclass like it is. How can i make the DI. How to make it valid parameter type? Can u plz elaborate with my code. – rajesh Jul 12 '17 at 13:42
  • You would need to create a class that matches that type, add the `@Injectable()` decorator and provide it somewhere. For more details see https://angular.io/guide/dependency-injection – Günter Zöchbauer Jul 12 '17 at 13:48