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

http://bit.ly/ADUnitTestingPost

The lies we tell ourselves using TypeScript

https://typescript-book.com

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.

any makes 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

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.

Underlying implementation details

Signals on their own are completely useless.

Creating

Creates:

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.