Class is using Angular features but is not decorated. Please add an explicit Angular decorator

Viewed 71920

I have some components like CricketComponent, FootballComponent, TennisComponent etc. All These Classes have some common properties :- TeamName, teamSize, players etc which are @Input().

Now I created a BaseComponent class, defined all these properties in there and this baseComponent class will be extended by cricket/football/tennis/etcComponents.

baseComponent.ts

export class BaseComponent {

    @Input() TeamName: string;
    @Input() teamSize: number;
    @Input() players: any;

}

CricketComponent.ts

@Component({
  selector: 'app-cricket',
  templateUrl: './cricket.component.html',
  styleUrls: ['./cricket.component.scss']
})
export class cricketComponent extends BaseComponent implements OnInit {

  constructor() {
    super();
  }

  ngOnInit(): void {
  }

}

I am getting this error:

ERROR in src/app/base-screen.ts:4:14 - error NG2007:

Class is using Angular features but is not decorated. Please add an explicit Angular decorator.

6 Answers

You'll need to add a @Component decorator to that base class (which should probably also be declared abstract).

This is the bare minimum you can get away with in Angular 9:

@Component({
  template: ''
})
export abstract class BaseComponent {

    @Input() teamName: string;
    @Input() teamSize: number;
    @Input() players: any;
}

For Angular 10+, see this answer.

From Angular 10, you can fix this issue by adding the decorator @Injectable() to your abstract base class like this:

@Injectable()
export abstract class BaseComponent {    
    @Input() teamName: string;
    @Input() teamSize: number;
    @Input() players: any;
}

While the accepted answer is correct in using @Component, one minor downside is that it requires all constructor argument types to be resolvable by DI. So if your base class constructor takes a constant/literal - say, an enum - as a flag, you're going to have to set up a corresponding DI provider/token just to get it to compile.

You can however also resolve NG2007 using the @Directive decorator instead, which doesn't require DI compatibility

See also: Missing @Directive()/@Component() decorator migration

Before:

export class BaseComponent {
    @Input() TeamName: string;
    @Input() teamSize: number;
    @Input() players: any;
}

After:

@Directive()
export class BaseComponent {
    @Input() TeamName: string;
    @Input() teamSize: number;
    @Input() players: any;
}

For These errors : NG6001: The class 'XComponent' is listed in the declarations of the NgModule 'AppModule', but is not a directive, a component, or a pipe. Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.

NG2003: No suitable injection token for parameter 'A' of class 'Y'.

NG2007: Class is using Angular features but is not decorated. Please add an explicit Angular decorator.

You may be writing the new class between @Component declaration and Component class.

ex.

// export class Y{ // }

@Component({
  selector: 'app-X',
  templateUrl: './X.component.html',
  styleUrls: ['./X.component.css']
})



export class XComponent implements OnInit {

todos : Y[]  = [
  new Y(1 ),
  new Y(2 ),
  new Y(3 )
]
  
  constructor() { }

  ngOnInit(): void {
  }

}

//export class Y{ //}

i.e. if you have more than one class . let say class XComponent and Class Y, where class Y is being used in class XComponent , then write code for class Y either above @Component({}) or below class XComponent

Related