Decide on UI structure, if the new feature creates a module.
Decide on components to be built by category of presentational or container components.
Decide on redux state activities to be performed
Decide on redux actions, reducers, effects.
Coding rules
Any additional npm package, utility or pattern to be implemented must be discussed in the team for a review.
UI structure adheres to accepted Angular project guidelines.
UI State management pattern should be implemented as per redux state management guidelines.
Principles
LIFT – File and folder structure principle
Locate code quickly
Identify code at a glance
Flattest structure possible
Try to be DRY (don’t repeat yourself principle)
SOLID
Single responsibility principle
Open/closed principle
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
5 seconds rule
If you can’t understand code in 5 seconds, it probably needs refactoring.
5 seconds is a figure of speech but it means if you can’t figure it out quickly its a candidate.
Organization of Code for readability
Code
private variables
public properties
public methods
private methods
Grouped and sorted
Consistent naming and spelling matters
One item per file – Component, Directive, Services, Pipes (Doesn’t apply to domain/model objects)
Components
Before starting to code, identify smart vs. dummy components or container vs presentational components.
The component should deal with ONLY display logic.
Avoid logic in templates, it should talk to a model variable that is updated by logic in typescript file.
Prefixing component selectors
<app name>-<component selector> for application-wide components available in core and shared modules.
<app name>-<feature name>-<component selector> for feature module components.
Always use @Input() or @Output(), don’t declare them in @Component tag as it’s not recommended.
Maintain Immutability when passing data to child components. This will ensure that with reference bugs that are hard to find in JavaScript will not happen.
Safe Navigation Operator example *ngIf = “products.length” will fail if products is null/undefined, use “products?.length“
Class – Component/Service/Directives/Pipes/Interceptors etc
The class name and file name should be the same. eg product-list.component will have class as ProductListComponent.
Use Angular guidelines for suffixes such as Component, Service, etc.
The class name is PascalCase.
Class variables/attributes/properties are camelCase.
Class methods are camelCase.
Observable type variable names should suffix $ in its name.
Constant names are UPPER_CASE with an underscore between each word.
Class member sequence (Note variables/methods are public by default in TypeScript)
private variables
public properties
public methods
private methods
Declare actual type used to keep application TypeSafe. DON’T use any until the real type is unknown.
Always mark services as injectable
Services are singleton by default
Services, if declared as a provider in a lazily loaded feature module
Needs caution as you may end up having multiple instances.
Multiple instances may be needed at times but that should be the vision rather than an oversight.
Consider caching your request results
Service should contain all business and data manipulation Logic
No long methods/functions
Methods should be readable
It should follow the single responsibility principle
The cyclomatic complexity of the method should be low.
Apply 5 seconds rule to refactor
Follow DRY
If there is a code available, similar or few changed lines of code that duplicates same code needs refactoring
There should be only one copy of code if several implementations are needed it should be changed to apply DRY.
Replace magic strings with constants (code reuse)
Variable/method names should well define what it is doing or used for.
Consider caching your request results.
Use barrels to reduce the number of imports.
Use Aliases for imports as we do with @shared, @core to have smaller imports
Tests
Unit Tests are written to cover all public methods
Variables/Methods should be written with a correct scope such as public/private etc. The scope should not be elevated for unit testing purposes.
There should be negative and positive unit tests to cover both scenario’s
There should be one unit test per logical path, we should have multiple tests to cover the overall public method.
All dependencies of a Service or Component that is being tested should be mocked.
Any utility type dependency in service or component under unit test should NOT be mocked.
There can be more than one assertions in the unit test, There MUST be one assertion else it is not a test.
90% of code and test coverage is needed but the quality of the unit test is what matters.
Change in code SHOULD break unit tests.
A small set of data can be embedded in the unit test file. JSON injection is required, if we need a large set of data for unit tests.
Setup and BeforeEach block should setup initial data for each test. An override can be done for the respective test.
A unit tests should be small and readable – apply long method/function rules.