Rainer Hahnekamp
Rainer Hahnekamp
  • 34
  • 136 857
Reactive Contexts
In this video, we delve into the concept of Reactive Contexts in Angular and their crucial role in making Signals reactive. You'll learn:
🚦 What a Reactive Context is and why it is essential for Signals.
🚦 How the effect function creates a Reactive Context.
🚦 How a Reactive Context functions within an Angular template.
🚦 The slight differences between the effect function and template Reactive Contexts.
🚦 Why effect might get triggered more frequently than templates and why this behavior is not problematic.
The repository is available at github.com/rainerhahnekamp/reactive-contexts.
There is also a much more detailed video on Signals, which you can find at ua-cam.com/video/6W6gycuhiN0/v-deo.html.
0:00 Introduction
1:38 Reactive Context via Template
5:19 Reactive Context via effect()
6:14 Different Behavior
8:18 "Does it matter?"
11:45 Farewell
Переглядів: 2 471

Відео

Signals Unleashed: The Full Guide
Переглядів 18 тис.3 місяці тому
This video is your one-stop guide to Signals in Angular (as of 17.3). We'll dive deep into: ✅ Essential functions: signal, computed, and effect explained. ✅ Reactive Context: Understand where it lives and how to use it. ✅ Glitch-free effects: Why this behavior is a strength, not a bug. ✅ Angular's safety net: Learn how Signals prevent cyclic dependencies and manage side effects effectively. ✅ S...
How do I test Signals (signal / computed / effect)
Переглядів 2,6 тис.4 місяці тому
Signals as lightweight "reactive primitive" will shape the future of Angular applications. At the time of this recording, signal() and computed() are stable, and effect() is in "developer preview". We see increasing integration of Signals into the Angular API, and there should be no more reason to hold us back from using Signals. What are the requirements? First, we must understand Signals' beh...
How do I test Components & Routing with the RouterTestingHarness
Переглядів 6574 місяці тому
Tired of writing boilerplate code to test Angular components with router-specific data? The RouterTestingHarness is your new best friend! This video dives deep into this under-appreciated Angular testing tool, showing you how to: - Simplify tests involving ActivatedRoute and dynamic router parameters. - Reduce boilerplate code and write cleaner, more maintainable tests. - Navigate to specific r...
How do test code using inject()
Переглядів 1,1 тис.4 місяці тому
Angular's inject function has been available since version 14 and was - next to Standalone Components - the star feature. In this video, I explain why you want to switch from constructor-based dependency injection to inject(), although it doesn't make testing easier. A bit about the difference between inject and TestBed.inject and finally, the TestBed.runInInjectionContext, which you require fo...
How do I test and mock Standalone Components
Переглядів 2,5 тис.4 місяці тому
Angular's Standalone Components offer the advantage of including all their sub-components, directives, and pipes, making them ideal for comprehensive testing of a component's complete functionality. However, there are scenarios where we may want to mock specific parts of the dependency tree, particularly when dealing with a dependency that brings along an extensive set of additional dependencie...
NgRx Signal Store Trilogy, Part 2: The Missing Piece to Signals
Переглядів 3,7 тис.5 місяців тому
The NgRx Signal Store is more than just a contemporary state management library. It seamlessly integrates with Angular's Signals, inheriting powerful features such as computed Signals, immutability, and reactivity. On top of them, it adds advanced functionalities like patching, automated nested Signals, coupled logic, and seamless integration with RxJs. Join me in this video as we delve into th...
NgRx Signal Store Trilogy, Part 1: Why, When, and How?
Переглядів 13 тис.6 місяців тому
NgRx, the reigning champion of state management in Angular, has taken a significant leap forward by introducing the NgRx Signal Store. Joining the ranks of the Global and Component Stores, the Signal Store represents the third evolution of NgRx's state management prowess. This video starts with Signals and explores why they necessitate a more sophisticated state management approach. We then shi...
Angular's Change Detection
Переглядів 6 тис.7 місяців тому
In this video, we delve into Angular's rendering behavior in version 17, examining how Angular responds to changes triggered by user interactions or tasks and how it updates the DOM accordingly. At the heart of this process is Angular's Change Detection mechanism, which operates seamlessly in its default state. However, there are scenarios where fine-tuning is necessary for improved performance...
Introducing Playwright
Переглядів 2,9 тис.7 місяців тому
This video serves as an introduction to Playwright, a high-performance End-to-End (E2E) testing framework developed by Microsoft known for producing reliable tests. As of the end of 2023, it has nearly caught up with Cypress in terms of download numbers. I'll walk you through the basics of Playwright, such as selecting and interacting with elements, and how to perform assertions. The video also...
OpenAPI with Spring & Angular
Переглядів 1,7 тис.8 місяців тому
In this video, I explain how to use the OpenAPI for type-safe communication between Spring and Angular. I will also do an application walkthrough, where I explain a minimal Spring application, which uses the latest features of Spring Boot 3 (for example Testcontainers). The GitHub repository is available at github.com/rainerhahnekamp/spring-angular-openapi 0:00 Introduction 1:14 Theory 6:53 App...
GraalVM and Spring
Переглядів 1 тис.8 місяців тому
Delve into the fascinating world of GraalVM in this video, with a special emphasis on its native image feature. Explore its origins, discover the advantages it offers, and gain insights into its inner workings. I'll also discuss potential limitations and examine its current status within Spring Boot and Spring AoT. Join me for an enlightening journey through the realms of GraalVM! #GraalVM #Nat...
Angular Signals enforce Immutability in v17
Переглядів 2,2 тис.9 місяців тому
I show you in this video that the latest stable version of the Angular Signals will have a breaking change with potentially huge consequences. It is not the missing mutate function, but the internal equality check. They cause that Signals will not trigger if we change them mutably. Here is a more detailed article: tinyurl.com/signal-eq-fn
Cypress and Playwright: A Comparison
Переглядів 7 тис.9 місяців тому
In this video, I compare the two E2E testing frameworks Cypress and Playwright. It should give you enough information to make the right decision for your project. 0:00 Welcome 1:33 Technological Approach 16:32 Developer Experience 24:22 CI 33:06 Coding 51:19 Architecture & Extensibility 58:49 Misc. Features 1:04:24 Summary & Farewell
NgRx Best Practices - Episode 4: Facade Pattern
Переглядів 4,3 тис.Рік тому
This video covers the facade pattern in NgRx. What it is, how it is implemented, and what advantages it offers. GitHub Repo: github.com/rainerhahnekamp/ngrx-facades 0:00 Introduction 0:54 Theory 5:30 Implementation 14:02 Advantage I: Decoupling & Simplification 18:05 Advantage II: Integrated Logic 21:08 Advantage III: "Elevated Selectors"" 30:50 Advantage IV: Testing 34:37 Summary & Farewell
Angular Testing in 2023: Past, Present, and Future
Переглядів 11 тис.Рік тому
Angular Testing in 2023: Past, Present, and Future
Angular Unit Tests with the inject() function
Переглядів 5 тис.Рік тому
Angular Unit Tests with the inject() function
Angular 15: Responsive Images with NgOptimizedImage, provideHttpClient, Directive Composition API
Переглядів 2,9 тис.Рік тому
Angular 15: Responsive Images with NgOptimizedImage, provideHttpClient, Directive Composition API
Type-Safe TypeScript with Type Narrowing
Переглядів 1,6 тис.Рік тому
Type-Safe TypeScript with Type Narrowing
Angular 14.2: NgOptimizedImage & provideRouter
Переглядів 1,3 тис.Рік тому
Angular 14.2: NgOptimizedImage & provideRouter
Angular 14.1
Переглядів 799Рік тому
Angular 14.1
Cypress Component Testing in Angular
Переглядів 12 тис.Рік тому
Cypress Component Testing in Angular
Migrating/Updating to Angular 14
Переглядів 4,5 тис.2 роки тому
Migrating/Updating to Angular 14
Angular Standalone Components and their Impact on Modularity
Переглядів 8 тис.2 роки тому
Angular Standalone Components and their Impact on Modularity
Deep Linking in a Single Component
Переглядів 1,9 тис.2 роки тому
Deep Linking in a Single Component
NgRx Best Practices - Episode 3: Routing & other Deferrals
Переглядів 2,4 тис.2 роки тому
NgRx Best Practices - Episode 3: Routing & other Deferrals
NgRx createFeature
Переглядів 1,8 тис.2 роки тому
NgRx createFeature
NgRx Best Practices - Episode 2: Architecture & Modules
Переглядів 4,4 тис.2 роки тому
NgRx Best Practices - Episode 2: Architecture & Modules
NgRx Best Practices - Episode 1: Cache & LoadStatus
Переглядів 4,5 тис.2 роки тому
NgRx Best Practices - Episode 1: Cache & LoadStatus
NgRx Best Practices - Folge 1: Cache & LoadStatus
Переглядів 6132 роки тому
NgRx Best Practices - Folge 1: Cache & LoadStatus

КОМЕНТАРІ

  • @prasoon2510
    @prasoon2510 День тому

    If i need to do some operations based on signal data, how to do that in component.. Not able to do that

    • @RainerHahnekamp
      @RainerHahnekamp День тому

      Hi Prasoon, generally speaking, that's what an effect is for. Can you maybe give me a concrete example?

    • @prasoon2510
      @prasoon2510 День тому

      @@RainerHahnekamp Yes I used effect and it works.. Can we use multiple effect of same component or not??

    • @RainerHahnekamp
      @RainerHahnekamp День тому

      @@prasoon2510 Yes, you can have as many effects as you want.

    • @prasoon2510
      @prasoon2510 20 годин тому

      @@RainerHahnekamp Thank you so much for the quick response 😊❤️

    • @RainerHahnekamp
      @RainerHahnekamp 14 годин тому

      @@prasoon2510 You are very welcome. If something is still unclear, let me know

  • @SaleemKhan17
    @SaleemKhan17 2 дні тому

    Can you share your vscode extensions?

    • @RainerHahnekamp
      @RainerHahnekamp День тому

      Saleem, that's IntelliJ what I'm using. If you mean the inlay Hints, they are available in VSCode as well: code.visualstudio.com/docs/typescript/typescript-editing#_inlay-hints

  • @n8_may
    @n8_may 3 дні тому

    @20:16 I believe exhaustMap() should be used over switchMap(). switchMap() would restart the stream rather than ignoring subsequent ones

    • @RainerHahnekamp
      @RainerHahnekamp 3 дні тому

      If I use an exhaustMap and switch quickly between page 2, 3 and 4, it could happen that requests for 3 and 4 are not processed. exhaustMap waits for the inner observable to complete and ignores all incoming values from the outer observable. So for pagination, you usually go with switchMap.

  • @emilsirbu236
    @emilsirbu236 4 дні тому

    As always super valuable content, thanks Rainer! 💪

  • @lahcenaouina
    @lahcenaouina 4 дні тому

    Can please do a video explain how to manage cach (CRUD with Pagination) using ngRX

    • @RainerHahnekamp
      @RainerHahnekamp День тому

      Hey, I'm not sure if CRUD + Pagination is enough for a complete video but I can answer specific questions, if you have any. What are you struggling with? In the end you have a list of entities with the CRUD actions and additional actions to swtch pages.

  • @meerawisniewski1351
    @meerawisniewski1351 5 днів тому

    Great example. What if my load method takes 2 more parameters they are signals? Do i need separate state for that? would my load method will call when those values changes? Currently i am using angular effects with signals and effects for loading data gets called when any of those values changes.

    • @RainerHahnekamp
      @RainerHahnekamp 5 днів тому

      Thanks. If the parameteruses is a Signal, rxMethod applies an effect to it. If it is an Observable, it subscribes to it. Every time an Observable emits or Signal emits (careful with glitch-free), the inner Observable is executed. To put it short for Signals: rxMethod is just a wrapper around the effect function with an untracked in it. Did I answer your questions?

  • @aymensellaouti5007
    @aymensellaouti5007 8 днів тому

    Great Job. Thank you for all the videos and articles you share with the community, it helps a lot.

    • @RainerHahnekamp
      @RainerHahnekamp 8 днів тому

      Thanks, I hope I can publish new videos very soon.

  • @uchto4
    @uchto4 9 днів тому

    I'm always thinking about the glitch-free-effect. What if I call a method for example twice with different inputs? Will the first one be gone? What if I want to use the signalstore for events . I fill a buffer with events from a websocket. Will I lose data? I really like the signal store, but I can't get my head around this. :o

    • @RainerHahnekamp
      @RainerHahnekamp 5 днів тому

      So if you call a method twice synchronously, the first one will be dropped. WebSocket messages usually arrive asynchronously, so they won't be dropped by the glitch-free effect. You can use the SignalStore for events with rxMethod, but you have to think what type you use to represent that event. I would avoid putting an event into as Signal, usually the events comes from an Observable or an event listener (also works without rxMethod). Observables and event listeners are both fine. If you end up having dependencies between signal stores, then you will very quickly have an event in the form of a Signal. You might now be worried about the glitch-free effect, but from my experience, it is very rarely a real issue.

  • @dezee2412
    @dezee2412 12 днів тому

    A very informative and well-presented video, thanks Rainer I learnt a lot .

  • @zajunc69
    @zajunc69 14 днів тому

    22:25 - why this child component is not updating itself? It has ChangeDetectionStrategy.Default and setInterval inside of it. My understanding is that it's because setInterval is a global action on Window and ChangeDetectionStrategy.OnPush in ListComponent is blocking tick() to propagate down to TimerComponent, am I right?

    • @RainerHahnekamp
      @RainerHahnekamp 13 днів тому

      YES, I don't have anything to add to your statement. 💯 correct

  • @ml_serenity
    @ml_serenity 20 днів тому

    Regarding 46:00 I think it's much simpler: the effect() takes an arrow function. If no signals inside that function emitted changed value since last change detection cycle, then the whole arrow function is not executed, but if any one or more have their values changed, then the whole arrow function is executed. Also, I believe it uses reference equality to tell if signal should produce a new value to consumers. That's why immutability of the internal state is so important.

    • @RainerHahnekamp
      @RainerHahnekamp 20 днів тому

      Hi, what do you mean exactly? The dynamic tracking is an advanced feature and I guess not used in the majority of use cases.

    • @ml_serenity
      @ml_serenity 19 днів тому

      @@RainerHahnekamp I mean the logic to run or not run the effect lambda is probably determined by whether any one or more of the tracked signals associated with it have a new value or not.

    • @RainerHahnekamp
      @RainerHahnekamp 17 днів тому

      @@ml_serenity Yes, but dynamic dependency tracking does exist: github.com/angular/angular/tree/main/packages/core/primitives/signals#dynamic-dependency-tracking

  • @mohsenarshad1588
    @mohsenarshad1588 25 днів тому

    This video is beyond awesome, thanks a lot for giving so many details and clear explanation.

  • @DerAlexD
    @DerAlexD 25 днів тому

    yet one question remains how do i test signalStores

    • @RainerHahnekamp
      @RainerHahnekamp 25 днів тому

      I guess, you've already found my other video on how test Signals, right ;)

    • @DerAlexD
      @DerAlexD 25 днів тому

      @@RainerHahnekamp Yep thanks :)

  • @DerAlexD
    @DerAlexD 26 днів тому

    very good video, so same method applies to my signalStore, or do i have to do something different ?

    • @RainerHahnekamp
      @RainerHahnekamp 25 днів тому

      Yes, the SignalStore is an Angular Service which exposes native Signals. All things apply there as well.

  • @rishukumar7586
    @rishukumar7586 27 днів тому

    why jasmine karma still exists in v18?

    • @RainerHahnekamp
      @RainerHahnekamp 27 днів тому

      Karma does still exist, because they are still working on the migration to Web Test Runner. To be fair, one has to say that Jasmine/Karma doesn't have any issues - it is running fine - so they don't see this task as main priority. Jest will come after Web Test Runner is done and Jasmine will stay (as I said in the video). Btw, in th meantime, I would use Jasmine for a new project. Given the troubles we have with Jest/Angular and the pace of the migrations, I am afraid official Jest support is something we get in 2025. Last year, I had the impression that Jest will already be available in Angular 17.

  • @rkrao8582
    @rkrao8582 28 днів тому

    Do you have written this guide somewhere? Like in medium or some other place? Because audio on this is not so great and putting me off.

    • @RainerHahnekamp
      @RainerHahnekamp 27 днів тому

      Hey, unfortunately no. What is the issue with the audio? I mean I know I am not a native speaker but microphone should be quite good.

  • @pazzuto
    @pazzuto 29 днів тому

    This is great content as always. The concern I have about moving to standalone components is the bundle size. I haven't taken a deep look into this, but I've read here and there that there's a lot of code duplicated and your app actually grows in size. I'm sure it can be mitigated with lazy loading, but it's something to consider.

    • @RainerHahnekamp
      @RainerHahnekamp 29 днів тому

      Hi, where did you hear about the bundle size issue? Could it be that you are mistake standalone with the barrel files? Having a lot of barrel files (index.ts) will problems to your bundler because it might not be able to tree-shake them efficientyl, and you may end up with a huge initial bundle. Regarding Standalone vs NgModule, there is no impact on the bundle size.

  • @arnoldm5358
    @arnoldm5358 29 днів тому

    Hi, great video again! I'm using createActionGroup method to organize actions from the source which uses them. This way, different actions can lead to the same effect like calling the loadCustomer method from a service for example. This is where I'm struggling with the facade pattern... How can I implement the customerFacade? Do I have to implement several methods like fromPageXLoadCustom(), fromPageYLoadCustomer()... in order to dispatch the right action? I mean that I don't want to loose the origin of each action for debugging purposes.

    • @RainerHahnekamp
      @RainerHahnekamp 29 днів тому

      I see, you are the action hygiene. So you have one facade method per action. If you have multiple actions, then you also have multiple methods. As a side note: If you have multiple actions just for debugging purposes, why don't you add {context: string} property to the action's payload. Saves the the same purpose. On the other side, if you have different load actions, stick to what you have.

    • @arnoldm5358
      @arnoldm5358 28 днів тому

      @@RainerHahnekamp Thank you for your reply! So It seems that using createActionGroup method and a facade service is not really appropriate. The source property in createActionGroup method is the interesting property (as well as the organisation of the actions of course) and unfortunately we can't benefit to use it.

    • @RainerHahnekamp
      @RainerHahnekamp 28 днів тому

      @@arnoldm5358 To be sure there is no misunderstanding. With "stick to what you have", I meant a facade with one method per action.

  • @toromanow
    @toromanow Місяць тому

    I'm experiencing the following issues: 1) When I uncomment the webserver section in playwright.config.ts, then playwright reports "No tests" 2) In my test *.spec.ts file, await page.goto('') results in an error with no explanation. Thoughts?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      You typically get that message, if you have an invalid configuration file. Check that your commenting also wasn't applied to some things (parenthesis for example). If you uncomment it, and Playwright works, it is definitely an invalid config. You can post the contents of it here as well.

    • @toromanow
      @toromanow Місяць тому

      @@RainerHahnekamp Actually, found those issues to be specific to Windows. All works fine on Ubuntu.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@toromanow It shouldn't make a difference...

  • @youpeekayey
    @youpeekayey Місяць тому

    Sweet mama, fantastic stuff. Most in-depth guide in this topic that i found on yt. Thanks for this and keep up with great work! And subscribed ;)

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Thanks Doman, will do. The next "big one" will be about RxJs and a little bit longer.

    • @youpeekayey
      @youpeekayey Місяць тому

      @@RainerHahnekamp ​ Great, RxJS is also very interesting topic so I will surely watch it. Btw. RxJs is broad topic so I'm not expecting that you will touch this subject in mentioned video but for future content you could consider adding to your 'pool of ideas' reactive/declarative vs imperative style of programming in context of RxJs (it's not so obvious for many programmers who are used to write imperative code - me included)

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@youpeekayeyI touched a little bit on it. I think that RxJs forces you to do declarative programming and I have seen very often that people overuse that paradigm. So I have an example where I show how simple it can become if you add a little bit of side effects into it. We will see 😅

  • @rolandjost3823
    @rolandjost3823 Місяць тому

    Thank you Rainer

  • @marcwinner567
    @marcwinner567 Місяць тому

    Thanks for the vid! Learned something new 🎉

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Great, I stumbled upon the different behavior in a workshop and thought it might be useful to share.

  • @dhavalv
    @dhavalv Місяць тому

    Thank you Rainer for this video. I always make sure to listen to all of your videos, always learn something not documented

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Thanks Dhaval, and also for your ongoing support. You are a well-known face to me 👍

  • @etexalbania7301
    @etexalbania7301 Місяць тому

    thank you for the video, a question about testing, why haven't you done a video for angular testing with Selenium?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      I don't see any benefit in using Selenium anymore. I've been using Selenium (Selenide) for so many years, and we had to deal with so many flaky tests that we gave up one time. When Cypress came out, we gave E2E testing with Cypress another chance and were more than happy. Since then, I've never heard that somebody really enjoyed working with any webdriver-based derivate. Since I would not use it, I don't want to make a video about it. I know that there is now WebDriver Bidi. It has been hailed to bring the same quality as CDP (Cypress, Playwright) but download statistics show a completely different picture. Did I miss anything, respectively is there a particular reason why you are asking?

    • @etexalbania7301
      @etexalbania7301 Місяць тому

      @@RainerHahnekamp thank you. I asked because a lot of testers QA teams use Selenium from what I see in jobs posts and I wonder why it was not used with Angular in any of your videos, and you are the best person to ask for it when talking about testing 🙂 .Have a great day

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@etexalbania7301 Yes, you also have remember that Selenium was the standard framework for more than a decade. In huge environments you don't change that quickly. So I don't think that there will be demand for Selenium developers in the future as well. For new projects, though, Selenium doesn't seem to be the first choice anymore (diplomatically said).

  • @JOELJOSEPHCHALAKUDY
    @JOELJOSEPHCHALAKUDY Місяць тому

    thanks, that was a wonderfull overview

  • @koempf
    @koempf Місяць тому

    great Video :-) thanks Rainer ! top

  • @nayrban2187
    @nayrban2187 Місяць тому

    I was talking with a teammate the other day about how most content explains the easy and "obvious" scenarios, but you also cover real scenarios, so thank you

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Yes, one has to try it on a more realistic application in order to know if it can keep what it promises.

  • @aianam5354
    @aianam5354 Місяць тому

    Thank you Rainer ❤ very helpful

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Thanks Aiana and you are very welcome 🙏

  • @lindermannla
    @lindermannla Місяць тому

    Wowww, excelent tutorial! Thnxz!

  • @MohamedAbdulRaouf
    @MohamedAbdulRaouf Місяць тому

    Super as always, thank you Rainer form Egypt 🙌

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Thanks a lot Mohamed and best wishes from to Vienna (🇦🇹) to the land of the pyramides (🇪🇬) 👍

  • @ShiftedBit
    @ShiftedBit Місяць тому

    That's an important issue you are showing here. Thank you for that. I think i will stick with rxjs on the data layer and use signals in components only. I may try out a signal store for state management. Currently I am quite happy with rxAngular StateManagement and event driven reactivity.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Serwas Markus, yeah so using Signals in the templates is definitely a safe bet. I don't think that we have to use RxJs all the time. There are quite a lot of applications out there who might be well off with relying only on Promises but you need to know when Promises aren't sufficient anymore and you need to level up. I intend to come up with a video on that topic. It is not easy one. Although I have very good connections to the RxAngular team, I still haven't tried it out. Shame on me 😅

    • @ShiftedBit
      @ShiftedBit Місяць тому

      @@RainerHahnekamp I know it sounds odd, but do you think it would make a difference to wrap the promise into an observable and embed it to the computed with toSignal()?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@ShiftedBit I don't know, you could try it out if you want to. I've added the link to the repository. But as I said in the video, it must not concern you that you might miss the intermediate change where the holidays are emptied. If it does, that don't use a Signal for the holidays but an Observable. "The problem" is not the Promise, but the Signal itself which skips some values (glitch-free).

    • @marcwinner567
      @marcwinner567 Місяць тому

      @@RainerHahnekamplooking forward to that video sir 🎉

  • @murhafsousli7191
    @murhafsousli7191 Місяць тому

    Great tutorial, thanks!

  • @vutruong4164
    @vutruong4164 Місяць тому

    Thank you for the bombshell video Rainer! While these Signal APIs vastly simplify how components/directives React to Changes, I feel that we still have not arrived at a good pattern for the Initialization phase of components/directives using Signal APIs. Scheduling Initialization in constructor using the afterNextRender() seems to be the most sensible approach for me, with the added benefit of being SSR-friendly I also tried setting up Initialization using effect() and untracked() but in the end it felt a bit "unsafe" because effect execution is asynchronously dependent on Change Detection Scheduling, which we have very little control over. I am also concerned about when the executed effect is itself an asynchronous fetch, like in your demo (the async search function). ngOnInit, on the other hand does not have access to viewChild() and contentChild(), unless these queries are marked static. Perhaps you can provide more insight regarding the advantages/disadvantages of the above approaches in future videos, when best practices emerge!

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hey, it sounds to me like you are afraid of loosing the control over things? I don't see it that way to be honest. Yes, an effect runs asynchronously but if it triggers a side-effect which is also asynchronous (e.g. HTTP request), it doesn't change anything. I was never in control of an HTTP request either. Would it be possible to elaborate your issue a little bit? Can you think of a use case where the new API might be a problem? --- I would be careful when it comes to afterNextRender and SSR. It is not executed on the serve. So your rendered page might be missing crucial content. --- Cheers!

    • @vutruong4164
      @vutruong4164 Місяць тому

      I would say it's the timing of the availability of various component signals during the initialization that causes me some confusion. Like if I tried to 1. read an input.required() signal, 2. then fetch some data in an effect(), 3. and then use that data to populate a 3rd-party chartJS node in the DOM using viewChild() => I'm not exactly sure where should I schedule this chain of behaviour, because input.required() cannot be read too early in the constructor (input not yet available error would be thrown), while effect() itself must be scheduled in an injection context (constructor or field declaration), when viewChild() result definitely is not yet available in constructor. With decorator based approach, I would say ngOnInit for reading @Input and fetch data, then afterViewInit for populating chartJS DOM node. I'll need to study that part of your video again to familiarize myself with these new timings. Thanks

  • @VladiSecuritas
    @VladiSecuritas Місяць тому

    voice sound quality is really bad.. please use a proper mic.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Yes sir, threw it away after that one and working with a wireless. You can see the difference in the second part.

  • @gaborballa9614
    @gaborballa9614 Місяць тому

    wow, thank you! this video is very simple to understand for anyone. I recommend it!

  • @pawezysk3404
    @pawezysk3404 Місяць тому

    Best Angular tRainer ;)

  • @vmark
    @vmark Місяць тому

    @51:37 In the constructor, when using an effect and setting type to 'city', it knows not to update it because its the same value as it was before. What if instead of type being a string, it was an object? where we set a property of an object? Does it deep compare objects as well? or does it compare only the primitive types for detection?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hey, nope for the deep compare. The signal does the equal check based on object reference. That's why a you need to do an immutable update of the state, i.e. clone the object. You can add an equals function, as second parameter of the computed function. Then you are in charge. That is something I haven't shown in the video.

  • @siebedom
    @siebedom Місяць тому

    Great video, very clear explanation, thank you very well!

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Thanks as well. And if someting is unclear and you have any questions, let me know!

  • @votok2
    @votok2 Місяць тому

    Hi how do you feel about calling a private method in a computed signal that could hide a lot, i.e. what signal(s) the computed one depends on? I kind of try to read the signals value first and pass them as function parameters for better readability...

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hi, you would have to show me some kind of code so that I can get an understanding of your use case. In general, I would avoid calling methods inside a computed. You don't know what the private method is doing exactly. If the method calls another Signal you have an implicit/hidden tracking of that one. If your method starts an asynchronous task, then you are problay using it wrong and have to find further workarounds, which doesn't really improve the code. On the other side, if the computed is derived by a very complicated algorithm which you want to re-use outside of the computed as well, then yes. That makes sense. But please be free to share a code snippet. You might have a use case I haven't thought about so far.

  • @MohamedAbdulRaouf
    @MohamedAbdulRaouf Місяць тому

    Can you share your IDE setup & extensions

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hi, I am using IntelliJ with the default settings.

    • @MohamedAbdulRaouf
      @MohamedAbdulRaouf Місяць тому

      @@RainerHahnekamp Thank you, really enjoyed the video 🙏🙏

  • @avonzo
    @avonzo Місяць тому

    I've subscribed. You're superb! Both in terms of explaining and choosing the content! Bottom right useful. Already shared your video with my Java circles. Wonderful work!!

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hey, thanks a lot. Guess that means, I have to come up with further Java-based Videos...

  • @donwald3436
    @donwald3436 Місяць тому

    Good video good explanation, light theme is the devil lol.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Hey! Thanks, I use dark theme occassionally but always come back to the light mode. Can't help myself 👺

    • @donwald3436
      @donwald3436 Місяць тому

      @@RainerHahnekamp Well some day you'll get old too.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@donwald3436 Well, that's exactyl why I need the light. I don't see so well anymore 😅

  • @artjomsfomenko757
    @artjomsfomenko757 Місяць тому

    Some time ago we had services as a 'store', then we went to ngRx, now we go to signal store - which is basically a service. So tell me where is the win? I mean withComputed = getter where you can specify some calc logic

  • @papastepano
    @papastepano Місяць тому

    Source: Window.addEventListener:message seems to be triggering change detection all the time

  • @tarquin161234
    @tarquin161234 Місяць тому

    Your example on toSignal() appears a simple solution, but in my experience, sometimes it is not appropriate to provide an arbitrary initial value, in which case signals don't work. I think this is an anti pattern. To me it seems more logical an architecture to wait for the real value from the database, rather than scattering around arbitrary starter values, which may have unexpected consequences (e.g. in effects that do calculations).

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      Well, I wouldn't say it is an anti-pattern. Especially not in the way how I used it. If it comes to HTTP Response, as you mentioned it, it is a little bit more complicated. First of all, a Signal forces us to provide a value. The alternative would be to have a union type with undefined. Sticking to an Observable is not really option if we consider that Angular is heading towards Signal Components. Another option is that you add metadata to that Signal which tells you, if you already have the response or if the signal's value is still the initial one. But again, with that approach you'll find yourself very quickly in a situation where you want to use a Signal-based state management library. So it starts to become more complicated although you might have a simple use case.

  • @davesharman8302
    @davesharman8302 Місяць тому

    Hmmm, with anglar 18, adding @ngrx/signals fails with resolve dependency errors (both with ng add and npm install). Are we expecting a bump in the ngrx signals soon, or is there a workaround? does npm i --force work properly in this case?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      --legacy-peer-deps is the recommended option. See here: github.com/ngrx/platform/issues/4352

    • @davesharman8302
      @davesharman8302 Місяць тому

      @@RainerHahnekamp Perfect, thanks for the reply. I have been greatly enjoying your videos on signals and the signal store.

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@davesharman8302 Thanks Dave. Happy to hear that 😄

  • @tejeshwinidugyala9226
    @tejeshwinidugyala9226 Місяць тому

    Best Video for understanding OnPush Strategy so Far :) thank you so much

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      You are very welcome. With Angular 18 markForCheck will now also trigger the change detection. Maybe I have to release an updated video.

  • @leiayuri
    @leiayuri 2 місяці тому

    Hi, would you know if I have a component A which extends a directive B. And in comp. a I am in injecting a service A with inject and inside of the constructor I am also calling super and injecting the service A. The question is, am I creating 2 instances os service A? Thanks in advance.

    • @RainerHahnekamp
      @RainerHahnekamp 2 місяці тому

      Dear Yuri, could you maybe provide me a small code snippet? Thank you

    • @leiayuri
      @leiayuri Місяць тому

      @@RainerHahnekamp see if that peace helps. private processStepPackService: ProcessStepPackService = inject(ProcessStepPackService); constructor(){ super ("ProcessStepPack", inject (ProcessStepPackService)); } In that case where I am injecting ProcessStepPackService twice. Would that be 2 instances or still just one?

    • @RainerHahnekamp
      @RainerHahnekamp Місяць тому

      @@leiayuri Ah, that should be just one. You would get multiple instances with different provides but not by calling inject multiple times

    • @leiayuri
      @leiayuri Місяць тому

      @@RainerHahnekamp thank you so much. It was very helpful.

  • @donwald3436
    @donwald3436 2 місяці тому

    huh signals replace ngrx tho?

    • @RainerHahnekamp
      @RainerHahnekamp 2 місяці тому

      If you mean the redux pattern of the globa store, then yes. If you say Signals will replace State management libraries then I would definitely say no. Because you have Signals and a structure that is suited for state management, you need a library on top of it. This is something which has already been confirmed by Angular itself. They said, the default signal function will not be enough as soon as your Signal contains larger values.

  • @michaeljuliano8839
    @michaeljuliano8839 2 місяці тому

    Vielen Dank! Sehr hilfreich.

    • @RainerHahnekamp
      @RainerHahnekamp 2 місяці тому

      Bitte schön. Gerne geschehen der Herr 😉