NgRx Signal Store Trilogy, Part 1: Why, When, and How?

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 ธ.ค. 2024

ความคิดเห็น • 180

  • @jamesdouglaswhite
    @jamesdouglaswhite 9 หลายเดือนก่อน +2

    Wow, great introduction to these amazing new functionalities! I will be signing up for more!

  • @dragos.grigore
    @dragos.grigore 10 หลายเดือนก่อน +1

    I learnt a lot of information from your video. I'll just go and apply everything now. Thank you for this full of information video, Rainer!

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน +1

      Thanks, happy to hear!

  •  2 หลายเดือนก่อน

    Thanks so much Rainer for your videos. This one was incredibly helpful. I just follow your steps to create a signal Store extension and was so great... I really appreciate your effort doing those videos. Thanks!

    • @RainerHahnekamp
      @RainerHahnekamp  2 หลายเดือนก่อน

      Hey, great to hear. Thanks as well.

  • @sakarsr
    @sakarsr 11 หลายเดือนก่อน

    A really great introduction to NgRx/SignalStore. Thank you for your time to put it up. I am planning to use it in my ongoing project.

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Great, happy to hear that Sakar!

  • @OlehBiblyi
    @OlehBiblyi ปีที่แล้ว +6

    Great video, really unique content. Thank you!

  • @MikeKushnerPoland
    @MikeKushnerPoland 11 หลายเดือนก่อน

    Wow, great video and great intro to SignalStore & Signals. I'm jumping right into this now! Thanks!

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      You're welcome. Btw. a second one is going to be published very soon but that's a secret 🤫

  • @dhavalv
    @dhavalv 11 หลายเดือนก่อน

    Rainer really good stuff. Didnt realize the encapsulation bit that I will not have with the SignalStore. Really good overview

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Thanks a lot Dhaval. I hope that there will soon be an encapsulation feature available.

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      In the meantime, a PR is available: github.com/ngrx/platform/pull/4210. You can upvote if you are in favor of that feature.

  • @LarsRyeJeppesen
    @LarsRyeJeppesen 9 หลายเดือนก่อน

    Absolutely love SignalStore.

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน

      yeah, me too (guess that's not really a surprise)

  • @yanekvoloshchuk64
    @yanekvoloshchuk64 10 หลายเดือนก่อน

    Amaizing content! As always. Brilliant knowledge sharing. Thanks a lot!

  • @emilsirbu236
    @emilsirbu236 5 หลายเดือนก่อน

    As always super valuable content, thanks Rainer! 💪

  • @Petre66CA
    @Petre66CA 10 หลายเดือนก่อน

    Still wrapping my head around using the signal store. However, the presentation is good. Thank you for sharing the code to allow for a slow digestion of information.

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      You're welcome. Is there something specific you are struggling with?

    • @Petre66CA
      @Petre66CA 10 หลายเดือนก่อน

      @@RainerHahnekampI am struggling with the deluge of new terms. How is a signal different from an event emitter in earlier Angular versions?

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      @@Petre66CA The EventEmitter extends from a Subject and you should only use it for dispatching Events to be consumed by the parent component. You might want to compare a Signal to BehaviorSubject or Observable in general. I highly recommend you to read github.com/angular/angular/discussions/49684 where they explain why Signals at all and how they are different from RxJs.

    • @jamesdouglaswhite
      @jamesdouglaswhite 9 หลายเดือนก่อน

      I did not know such docs existed, what a game changer. Thanks for the clue@@RainerHahnekamp

  • @olgoree
    @olgoree 8 หลายเดือนก่อน

    I really like the general approach with having the state out of the component and quite minimal with signalstore compared to that huge boilerplate code you have to write for standard state management with ngrx.

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      Yes, me too. It makes things a lot of easier.

  • @DenisGitonga
    @DenisGitonga ปีที่แล้ว

    Glad have discovered your channel very educative. Waiting more knowledge sharing.

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว

      Thanks Denis, what kind of content would you expect?

    • @nnaluekenneth8420
      @nnaluekenneth8420 5 หลายเดือนก่อน

      ​@@RainerHahnekampI am also very happy to find your channel. I appreciate the way you explain advanced topics and I'm looking forward to more content on building systems like esbuild, and the usage of design patterns in Angular (Adapter, Composite, Facade, etc).

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน

      @@nnaluekenneth8420 Thanks, there is a video covering the Facade in NgRx. I would also be interested to cover build systems. Not just esbuild, but how it works together with Vite and what other parts are relevant in this area.

  • @n8_may
    @n8_may 5 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน +1

      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.

  • @wiliamferraciolli5380
    @wiliamferraciolli5380 5 หลายเดือนก่อน

    This is great, got a bit tricky at the end, but thanks a lot

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน

      Yeah, I know. Extensibility is the most powerful feature but also the hardest.

  • @etexalbania7301
    @etexalbania7301 6 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  6 หลายเดือนก่อน +1

      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 6 หลายเดือนก่อน

      @@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  6 หลายเดือนก่อน +1

      @@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).

  • @BDominikGT
    @BDominikGT 3 หลายเดือนก่อน

    Thank you very much. ❤

  • @koern82
    @koern82 10 หลายเดือนก่อน

    Great Video - asking myself why you don't have more subscribers.

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      Thanks, I'm quite satisfied with the current progress of my channel. I am getting more and more subscribers each day. Would have never thought that I reach 1,000 but I'm almost at 3 now. I think it is just a question of time and consistency.

    • @koern82
      @koern82 10 หลายเดือนก่อน +1

      @@RainerHahnekamp with such good content, you will grow quickly. i will be visiting more often now.

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      @@koern82Thank you, if you want you can also help me by recommending this channel to your peers. 😀😅

  • @rafaelcarvalho2918
    @rafaelcarvalho2918 3 หลายเดือนก่อน

    Thank you for sharing the content. A question would be with ngrx effects?

    • @RainerHahnekamp
      @RainerHahnekamp  3 หลายเดือนก่อน

      @@rafaelcarvalho2918 yes, what question do you have about the ngrx effects? The SignalStore doesn’t have them.

    • @rafaelcarvalho2918
      @rafaelcarvalho2918 3 หลายเดือนก่อน

      @@RainerHahnekamp Does the way we implement change?

    • @RainerHahnekamp
      @RainerHahnekamp  3 หลายเดือนก่อน

      @@rafaelcarvalho2918 If you mean if you still have to differentiate between reducer and effect: No. The SignalStore does not follow the redux pattern.

  • @imtech_be
    @imtech_be 11 หลายเดือนก่อน

    YOUR CROWN HAS FALLEN, KING 👑👑

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      It falls slowly but it the crown stays within the dynasty

  • @miklosbecsei8128
    @miklosbecsei8128 11 หลายเดือนก่อน

    This is is amazing! Thanks for the video!

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      You are welcome. Btw, it has been released in 17.1 this week.

  • @rajeshnakrani526
    @rajeshnakrani526 11 หลายเดือนก่อน

    Always appreciate your videos! I adopted the not-loaded, loading and loaded paradigm from watching your videos as I was learning about state management in Angular.
    I had a few thoughts that I wanted to share:
    - The auto-suggestion feature in the IDE you are using makes it difficult to follow along. As a viewer, we are watching and the code suggestions appear and then disappear and it forces some viewers to have to scratch their head, pause the video, backtrack and watch a section over and over. Disabling it in the IDE when making videos should make it much easier for all viewers, not just experienced developers and/or those who are familiar with the IDE you are using, to follow along.
    - I have only watched about the first half of this video, but I know that I would really love to see an example from scratch that covers managing state client-side and how to handle effects. Do we first update the state client-side and then make an external call (to an api)? Is it possible (and is it a good architecture) to use the NOT_LOADED, LOADING and LOADED paradigm that was used previously in the rxjs variant of NgRx?
    Thanks again, much appreciated, you offer really good thoughts about architecture and design!
    - raj

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Hi Raj, thanks a lot for your comments.
      I'm not sure I understand your point about the IDE auto-suggestions. Could you maybe give me an example from the video? If it helps I can of course disable whatever feature I'm using there.
      You can change the state first and then do the backen call. That's what we call optimistic locking. It brings better user experience but makes it harder for you. You always have to provide a function which reverts the state change if something goes wrong.
      It only makes sense for simple changes. If a single action triggers changes in different entities, it is way more difficult to provide a revert logic, so we usually want to send the request there first and wait for the response before updating the state.
      I would definitely recommend to use the LoadStatus pattern which I presented in one of my videos for the global store. Definitely do that!
      All the best,
      Rainer

  • @gemini9775
    @gemini9775 หลายเดือนก่อน +1

    Very helpfull thanks a lot 😀

  • @beezesty
    @beezesty 8 หลายเดือนก่อน

    Very nice and clear, to the point. Thanks a lot. So is this more or less the end of ngrx/store and will the community move to SignalStore for global state?

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน +1

      Thanks I can't predict 100% the future, but yes. Also the NgRx team says (talk at ng-conf) that SignalStore is the way to go. Only, if you absolutely must use the Redux pattern, then the global State is an option.

  • @usmanmustafa6845
    @usmanmustafa6845 ปีที่แล้ว +1

    if possible , can you please shared repo link ?

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว +1

      Sure, there you go: github.com/rainerhahnekamp/ngrx-signal-store-demo

  • @SonPham-zy2zp
    @SonPham-zy2zp 7 หลายเดือนก่อน

    A really nice demonstration. I have a question, If I have 2 signalStore for Customer and User for 2 different pages. I have a global loading bar, how can I apply isLoading on the global component

    • @RainerHahnekamp
      @RainerHahnekamp  7 หลายเดือนก่อน

      Hi, please take a look at my example. I have an http interceptor which sets the loading status in a service which is then read by the global component. If that doesn't answer your question, let me know and I can provide alternatives.

    • @SonPham-zy2zp
      @SonPham-zy2zp 7 หลายเดือนก่อน

      @@RainerHahnekamp I see that interceptor but sometimes we have calls that we don't want to show a loading bar. I have just come up with the idea of making a LoaderStore with isLoading property. Inject this store into withMethods of each Entity store where I want to show or hide the loading bar. This LoaderStore will be injected in LoaderComponent and bind isLoading into our HTML element. I am not sure if this is also the correct way to do it.

    • @RainerHahnekamp
      @RainerHahnekamp  7 หลายเดือนก่อน

      ​@@SonPham-zy2zpIf it is just about being able to exclude certain requests from not showing the loader spinner, please take a look at the HttpContext. Whenever you execute an HTTP request you have the option to add contextual data to the request which could be read by the interceptors. For example I use the context for a specific error message. You can find it at github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/shared/http/error-message.context.ts.
      If you need more option, then going with a service as you did is definitely something I would also then. If it is just about a simple property, I think I would skip the Signal Store for that and just use a simple Signal.

  • @fmaransatto
    @fmaransatto 9 หลายเดือนก่อน +4

    Awesome video, my only suggestion is to adjust your microphone equalizer and make it more acute, remove the bass, it's a bit difficult to understand.

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน +3

      Thanks a lot. After that recording I bought a wireless microphone. Sorry for the bad audio quality. Will not happen again :)

    • @fmaransatto
      @fmaransatto 9 หลายเดือนก่อน

      @@RainerHahnekamp It's nice to see a small channel with such a great quality and you have potential to grow. I've invested on youtube a few years ago, you can check out my channel containing angular and other nodejs content, but it's all in Portuguese. youtube.com/@fmaransatto

    • @fmaransatto
      @fmaransatto 9 หลายเดือนก่อน

      @@RainerHahnekamp let me consider reproducing a similar content but in Portuguese

  • @uchto4
    @uchto4 5 หลายเดือนก่อน

    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 หลายเดือนก่อน +1

      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.

  • @arnoldm5358
    @arnoldm5358 8 หลายเดือนก่อน

    Hi Rainer! Thanks a lot for sharing this knowledge! Just a question... How can the signalStores communicate with each other ? I often use effects and actions between several stores to manage the global state of applications... Is this still possible?

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      Hey Arnold, I have already answered your question below. I think you asked twice :)

    • @arnoldm5358
      @arnoldm5358 8 หลายเดือนก่อน

      @@RainerHahnekamp Sorry Rainer! My first comment didn't show up when I submitted it, so I wrote another one. 😅

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      @@arnoldm5358I see, all good!

  • @maciek77killer
    @maciek77killer 8 หลายเดือนก่อน

    Can I combine stores? For example, to retrieve all products of the logged in user?

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      Sure, the bookingStore for example has a dependency to customersStore: github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/bookings.store.ts.
      You just inject whatever you require, and that should do it.

  • @tonyxavier4724
    @tonyxavier4724 10 หลายเดือนก่อน

    Which font and theme are you using in this ?

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      The font is cascadia code pl but the rest is standard IntelliJ

  • @LukasMachetanz
    @LukasMachetanz 10 หลายเดือนก่อน

    Great video. Thank you for the amazing content. I am wondering how to update the store based on a signal input of the component. Let's assume having an input "id". Whenever the "id" changes I would like to update the store. How would this be done?

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      Hi Lukas, that’s where you use rxMethod. If you have an rxMethod of type number for example, it doesn’t just accept a number as parameter but also a signal of oberservable of type number. You can an example here: github.com/rainerhahnekamp/eternal/blob/talk/ng-india-2024-solution/src/app/holidays/feature/quiz/quiz.component.ts

    • @LukasMachetanz
      @LukasMachetanz 10 หลายเดือนก่อน

      Thank you for the fast reply. I really appreciate it.
      Makes sense. That’s how I did it in the end anyway. I was just not sure if it is the best way to do it as I initially thought rxMethod is only necessary working with rxjs. In this case the only operator needed is tap to patch the state. But it works fine. 👍🏻
      Originally I used an effect within the component but this resolved in some errors. I just wanted to mention it if someone else also experiences this “problem”.
      Anyway. Thanks for the response and the great content. Keep it going. ✌🏻☺️

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      @@LukasMachetanz Thanks, I will 💪👍

  • @ramoo06
    @ramoo06 11 หลายเดือนก่อน

    Great content.
    Thank you so much.

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Thanks and you are very welcome!

  • @arnoldm5358
    @arnoldm5358 8 หลายเดือนก่อน

    Hi Rainer, thanks a lot for sharing! I often use actions and effects to manage global UI state for example. Is this still possible with NgRx signalStores? Can signalStores communicate with each other?

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      Hi, thanks. So the way how SignalStore can communicate with each other is via the dependency injection. You can find in example at: github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/bookings.store.ts The bookingStore has a dependency to the customersStore.
      Reducer & Actions are part of the Redux pattern and not supported in the Signal Store. You could use our Redux extension: github.com/angular-architects/ngrx-toolkit, stick to the global store, or try to do it without Redux.
      Does that answer your question?

  • @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?

  • @walterluszczyk
    @walterluszczyk 9 หลายเดือนก่อน

    Hi, thanks for grat tutorial. Furthermore. do you have any material which shows how to manage with saving data to DB?

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน

      Hi Walter, you are welcome. Do you mean Date or data?

    • @walterluszczyk
      @walterluszczyk 9 หลายเดือนก่อน

      @@RainerHahnekamp sorry for the typo, I meant "data". I considered for example such as restaurant rating. It is quite simple to define a state (rest. name, photo, rating, etc.), load it at the beginning and show the state in template. But what should happen when user is rating restaurant by clicking 4th star? Should store be somehow involved in passing data (vie REST) to server? Or should I update data in store and in database separately?

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน +1

      @@walterluszczyk Yes, the store is responsible for calling the backend. Instead of patchState, the store would have a method called 'updateRating'. In that method, the store calls the API and then updates the store via patchState.

  • @andyhb1970
    @andyhb1970 11 หลายเดือนก่อน

    Hi Rainer, when patching state in the store if you have nested objects once you go to the second level object you must supply all parameters not just the attributes that have changed, is this a limitation of the patch state concept?

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      Yes, exaclty. So the patchState refers only to the first level. A possible alternative might be patchState(store.nestedProperty, {foo: 1}) but that does not exist.

    • @andyhb1970
      @andyhb1970 11 หลายเดือนก่อน +1

      @@RainerHahnekamp interesting I see there's a similar issue raised in the component store on gh. Thanks for the feedback

  • @MykolaReheda
    @MykolaReheda 11 หลายเดือนก่อน

    Hi, thank you for the content
    I would like to ask if we can use store methods inside rxMehtod?
    For example, if I need to implement a search and in case of an empty query, just call the loadAll() method, how can I access it from inside rxMethod?

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Hi, can you give me a more concrete code example? You have direct access to your store in an rxMethod. So it shouldn't be an obstacle, but I think you asking for something more specific.

    • @MykolaReheda
      @MykolaReheda 11 หลายเดือนก่อน

      @@RainerHahnekamp
      *TH-cam is deleting my comment for some reason
      I'll split it into two parts
      Yes, you are right, I have access to store inside rxMethod, but it is access to its properties that are declared in initialState. I don't have access to the methods themselves. Here is a simple code sample where you can see what the problem is:
      const initialState: IUsersState = {
      users: [],
      isLoading: false,
      error: null,
      }
      export const usersStore = signalStore(
      { providedIn: 'root' },
      withState(initialState),
      withMethods((store) => ({
      generateUsers() {
      return [ { name: 'John' }, { name: 'Marry' } ];
      },
      loadAll() {
      const users = this.generateUsers();
      patchState(store, { users });
      },
      search: rxMethod(
      pipe(
      debounceTime(500),
      distinctUntilChanged(),
      switchMap((query) => {
      if (!query) {
      this.loadAll(); // TS2532: Object 'this' is possibly undefined
      //OR
      store.loadAll(); // TS2339: Property loadAll does not exist on type
      // {
      // users: Signal;
      // isLoading: Signal;
      // error: Signal;
      // [ STATE_SIGNAL ]
      // :
      // WritableSignal;
      // }
      }
      // ...rest of code
      }),
      ),
      ),
      })),
      );

    • @MykolaReheda
      @MykolaReheda 11 หลายเดือนก่อน

      As you can see, I have no problem accessing generateUsers() inside loadUsers() via 'this'.
      But in rxMethod the context is lost, so this.loadAll() displays an error because 'this' === undefined.
      Also when using store.loadAll() inside rxMethod I get an error that such a method does not exist on my store type (but still I have an access to 'users', 'isLoaing' and 'error').
      Now I've found a solution that looks something like this:
      export const usersStore = signalStore(
      { providedIn: 'root' },
      withState(initialState),
      withMethods((store) => {
      function generateUsers() {
      return [ { name: 'John' }, { name: 'Marry' } ];
      }
      function loadAll() {
      const users = generateUsers();
      patchState(store, { users });
      }
      const search = rxMethod(
      pipe(
      debounceTime(500),
      distinctUntilChanged(),
      switchMap((query) => {
      if (!query) {
      loadAll();
      }
      // ...rest of code
      }),
      ),
      );
      return { loadAll, search };
      }));
      I hope my explanation is clear😅

  • @davesharman8302
    @davesharman8302 7 หลายเดือนก่อน

    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  7 หลายเดือนก่อน

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

    • @davesharman8302
      @davesharman8302 7 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  7 หลายเดือนก่อน

      @@davesharman8302 Thanks Dave. Happy to hear that 😄

  • @andyhb1970
    @andyhb1970 10 หลายเดือนก่อน

    Hi Rainer, another challenge I have encountered is how do you initiate a method call on a component signalStore via a signal state change in a global signalStore? My scenario has a CompanyId on the global signalStore which can be changed by the user at any given point, there are then a collection of chart components which needed to be refreshed but I can't work out how I would do that other than using an effect which firstly causes a problem because by default you can't change signal states within them and I don't want to override that behaviour it suggests I'm doing something wrong!

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน +1

      Hi, you do that via rxMethod. rxMethod would trigger a method of a local signalStore whenever the the selector/signal of the companyId changes.
      Do you have some code snippt, so that I get a better impression on what you do?

    • @andyhb1970
      @andyhb1970 10 หลายเดือนก่อน

      I have my rxMethod that loads the chart data and I call that on the ngOnInit of the chart component and the data loads however, how do I call that method again when the CompanyId changes externally?@@RainerHahnekamp

    • @andyhb1970
      @andyhb1970 10 หลายเดือนก่อน

      @@RainerHahnekamp not sure what happened I responded to this an hour ago and now it's disappeared! Anyhow, I've got a solution working by converting my authStore.companId signal to an observable and subscribing to that in my component constructor e.g.
      this.companIdChangedSubscription = toObservable(
      this.authStore.companyId,
      )
      .pipe(tap(() => this.loadChartData()))
      .subscribe();
      However, I thought I'd seen the back of subscribing and unsubscribing, or is there another way?

    • @andyhb1970
      @andyhb1970 10 หลายเดือนก่อน

      @@RainerHahnekamp I keep replying and my reply just disappears :-(

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      @@andyhb1970 then write to me directly on LinkedIn or Twitter please

  • @jdnichollsc
    @jdnichollsc ปีที่แล้ว +1

    First question, are Signals ready for Production? 😅

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว +4

      signal() & computed(): yes (since Angular 17)
      effect(): no (developer preview)
      NgRx Signal Store: no (developer preview)
      I'd like to add that developer preview does not mean that it is untested and you to expect bugs, like in a beta version. Developer Preview means it is quite stable but they can introduce breaking changes within a major version.

    • @jdnichollsc
      @jdnichollsc 11 หลายเดือนก่อน

      @@RainerHahnekamp awesome, still waiting for a stable version of that NgRx Signal Store, thanks for sharing!

  • @MahmoudTarek-pz1rl
    @MahmoudTarek-pz1rl 11 หลายเดือนก่อน

    Can I use it now in my upcoming projects or it is still not stable?

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      You can use it. It is very stable.

    • @MahmoudTarek-pz1rl
      @MahmoudTarek-pz1rl 11 หลายเดือนก่อน

      @RainerHahnekamp Thanks a lot, and thank you so much for the great content.
      I wish to see and learn more about new approaches

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      ​@@MahmoudTarek-pz1rl You're welcome. I wouldn't expect that the SignalStore will get so many new features. Maybe some extensions like withEntities but not in its core.

    • @MahmoudTarek-pz1rl
      @MahmoudTarek-pz1rl 11 หลายเดือนก่อน

      @RainerHahnekamp I totally agree with you.
      But I was sure that something related to deal with entities will have a place with signal store, whatever how.
      But, for me the surprise and it was the first time I see it I even didn't came across it was signalStoreFeature it is really powerful feature to have, extensibility in this way and having a generic store features just so much powerful

  • @vutruong4164
    @vutruong4164 11 หลายเดือนก่อน

    great intro to SignalStore. It really looks more intuitive and yet equally powerful (if not more) than the original global store/ComponentStore.
    Do you know if the effect() API will be introduced to SignalStore once effect() is fully stable, for example, withEffects()? The current approach, withMethods + rxMethod seem not fully "signalized" to me, but I do think it is sufficient for almost all use cases

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      I don't think so. The rxMethod itself also expects a signal and is executed whenever that Signal emits. In that sense, rxMethod is already an effect.

    • @vutruong4164
      @vutruong4164 11 หลายเดือนก่อน

      Thanks. I read up the documentation on SignalStore on NgRx and realized that the function generated by RxMethod can actually receive a static value (effect triggers only once), and a signal/observable (effect triggers on signal/observable update), and it auto-cleanup since it got access to DestroyRef in InjectionContext. Way more powerful than I initially thought.
      I look forwards to future videos on this very interesting SignalStore, perhaps on a higher architectural level, such as using it as global store, connecting and initializing component-level signalStore to global signalStore

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      @@vutruong4164 Yes, there is an upcoming video where I focus more on the role of the Signal Store to enhance Angular's Signals. I'll explain the rxEffect there more in detail.
      When it comes to global and local store, the repo of this video contains already a working example. github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/bookings.store.ts. You just inject like any other store.

    • @vutruong4164
      @vutruong4164 11 หลายเดือนก่อน

      @@RainerHahnekamp sorry for troubling you again, but is there still the concept of eagerly vs lazily initialing states with SignalStore?
      My understanding is withState will always eagerly initialize the store, so I probably have to initialize states with "undefined" if I want to "lazily" initialize states later by using a load method in withMethods

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      ​@@vutruong4164No worries at all. So as soon as you inject the Store for the first time, it will be initialized and it has to have state from the very beginning. You could use undefined, but I would provide default values and a property to my state that says if the state is ready or not. If you use undefined for all your properties, you always have those union types which are net very comfortable to work with. All components, all services have to deal with those.

  • @andyhb1970
    @andyhb1970 11 หลายเดือนก่อน

    Thanks for the video, how can you update multiple states let's say you have a component scoped state but you also want to update part of the global application state, with actions and reducers you can hook onto any action you wish and thus reduce multiple states, but I can't see how you would do that with Signal Store?

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      You would require to have access to the component-provided and to the global state. patchState will work for both. Did you mean that?

    • @andyhb1970
      @andyhb1970 11 หลายเดือนก่อน

      @RainerHahnekamp Yes but how do I provide access to both states, how do I provide that access, is it via the withMethods parameter list? if so how do I get the store instance to pass through?

    • @andyhb1970
      @andyhb1970 11 หลายเดือนก่อน

      @@RainerHahnekamp I think I've solved it, by exporting the type from my store e.g. "export type AuthStore = InstanceType;" I can then pass it into the withMethods function and use it with patchState! Not tested it yet though 🙂

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน +1

      ​@@andyhb1970That sounds a little bit unnecessary. If you want in your withMethod access to another store, then just use the inject function. You can an example here: github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/bookings.store.ts

    • @andyhb1970
      @andyhb1970 11 หลายเดือนก่อน

      @@RainerHahnekamp I've just removed the exported type and it's working fine! I must have had a funny five minutes or VS Code intellisense did!!! Yes you're right I can just inject any dependencies into the withMethods function.

  • @prasoon2510
    @prasoon2510 5 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน

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

    • @prasoon2510
      @prasoon2510 5 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน

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

    • @prasoon2510
      @prasoon2510 5 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  5 หลายเดือนก่อน

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

  • @sawmkcsaw
    @sawmkcsaw ปีที่แล้ว

    In component store can create selector something like storeBSomeValue$ = this.select(this.#storeA.someValue$, (someValue) => someValue). Is it possible to provide state from other store? So I can get access to value from storeA using storeB. Thank you for nice video.

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว +1

      Sure, I've pushed a version which contains a bookingStore that requires data from the customersStore. Check it out here: github.com/rainerhahnekamp/ngrx-signal-store-demo/blob/main/src/app/bookings.store.ts

  • @loko1944
    @loko1944 ปีที่แล้ว +12

    awesome content, but terrible audio :/

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว +1

      Hi, how bad is it? Do you think it is better, if I do a retake?

    • @loko1944
      @loko1944 ปีที่แล้ว +1

      ​@@RainerHahnekamp Hi. Its really bad, but I always payed a lot of attention to this so maybe other people wont be bothered so much. I treated video as nice introduction, but skipped some parts and filled gaps with articles due to this.

    • @hille-hausonfire4338
      @hille-hausonfire4338 ปีที่แล้ว +3

      @@RainerHahnekamp Yes, the sound quality is not particularly good, but I don't mind. I appreciate much more the hard work put into the video and the valuable information, so the sound quality doesn't really matter. Thanks for the great video Rainer! I hope you had a wonderful Christmas. Wishing you all the best for the New Year and hope you continue to give us such good content :)

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว +2

      @@hille-hausonfire4338 Thanks both. I will manually create subtitles and will upload them. The automatic ones aren't that good. To me, it is important that you can understand what I'm saying. As soon as that's not the case anymore, I have to re-record it. And thanks for Christmas wishes. Hope you enjoyed it as well!

  • @alexle7895
    @alexle7895 10 หลายเดือนก่อน

    I enjoyed the video very much, but I wish the audio could be better. I turned my volume to 100% and it was still difficult to hear.

    • @RainerHahnekamp
      @RainerHahnekamp  10 หลายเดือนก่อน

      Hello Alex, sorry for the poor quality. It was due to a damaged wire of the microphone and I had to aggressively apply audio filters to remove the majority of the background noise.
      It won't happen again. Switched now to a wireless microphone.
      You can also watch the second Part which takes on a different perspective but with much better audio quality.

  • @TheHelianos
    @TheHelianos 11 หลายเดือนก่อน

    there is a solution to easily handle side effects with it ??
    I have a case that one slice of a store, when updated, trigger a side effect in another slice to handle... it's like a domain event.

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Yes there is. The function you generate with rxMethod can also accept an Observable or event a Signal.
      Example:
      const Store = signalStore(withMethods(store ({incrementer: rxMethod()})));
      const store = new Store();
      // default usage
      store.incrementer(1);
      // usage with Observable
      store.incrementer(of(1,2,3));
      //usage with Signal
      const number = signal(1);
      store.incrementer(number);
      ---
      So you just provide your event in the form of an Observable and you're done.

    • @TheHelianos
      @TheHelianos 11 หลายเดือนก่อน

      @@RainerHahnekamp thank you... it helped a lot!

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      @@TheHelianos You are welcome. That rxMethod is extremely powerful. Also outside of the Signal Store. RxJs v8 will have something similar built-in

  • @donwald3436
    @donwald3436 7 หลายเดือนก่อน

    huh signals replace ngrx tho?

    • @RainerHahnekamp
      @RainerHahnekamp  7 หลายเดือนก่อน

      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.

  • @simong9559
    @simong9559 2 หลายเดือนก่อน

    Your microphone settings should be adjusted for better performance.

    • @RainerHahnekamp
      @RainerHahnekamp  2 หลายเดือนก่อน

      Yes, I bought a new mic after that video. Btw. this video covers also the latest features introduced in v18: th-cam.com/video/jrIXg0Avv38/w-d-xo.html

  • @birdvoron
    @birdvoron ปีที่แล้ว

    very good stuff. But where is github? ;-)

    • @RainerHahnekamp
      @RainerHahnekamp  ปีที่แล้ว

      Thanks! Here it is: github.com/rainerhahnekamp/ngrx-signal-store-demo

  • @floriss9
    @floriss9 8 หลายเดือนก่อน

    I'm having trouble understanding you because of the audio quality

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      Sorry, I am aware of that and all my newer videos are using a much better microphone. You can also checkout the second part which has overlapping content with that one.

    • @floriss9
      @floriss9 8 หลายเดือนก่อน

      @@RainerHahnekamp Nice! Thanks for that. Good luck and keep up the good vids

    • @RainerHahnekamp
      @RainerHahnekamp  8 หลายเดือนก่อน

      @@floriss9Thanks, will do!

  • @Marc-ox7fy
    @Marc-ox7fy 9 หลายเดือนก่อน

    Do you have Dutch ancestors? Hahnekamp/Hanenkamp, it is a Dutch name.

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน

      Yeah, I know. I come from a small village in East Austria where half of the population have that surname. What I know from ancestry research is that one Hahnekamp appeared there in the 17th century. I guess Hahnekamp got a little bit germanized. The "kamp" is still as it was but I don't think that "Hahne" is Dutch.

  • @AndrejMilas
    @AndrejMilas ปีที่แล้ว +2

    Ngrx all ur angular state are belong to us

  • @ShaggyRobot
    @ShaggyRobot 9 หลายเดือนก่อน

    Please, consider better mic or equalization in post, your audio is too bassy, it is not good for voice clarity.

    • @RainerHahnekamp
      @RainerHahnekamp  9 หลายเดือนก่อน

      Hi, I've considered it already after that recording ;) All my newer videos are now done with a wireless mic. If you checkout the second part, you should hear that it is much better.
      I still hope, you could understand what I said.

    • @ShaggyRobot
      @ShaggyRobot 9 หลายเดือนก่อน

      That's great :) @@RainerHahnekamp

  • @VladiSecuritas
    @VladiSecuritas 6 หลายเดือนก่อน

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

    • @RainerHahnekamp
      @RainerHahnekamp  6 หลายเดือนก่อน

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

  • @cocoscacao6102
    @cocoscacao6102 11 หลายเดือนก่อน

    Still hilariously overcomplicated way to achieve something a simple service can do....

    • @RainerHahnekamp
      @RainerHahnekamp  11 หลายเดือนก่อน

      Well, the SignalStore is still in developer preview. If you can provide an easier solution with the same kind of extensibility, we will be more than thankful.