Analysis and Design activities
- 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
- Code
- 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.
Auto Amazon Links: No products found. WEB_PAGE_DUMPER: The server does not wake up: https://web-page-dumper.herokuapp.com/ URL: https://www.amazon.com/gp/top-rated/ Cache: AAL_048d91e746d8e46e76b94d301f80f1d9