19

I have a Base Component extended by its children, but when we create a new Component in Angular using angular-cli it creates html and css files, but I will not use these files from base component.

Is there a way to create a Base Component without html and css?

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-base',
  templateUrl: './base.component.html', //I dont need this
  styleUrls: ['./base.component.css'] ////I dont need this
})
export class BaseComponent implements OnInit {

  constructor() {}

  ngOnInit() {}

}


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

import { BaseComponent } from '../base/base.component';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent extends BaseComponent {

  constructor() {
    super();
  }

  ngOnInit() {
  }

}
Tzippy Wo
  • 21
  • 6
brazuka
  • 1,011
  • 4
  • 13
  • 22
  • 2
    Omit `@Component` annotation in the base component. But I suspect you might be doing something wrong in general. Why do you want to have a base component in the first place? – s.alem Mar 16 '18 at 12:30
  • 1
    Cause I want to share some variables and methods which are in common in all the child components. – brazuka Mar 16 '18 at 12:33
  • 1
    Thanks, now it works. I removed @Component and remove it from module declarations. – brazuka Mar 16 '18 at 12:35
  • 2
    I would recommend a global service that you import into each component, much cleaner – Shane Mar 16 '18 at 12:36
  • @Szenmu call you provide an example? – brazuka Mar 16 '18 at 12:39
  • https://stackoverflow.com/questions/43991306/angular-4-5-global-variables/43991457 That would be a great example of what I mean there – Shane Mar 16 '18 at 12:46
  • 3
    I suggest using a base component class only if all of the sub classes are going to use all of the methods and fields that defined in base class. Otherwise you will end up with a lot of dead code when it's compiled to JS. – s.alem Mar 16 '18 at 12:49
  • @s.alem Can you please explain what you mean by dead code? I believe there is a reason why we've inheritance. I don't understand why nowadays Angular and React library authors don't care about that much! – VJAI Jul 20 '18 at 16:38

1 Answers1

29

Since base class doesn't need to be instantiated on its own, it's abstract class and doesn't need to have @Component decorator.

If it has dependencies, and there's a chance that constructor will be omitted in child classes and inherited, base class should have @Injectable decorator:

@Injectable()
export abstract class BaseComponent implements OnInit {
  constructor(public dep: Dep) {}

  ngOnInit() {}
}

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent extends BaseComponent {
  // dummy constructor can be omitted
/*
  constructor(dep: Dep) {
    super(dep);
  }
*/
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 2
    When I use "@Injectable()" my child component doesn't need to do "super()" call? – brazuka Mar 16 '18 at 12:56
  • 3
    Yes. And you don't need `@Injectable()` if base class doesn't have dependencies. – Estus Flask Mar 16 '18 at 12:58
  • @EstusFlask that's a nice trick with `@Injectable()`. Why does it work? Is it documented somewhere officially? – bersling Sep 29 '19 at 05:38
  • @bersling Yes, https://angular.io/api/core/Injectable . See also the explanation on how it works, https://stackoverflow.com/a/39029435/3731501 – Estus Flask Sep 29 '19 at 09:31
  • Thanks @EstusFlask , but is it okay if we don't put any decorator and just make it an abstract class? Neither `@Component` nor `@Injectable`? It works fine but I'm just thinking about what could go wrong? – Rachit Kyte.One Feb 20 '20 at 17:40
  • 1
    @RachitMagon IIRC this depended on Angular version and AOT/JIT compiler. I'm positive omitted `@Injectable` caused problems at some point. The provided way (a decorator on both parent and child) is a way it's guaranteed to work. For the record, did you use latest version and AOT? – Estus Flask Feb 20 '20 at 17:48
  • Thanks for your reply, I'm using Angular 8 & JIT – Rachit Kyte.One Feb 28 '20 at 18:06