We are upgrading to Angular 6 from 5. We have a shared library that we are getting build errors. Being a Java shop, we got in the habit of marking our component methods and attributes private. In Angular 6 when building our library (after converting and using the new library CLI capability), we get:
Property 'getCurrentYear' is private and only accessible within class.
In effect any attribute or method used in a template html cannot be marked private anymore on the component class. Of course we can fix this by removing the 'private' modifier. This was not the case in angular 5 when we produced our library using https://github.com/raphael-volt/ng2-testable-lib.
Oddly enough, this ONLY happens when compiling our library. We upgraded an app to angular 6 that also has private attributes and methods on the component / usage in template and no issues there.
Did we find a bug? Is there a best practice we are not adhering to?
The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.
Private methods are typically used when several methods need to do the exact same work as part of their responsibility (like notifying external observers that the object has changed), or when a method is split in smaller steps for readability.
Private methods can be implemented static or non-static. This means that in an interface we are able to create private methods to encapsulate code from both default and static public method signatures. bar() is able to make use of the private method baz() by calling it from it's default method.
In Angular we have 2 models of compilation
JIT - Just-in-Time Compilation : JIT compilation as the name implies, compiles the application Just-in-Time in the browser at
runtime.
AoT - Ahead-of-Time Compilation : AoT compilation compiles the application at build time.
By default, with the development build i.e ng serve
we get JIT compilation. This is how it works. The application code along with the angular compiler is downloaded by the browser. At runtime, when a request is issued to the application, the JIT-compiler in the browser compiles the application code before it is executed.
with the production build i.e ng build --prod
we get AoT compilation the angular application is pre-compiled. So this means the browser loads executable code so it can render the application immediately, without waiting to compile the application first.
TypeScript public
doesn't matter but private
does
From Angular Docs
Alldata bound
properties must be TypeScript public properties. Angular never binds to a TypeScript private property.
Actually, it does bind to the private
properties, but not in AoT mode
Why AOT Compiler requires public properties, while non-AOT allows private properties?
With JIT we convert all the code to ES5 and then at runtime, we do the bindings. All the visibility modifiers are lost in that process, so it doesn't matter if you say public
or private
for that.
On the other hand, with AoT, we generate some typescript code for our templates, that will try to access those fields. If they are private
, they simply cannot access those properties, hence, you need to put them as public
.
Properites used in templaes must be public - this is connected with AoT compilation.
https://angular.io/guide/aot-compiler (find word "public" there)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With