1/28/2019 - 12:32 PM

Angular / Typescript / RxJs - BEST PRACTICES

1) trackBy
When an array changes, Angular re-renders the whole DOM tree. But if you use trackBy, 
Angular will know which element has changed and will only make DOM changes for that particular element.

<li *ngFor="let item of items; trackBy: trackByFn">{{ item }}</li>

trackByFn(index, item) {    
   return item.id; // unique id corresponding to the item

2) Use pipeable operators when using RxJs operators.
Pipeable operators are tree-shakeable meaning only the code we need to execute will be included when they are imported.

3) Subscribe in template | async
async pipes unsubscribe themselves automatically and it makes the code simpler by eliminating the need to manually manage subscriptions. 
It also reduces the risk of accidentally forgetting to unsubscribe a subscription in the component, which would cause a memory leak.

4) Avoid having subscriptions inside subscriptions
Sometimes you may want values from more than one observable to perform an action. In this case, avoid subscribing to one observable
in the subscribe block of another observable. Instead, use appropriate chaining operators. 
Chaining operators run on observables from the operator before them. Some chaining operators are: withLatestFrom, combineLatest, etc
Code smell/readability/complexity: Not using RxJs to its full extent, suggests developer is not familiar with the RxJs API surface area.

5) Avoid any; type everything;
Па панятіям всьому вказувати тип так буде легше працювати з кодом + будуть перевірки під час компіляції TS
setting strict:true in the tsconfig.json file to enable all strict type checking options.

6) Small reusable components
Extract the pieces that can be reused in a component and make it a new one. Make the component as dumb as possible, 
as this will make it work in more scenarios. Making a component dumb means that the component does not have any special 
logic in it and operates purely based on the inputs and outputs provided to it.

As a general rule, the last child in the component tree will be the dumbest of all.
Reusable components reduce duplication of code therefore making it easier to maintain and make changes.
Dumb components are simpler, so they are less likely to have bugs. Dumb components make you think harder 
about the public component API, and help sniff out mixed concerns.

7) Components should only deal with display logic
Avoid having any logic other than display logic in your component whenever you can and make the component deal only with the display logic.
Components are designed for presentational purposes and control what the view should do. Any business logic should be extracted into its own 
methods/services where appropriate, separating business logic from view logic.
Business logic is usually easier to unit test when extracted out to a service, and can be reused by any other components that need the same business logic applied.

8) Avoid long methods
Long methods generally indicate that they are doing too many things. Try to use the Single Responsibility Principle. 
The method itself as a whole might be doing one thing, but inside it, there are a few other operations that could be happening.
We can extract those methods into their own method and make them do one thing each and use them instead.
Long methods are hard to read, understand and maintain. 
They are also prone to bugs, as changing one thing might affect a lot of other things in that method.
They also make refactoring (which is a key thing in any application) difficult.

9) Avoid logic in templates
If you have any sort of logic in your templates, even if it is a simple && clause, it is good to extract it out into its component.
Having logic in the template means that it is not possible to unit test it and therefore it is more prone to bugs when changing template code.

10) Strings should be safe (private myStringValue: 'First' | 'Second, enum: {})
If you have a variable of type string that can have only a set of values, instead of declaring it as a string type, 
you can declare the list of possible values as the type.
By declaring the type of the variable appropriately, we can avoid bugs while writing the code during compile time rather than during runtime.

11) Hot vs Cold Observables
When the data is produced by the Observable itself, we call it a COLD Observable. When the data is produced outside the Observable, we call it a HOT Observable.

Is one better than the other?
Well, that depends on the usecase. A cold Observable is usually fine, unless:
- You want to make sure multiple subscribers get the same data.
- Your creating a new instance of something on each Observable execution, let’s say a websocket connection. 
You don’t want to create a new connection for each subscriber, but instead just share it to all the subscribers. 
Moving the instantiation of the connection outside the Observable will make it hot and fixes this.