Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactivity in Angular with Signals

Dany Paredes
October 14, 2023
71

Reactivity in Angular with Signals

Talk about Reactivity in Angular with Signals

Dany Paredes

October 14, 2023
Tweet

Transcript

  1. @angular Defer views in Angular Dany Paredes GDE / Technical

    Writer Kendo Telerik Angular Reactivity with Signals
  2. About Me Dany Paredes 🏀 NBA, 🏆🅰ngular GDE Technical Writer

    for Telerik Google Dev Library http://danywalls.com
  3. export class App { ngZone = inject(NgZone); name = 'Angular';

    click() { //other code… this.ngZone.runOutsideAngular(() => { console.log("Hello Vienna"); } ); } } decoded Cipher
  4. @Injectable({ providedIn: 'root' }) export class CardsService { cards: Array<Card>

    = []; cardsleft: number = 3; lastClient = 'No clients yet!'; add(holder: string) { const card = { id: Math.random().toFixed(), holder, status: 'pending' }; this.cards = [...this.cards, card]; this.cardsleft--; this.lastClient = `Thanks ${holder}!!`; } } decoded Cipher
  5. export class App { private cardsService = inject(CardsService); cards =

    this.cardsService.cards; cardLeft = this.cardsService.cardsleft; lastClient = this.cardsService.lastClient; add(holder: HTMLInputElement) { this.cardsService.add(holder.value); holder.value = ''; } } decoded Cipher
  6. @Component({ selector: 'my-app', standalone: true, imports: [CommonModule], template: ` <h3>We

    have {{cardLeft}} cards {{lastClient}}</h3> <input type="text" #holder /> <button (click)="add(holder)">Save</button> <div *ngFor="let card of cards"> {{card.holder}} {{card.id}} </div> `, }) decoded Cipher
  7. Momentum forwards v15 v16 v17+ Angular Release User research and

    prototyping GitHub RFCs (Request for Comments)
  8. Developer Preview Momentum forwards v15 v16 v17+ Angular Release User

    research and prototyping GitHub RFCs (Request for Comments) Signal-based APIs
  9. Developer Preview Momentum forwards v15 v16 v17+ Angular Release User

    research and prototyping GitHub RFCs (Request for Comments) Support for inputs, outputs and queries Signal-based APIs
  10. Developer Preview Momentum forwards v15 v16 v17+ Angular Release User

    research and prototyping GitHub RFCs (Request for Comments) Fully zoneless apps Support for inputs, outputs and queries Signal-based APIs
  11. Reactivity Everywhere Precision Updates Lightweight Dependencies Signal primitives let you

    react to state changes anywhere in your code, not just components. Signals unlocks better performance- by-default - by minimizing the work Angular performs to keep your DOM up-to-date with precise writes. Signals are ~2KB* and fast. With no requirement to load third-party dependencies and no up-front startup cost when your page first loads. Build Faster Apps By Default
  12. signal A value that can tell Angular when it changes

    capable of notifying its context of future changes in its value 1. Signal
  13. signal A value that can tell Angular when it changes

    capable of notifying its context of future changes in its value 1. Signal
  14. First Last Full Name Emma Twersky Emma Twersky Dany Paredes

    Dany Paredes firstName = signal("Dany"); lastName = signal("Paredes");
  15. First Last Full Name Emma Twersky Emma Twersky Simona Cotin

    Simona Cotin firstName = signal("Simona"); lastName = signal("Cotin"); fullName = computed(() => firstName()+ " " + lastName());
  16. effect computed signal An effect is a side-effectful operation which

    reads the value of zero or more signals Automatically scheduled to be re-run whenever any of those signals is notified of a change 3. Effect
  17. export class App implements OnInit { count = signal(0); limitMessage

    = 'Feel free to click!'; constructor(): void { effect(() => { if (this.count() == 10) { this.limitMessage = 'You reached the limit, sorry'; } }); }
  18. Injection Context Effects is that they can only be used

    in an injection context Effects runInjectionContext
  19. injector = inject(Injector); ngOnInit(): void { runInInjectionContext(this.injector, () => {

    effect(() => { console.log(this.lastClient()); }) }); } Effects and Injection Context
  20. @Injectable({ providedIn: 'root' }) export class CardsService { cards =

    signal<Card[]>([]); cardSlots = signal<number>(3); lastClient = signal('No clients yet!'); add(holder: string) { const card = { id: Math.random().toFixed(), holder, status: 'pending', }; this.cards.update((p) => [...p, card]); this.cardSlots.update((p) => p - 1); this.lastClient.set(`Thanks ${holder}`!!); } } decoded Cipher
  21. @Component({ selector: 'my-app', standalone: true, imports: [CommonModule], template: ` <h1>{{title}}</h1>

    <h3>We have {{cardSlots()}} slots </h3> <p>{{lastClient()}}</p> <input type="text" #holder [disabled]="soldOut()"/> <button (click)="add(holder)" [disabled]="soldOut()">Save</button> <div *ngFor="let card of cards()"> {{card.holder}} {{card.id}} </div> `, }) decoded Cipher
  22. export class App { private cardsService = inject(CardsService); cards =

    this.cardsService.cards; cardSlots = this.cardsService.cardSlots; soldOut = this.cardsService.soldOut; lastClient = this.cardsService.lastClient; add(holder: HTMLInputElement) { this.cardsService.add(holder.value); holder.value = ''; } } decoded Cipher
  23. toSignal toObservable takeUntilDestroyed Get the current value of an Observable

    as a reactive Signal. Exposes the value of an Angular Signal as an RxJS Observable. Completes the Observable when the calling context (component, directive, service, etc) is destroyed. RxJS Interop