TIL, 2021-12-29, NgRx selector test,s `SharedModule`
How I test my NgRx selectors
- What is a selector?
- A selector is a pure function that takes the state as an argument and returns a slice of the store state.
- Because selectors are pure functions, it can optimise itself via memoization.
- What to test: Just test the ones with logic in them.
- Ways of testing
toBe
- just returning a slice of store state - getter.- Snapshot
- Projector - Use
projector
function to skip execution from other selectors and pass their outputs to the selector.
Angular 2: Difference between property binding with and without brackets?
- Template syntax.
- Omit the brackets when these are true:
- Target property accepts a string, the string is fixed, and this initial value never changes.
- The brackets, [], tell Angular to evaluate the template expression. If you omit the brackets, Angular treats the string as a constant and initializes the target property with that string.
- So in the translation case, we do want to treat it not as a constant.
- When you use square brackets, the right hand side is an expression. When you use no brackets at all, the right hand side is a constant.
- Interpolation vs brackets?
Eliminating Shared Module(s)
- Where do the boundaries exist within a split shared module? And what happens if I create a smaller
SharedModule
for Feature X and Feature Y? - “For each component, we create an
NgModule
that imports only the declarables used by that specific component. Likewise, it only declares and exports that single component.” - Later on, when Ivy renderer is out, I can ditch the module file and put all the dependencies into a component file:
import { NgIf } from '@angular/common';
import { MatSelect, MatOption, MatFormField } from '@angular/material';
@Component({
selector: 'app-backup-selector',
templateUrl: './backup-selector.component.html',
styleUrls: ['./backup-selector.component.scss'],
deps: [
NgIf,
MatSelect,
MatOption,
MatFormField
]
})
export class BackupSelectorComponent implements OnInit {}
- SCAM makes it easier to migrate to the Ivy renderer.
- For new applications I recommend not using Shared Module at all, but using a shared folder which contains all the SCAMs imported by other Feature modules instead.
Your Angular Module is a SCAM!
A Scalable Angular Project Structure
Angular Revisited: Tree-shakable components and optional NgModules
- In the current Angular generation, a component can and must only be declared in a single
NgModule
. Thedeclarables
that can be used are determined at compile time from the metadata of its declaring Angular module. - Transitive scopes:
- Transitive compilation scope: All the declarables that the Angular module can use in its template.
- Transitive exported scope: All the declarables in
exports
. It can also re-export other Angular modules by listing them in that same option.
@NgModule({
declarations: [HeroComponent, HeroListComponent],
imports: [CommonModule],
})
export class HeroModule {}
- This means that
HeroComponent
can referenceHeroListComponent
because it declares itself. And it can also useNgIf
since it is importingCommonModule
. - Reference suggests that components itself will have those
deps
, thus bypassing Angular module. - Local component scope: Reference
- SCAM:
- Sure, it is a bit more work but I actually started doing this in most places anyways. It makes it easier to maintain a current list of declarable dependencies to keep a small bundle size.
- When looking at a SCAM, we only have to consider a single component to determine whether an Angular module import is in use.
-
The goal: