10

I struggle to understand which methods should be private and which should be public in component class.

It seems to be fairly easy in service to judge if method is public or private e.g:

export class MyServiceClass {
  private _cache = {}; // this value is private and shouln't be accessed from outside
  public accessCache(){ // it's public as it's an API method
    return this._cache;
  }
  public setCache(newVal){
     this._cache = newVal;
  }
}

Following that logic all methods in component should be private because none of the methods should be exposed outside of the class. (according to to that post component and its view are one entity)

export class MyComponent {      
  private _getRandomNumbers(){ // this is used in view only
    /*..*/
  }
}

There is no tragedy but then in this video you can learn that only public methods of component should be unit tested. By following above I can't find any reason to have public methods in component class but I still have some methods which are worth testing (especially methods used in view). It means that I'm completely lost in the meaning of private and public methods in angular world.

So my question is simple:

which methods in components should be marked as public and private.

LJ Wadowski
  • 6,424
  • 11
  • 43
  • 76
  • 1
    Why does the statement from the video cause confusion? It's normal to only test the public API of a component. – Günter Zöchbauer Jun 22 '16 at 14:02
  • You usually have inputs and outputs and dependencies that are injected that get methods called by the component or provide observables to subscribe. You can also access the resulting DOM and test if it contains the expected content. – Günter Zöchbauer Jun 22 '16 at 14:37
  • @GünterZöchbauer It's because following this logic when all methods in component are private (used only internally or in component template) there is nothing to test. – LJ Wadowski Jun 22 '16 at 14:37
  • 2
    If you want to test the component class (controller only) without investigating the resulting view, then I guess it makes sense to treat the view as a different unit and make all members that are accessed by the view public instead of private. – Günter Zöchbauer Jun 22 '16 at 14:40
  • 1
    @GünterZöchbauer That's quite a valid question that applies more to Typescript best practices rather than to Angular. Considering private methods a blackbox harms testability a lot. Private members should be reachable, spyable and mockable. Can `reflect-metadata` help with that? I've encountered it in utilitarian contexts (DI) but never for basic reflection. – Estus Flask Jun 22 '16 at 14:46
  • @GünterZöchbauer I think your last comment pushed me in right direction, somehow I wasn't thinking about testing component together with its template which seems to have a lot of sense. – LJ Wadowski Jun 22 '16 at 14:50
  • Might be related http://stackoverflow.com/questions/34574167/angular2-should-private-variables-be-accessible-in-the-template/36593845#36593845 – Günter Zöchbauer Jun 22 '16 at 14:51
  • When you use `TestComponentBuilder` then you have access to the created DOM. I think this is the common way to test components. I think components are usually about updating the DOM. If you have complex logic it should be moved to a service anyway (AFAIR from the style guide). – Günter Zöchbauer Jun 22 '16 at 14:53

1 Answers1

6

In Component Class, I would say, set everything as public (if no access modifier, it's public by default).

In normal case, we don't extends a component class, therefore, access modifier is not needed, IMHO.

There are cases where we will inherit a component. See here component inheritance in Angular 2. However, even in these cases, access modifier might not be necessary.

...

export class MyComponent {
  // injected service as private
  constructor(private _randomSvc: RandomService) {} 

  getRandomNumbers(){ } // leave it as public

  @Input()
  myInput: string; // leave it as public

  @Output()
  myOutput; // leave it as public
}

Remember Javascript itself has NO access modifier. The access modifier only applicable during development(IDE). While modifier is useful in some cases, I would suggest minimise the usage of that.

Jecfish
  • 4,026
  • 1
  • 18
  • 16