I could remove ALL RxJS in my Angular app, but should I?

Поділитися
Вставка
  • Опубліковано 14 лис 2024

КОМЕНТАРІ • 49

  • @JoshuaMorony
    @JoshuaMorony  День тому +2

    Important bit of context for the viability of signals based sources/actions here (thanks to Younes Jaaidi for pointing this out). One reason I gave for not using signals was that (by default) the signals value needs to change in order for effects to run. But I mentioned we *could* work around that if we wanted to. However, a more important problem with the signal approach is how effects are scheduled. Even if we do make sure we only set unique values, or supply a custom equality function to the signal so that the signal always sees values as being different, we can still run into problems with missing events. If we were to trigger "add" twice in succession for example, even with different values, the effect will only run once for the second value, meaning the first "add" event will just be ignored. This works fine in my case in this example app, but this could be pretty surprising behaviour that could trip you up, and makes a stronger case for using RxJS for events.

    • @larshanisch
      @larshanisch День тому +1

      I was just about to mention that. Effects don't run on every signal change. They are scheduled to run, when the signal graph is in a consistent state (glitch free state, keyword: diamond problem). Signals are the shiny new thing in Angular, but they are only one side of the coin. The other side is events, and events are best handled with observables. Or in other words: signals hold the state, and events transitions between states. And we don't want to miss events (like I don't want to miss the event when you publish a new video...).
      Thanks for your content!

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

      I think of signals/effects as a "distinctUntilChanged, debounceToEffect, shareReplay" kind of thing. And depending on the events you want to process, that are most likely not the operators you want to use.

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

    Great use of animations and graphics! 👍

  • @jonatabiondiJsLover
    @jonatabiondiJsLover 2 дні тому +3

    You will update the angular course?

  • @nathanalberg
    @nathanalberg 18 годин тому

    I tried your pattern once but did not like that some of the event 'sources' were subscribed to on construct..... If I had any unexpected error on one of my sources.. the source was unsubscribed... thus closing the subscription... breaking the app... so I found it too error prone.. and just went back to using imperative click handlers to call/subscribe.

  • @thespiciestdev
    @thespiciestdev 18 годин тому

    Instead of the “actions” as Subjects that you .next(), why not methods that then interact with signals?

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

      There was a similar question somewhere else in the comments, I'll paste my reply from there:
      In short: to enable actions/facilitate more declarative code. With the approach where we have some sort of event notifier we limit the imperative code to just triggering that action, and wherever our reducers are. When an action is triggered, anything that is interested in that action can react to it. If we have add/remove methods, we have more imperative code in those methods. To give a concrete example where the action approach is nice from this app, when a checklist is removed two separate services need to react to that happening. With the action based approach, they just share the same event source of the remove being triggered and react however they need to. With a remove method, the remove method will contain imperative code that also needs to make sure it calls more imperative code from the other service to make sure the remove happens there as well.

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

    im with you in this one. some cases is better to let the rxjs to its job and signals handle states

  • @sd-sr4gq
    @sd-sr4gq 2 дні тому +1

    Curious, why not just ditch the observables and have add and remove methods? Seems like less of a clash of styles than mixing observables and signals as sources.

    • @JoshuaMorony
      @JoshuaMorony  2 дні тому +2

      In short: to enable actions/facilitate more declarative code. With the approach where we have some sort of event notifier we limit the imperative code to just triggering that action, and wherever our reducers are. When an action is triggered, anything that is interested in that action can react to it. If we have add/remove methods, we have more imperative code in those methods. To give a concrete example where the action approach is nice from this app, when a checklist is removed two separate services need to react to that happening. With the action based approach, they just share the same event source of the remove being triggered and react however they need to. With a remove method, the remove method will contain imperative code that also needs to make sure it calls more imperative code from the other service to make sure the remove happens there as well.
      Ultimately it's a style choice

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

      ​@@JoshuaMorony Thanks for the explanation. I was about to ask the same question. The sources approach makes it much easier for other services to act on the event streams. I might have gone a little offroad with signal effects.

    • @sd-sr4gq
      @sd-sr4gq День тому

      @@JoshuaMorony thanks, I like it. Basically pub sub right?

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

      And of course, it depends... on your context. In really simple scenarios you can get away with the imperative approach. But some day you will encounter situations where the event based solution will fit better. You decide, which and how many patterns your app should use.

  • @ВиталийСтарожилов-с2б

    for signal to emit on each change pass it this options object: { equal: () => false }

    • @JoshuaMorony
      @JoshuaMorony  День тому +1

      I've thought about using an abstraction that uses this, e.g. wrap a signal with a custom equality function into something like "sourceSignal()". Still not sure it's the right idea though, but maybe.

  • @moitp2
    @moitp2 2 дні тому +24

    I’m a bit confused. Angular is gradually moving away from RxJS because it’s considered 'too complex,' but in the process, they’re introducing a number of new mechanisms that aren’t necessarily easier to understand or learn. So, in the end, we’re just replacing one form of complexity with another.

    • @o_glethorpe
      @o_glethorpe 2 дні тому +1

      I don’t get why people think that a new feature should replace an older one. You know, you can have two ways of doing something, right? You can do it with signals only, with RxJS only, with both combined, or with neither of them.

    • @JoshuaMorony
      @JoshuaMorony  2 дні тому +3

      I don't think we can say RxJS complexity is the reason Angular is adopting signals. They were evaluating how they wanted to approach reactivity in Angular moving forward (including what mechanism they would use to allow for zoneless change detection), potentially they could have chose to lean more into RxJS, but ultimately decided that signals were a better fit for what they are trying to achieve.

    • @aheendwhz1
      @aheendwhz1 День тому +4

      @@o_glethorpe Because having 2 ways to do one thing is something bad that you try to avoid as a framework developer whenever possible. So they must have thought that signals offer a greater advantage over RxJS. I don't know whether it's simplicity or anything else.

    • @adambickford8720
      @adambickford8720 День тому +1

      A large part of development, especially front end, is fashion.

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

      @@o_glethorpe Because the learning curve is staggering for new devs. It also constrains future evolution of a language/framework

  • @dreivierabi6314
    @dreivierabi6314 2 дні тому +3

    Tbh before this stuff is not properly figured out and set into an industry standard I'm not moving away from a rxjs only approach. Once you get used to rxjs it really repeats itself and is easy to use. I don't get why we are trying to replace something that is working perfectly fine.

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

      Well, whos saying this is a new way of doing and you should replace rxjs? Its another way of doing it and you can choose what you prefer.

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

      @@o_glethorpefor now, but we know that at some point someone will want to stop maintaining two things and will ditch the support for the old one

    • @larshanisch
      @larshanisch День тому +1

      In the scope of Angular, what we should aim for is using signals in the template to get rid off zonejs one day. But outside of the template rxjs/observables are just fine.

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

      @@larshanisch Can you clarify this please with an example? I am using the ViewModel Design Pattern mostly, combining observables for my template. Does this mean, that I would simply have to replace my ViewModel Observable with a Signal? Or is there more to it?

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

      @@dreivierabi6314 I don't know how your ViewModel Design Pattern is implemented. I use (for now) mainly a redux like pattern, where I have one AsyncPipe in the template where I push the state and use properties on that state in the template (OnPush of course) and let the "input not changed if reference not changed" behaviour do it's thing. On new components I don't use the AsyncPipe anymore but replace all data needed in the template with signals. That can be "computed" (most of the time), but any readable signal will do. Then I have some event sources like button clicks etc., transform them with rxjs and use "toSignal" at the right place. I will simplify this once the "Resource API" in Angular gets more stable. For now I had something similar implemented by myself. A "subscribe" with the right "takeUntil(Destroyed)" to set some signals would also work.

  • @rockenOne
    @rockenOne 2 дні тому +1

    Why not just use the signal store library? Honest question.

    • @JoshuaMorony
      @JoshuaMorony  2 дні тому +6

      If I'm using a library I generally prefer to use signalSlice (I don't have anything against SignalStore), but I like to have a sense/method of how to approach state without a library as well, and doubly so for scenarios where I'm teaching (I would prefer to teach using just what comes out of the box).

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

      @JoshuaMorony good answer

  • @Szergej33
    @Szergej33 2 дні тому +1

    :3