NG-BE 2023
tags:: Angular #source/lecture Lab900
Keynote
Required input parameters
Automated migration and Ng new with standalone
Angular image component
Images are key factor in LCP and Cumulative Layout Shift
Test Harness
What is it
All Angular Material components have harnesses so you don't have to go through the HTML API. It uses the test harness CDK thing.
await loader.getHarness(MatInputHarness);
Harness loader can load components in the context of the component under test.
Filters
const leMyComponent = MatInputHarness.with({
value: 'blabla'
})
Doing it for your own components
- Extend the
BaseComponentFiltersinterface so you an add your own - Create a
MyComponentHarness extends ComponentHarness - Implement the methods that others might want to use when using your component in their tests
- Treat it like you're publishing an API
- Implement the locator method too
http://bit.ly/ADUnitTestingPost
The lies we tell ourselves using TypeScript
Star Wars API: https://swapi.dev
A Tale of Fetch
any makes Typescript stop complaining. When you're using it, you must add extra checks ot make sure things are correct. Use unknown.
anymakes things go boom
A type assertion is an unsafe operation. Just like type predicates (asserting type through a method).
Improving fetch
By default it's any but with type declaration merging we can improve it
declare global {
interface Body {
json(): Promise<unknown>;
}
}
Now we properly get errors until we assert types.
The Theme is Dark and Full of Errors
Never blame the developers, always blame the tools.
You can throw anything. So you never know the type of the thing that ends up in your catch block.
throw '💩';
Use unknown in catch and then instanceof checks.
tsconfig.json: useUnknownInCatchVariables so it's not any.
The Matrix Overloaded
Use conditional types, it is often better than method overloads.
The Virtues of Something Something
Typescript does not check control flow, and it won't change the type of a variable.
Use generic types, they're often a magic bullet. T extends Array<A | B> instead of just Array<A | B>. They narrow down.
The Final Chapter: Lies with Typescript
Global merging
Nothing in Typescript tells you when you're accidentally merging with globals.
Instanceof lies
You can Duck type and it'll accept it, but it would fail the instanceof check. Typescript is structurally typed.
Conditional Types are complicated
But I still love it
Typescript is my second favorite programming language.
Partial DOM Hydration
Resumability
Quik framework does this and had incredible first load times
architecture
Linter eslint sheriff plugin to prevent imports from unrelated directories. Then your can organize per feature of domain.
Use index file to create a public API for these folders.
Create a custom provideX method for your library. The implementation should call makeEnvironment something.
Reactive Angular Enterprise
ViewModel pattern
Define a single observable that calculates all the properties for the template.
public readonly vm$: Observable<ViewModel> = combineLatest({
...stuff$
}).map(() => something);
His @InputState() cleans up the input values.
https://github.com/simplifiedcourses/observable-state/tree/main/src
- Observable of inputs
- Only one emission
- Distinct all props until changes
- No more take until destroy
Improving it
Debounce will trigger a change detection cycle?
With multiple subjects and combinelatest it's easy to trigger multiple emissions accidentally because you just wanted to patch a few parts of the state.
Observable local component state
Also in the repo, "check the source code because it's very simple."
Good idea to treat components as tiny state machines.
refCount: true is important when you're sharing replay 1. Why?
State + VM
A state observable, that can connect to any observable, and maps into a view model.
Global State
Provide'able state so you can choose where to create it.
SIP Principle: Source / Intermediate / Presentation observables.
Signals
Wellllll they are all of this.
In his presentation he refactored it to signals.
NGBE-23 discount.
Signal Shit (Reactive Angular at its Core)
Value in a box. Always has a value. Signals changes.
Function call is value access + implicit subscription.
Will be backwards compatible.
Signals
Michael is Czech.
- "Clever use of WekRef to avoid explicit subscription management."
- Promised RxJS two-way integrations
Underlying implementation details
Signals on their own are completely useless.
Creating
Creates:
- The box
- A list of observers (now empty)
Update
Goes over observers and notifies them.
Get Value
Adds "global active context" to the observer. Sort of a global variable.
If there's no activeContext, nothing happens.
Effect
Within the lambda, the effect is set as active context.
Computed
A computed is lazy. They do the dependency tracking but only execute lazily.
Implementing fine-grained reactivity
Basically Rx-Angular + Signals. They want to mix in signals in their library and add interop.
Push pipe will work with signals too.
Basically, PushPipe does detectChanges instead of markDirty, which prevents rechecking the entire tree. By default it marks everything and rerenders it all on the next tick() triggered by Zone.
Structural directives create an embedded view that has its own detect changes method. So when you use rxLet you can trigger change detection only on that sub-part.