RxJS Scan Operator - How to Manage the State

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi have you ever had a use case when you have an xgs stream of data and you want to shape some state from it for example accumulate all limitted values in one array similar to what I do right here with click events and I do it in order to accumulate values and generate a click map by rendering circles with the coordinates of the actual user click for similar scenarios I see a solution like this one quite often and despite it being working solution uh it has few drawbacks which I will mention a little bit later but I think for many of you they are pretty obvious here so watch this video Until the End and I will show you how you can create and maintain the state right inside your rxjs streams so you can deliver your data straight to the component View and avoid the explicit subscription to your observable I will show you how to do it the scalable way so you can easily add the functionality like State resetting or removing some certain element from the state my name is m maeni and my mission is to help people to become Advanced andl developers who really knows what they're doing and understands how things are really working you can check out my YouTube channel later and see the topics I covered in the past but today let's let's focus on managing state in RX GS observables all right so let's very quickly go through the disadvantages of the current implementation firstly we explicitly subscribe to observable meaning that now we have to manually handle un subscription and it would be much better to use something like a sink pipe or convert uh this observable to a signal so we can deliver data straight to the component View and let the SN pipe or the uh signal handle on subscription automatically for us secondly we lose the reactive context and we start imperatively manage the state this mix might be convenient initially but it becomes much harder to maintain when logic gets more and more complicated especially if there are a lot of asynchronous stuff is involved usually if you follow the reactive Paradigm you want to keep your data inside your stream for as long as possible and resolve it already in the last moment inside the uh component view or subscribe to it at the very last moment if you cannot avoid the explicit subscription for example somewhere inside the Ang directive or service so let's have a look how we could solve this this task without explicit subscription and staying reactive so first let's remove all this stuff here including the click events array because we will not need it anymore and uh let's start delivering clicks directly to the component template currently you see an error because the value being delivered is a click event and not an array as it is expected and and to address add this issue we have to aggregate The Click events into the array within this stream and this is where scan operator becomes useful and to deal with the state the operator needs actually two things it needs some initial State and some function that this state will be updating so the initial State we can Define as a second argument of the scan operator function and depending on your use case you can Define actually any value there I need to aggregate events into an array so in my case the initial state would be an empty array another argument of the scan operator is so-called accumulator function or simply saying this is a function that creates and Returns the new state based on the current or the initial one this function will be involved each time when the Source emits a new value and this accumulator function takes two arguments which eventually allow us to shape a new state those are the current state and the entity which is emitted from The Source observable and now with this data I can shape a new state by cloning the current one and adding the new event to the end of this new array so now uh this new state will be propagated Downstream to other operators or subscribers like in my case and also when the accumulator function is involved next time the value returned by this function will appear inside the state function argument then again we reshape the state and this new value will be propagated Downstream to my subscriber and this process just continues and in such a way we will be accumulating next uh click events within one array and this is it now we have achieved the same result as we had before but we do it reactively and we do not manually uh subscribe to the observable which is really cool however besides the value accumulation we would need to perform some other operations like State resetting before we proceed I would like to quickly remind you that if you want to learn angular in depths you can check out my video courses which can bring your angular skills to entirely new level for example I have one of the most advanced uh video courses about angular forms and there you will learn everything about building the complex form controls like this complex drop- down component which has a searching functionality multi- selection and accessible keyboard navigation and we will develop it together from scratch without using any third party libraries except the angular cdk or if you want to start with unit testing in angular but you don't know where to start uh I have a also dedicated course that helps you to grasp the general idea about the testing and uh we will start with testing the most primitive uh utility functions and then eventually we will Master more complex scenarios like testing components with uh content projection or testing the structural directives with a synchronous code all the links will be in the video description so you can check it out but now let's get back to the topic all right so how do we reset the state of the scan operator well it might seem a bit more complicated because the state of clicks isn't available from outside the rxg stream so we have to perform it somehow inside right and for that we would need to have another stream that will emit values when the state is supposed to be reset and for that purpose we can use a simple ARX GS subject having that we can emit the value into this uh reset stream whenever the user clicks the reset button or you might have some other triggers but in my case it will be like that and then the idea is the following first I want to combine those streams into one which will be emitting either click event or undefined and to achieve that I can use another familiar and helpful operator called merge which takes the observables you want to merge as arguments after that in the accumulator function I will be checking if the value emitted by the source is defined then it means that the value came from the clicks stream so I have to add this click event to the state but otherwise if I get the undefined it means that the value came from the reset stream so I would need simply return the ENT array and in such a way I kind of reset the state so now if we save this change change you can see that if I click on the page emitting The Click events I accumulate values in my state but when I click reset button it emits the undefined and accumulator function returns an empty array and in such a way my uh clicks state is reset this solution works okay while the logic here is very primitive however when things become more complicated this solution doesn't scale well so let me show you the solution that I learned many years ago and I don't even remember where exactly but uh this solution worked quite well for me until now and I will be happy to share this solution with you so the idea here is to emit from Source observables not a row values like I currently do like click or undefined but in instead we will be emitting Handler functions that know how to update the state for that particular operation it might look a bit complicated at the beginning and indeed I would say that this solution is quite Advanced uh but it will hopefully become more straightforward once we start using this approach in practice so let's get started with the accumulation a operation we can actually represent this operation as a high order function that takes the emitted value as an argument and returns another function that will already know how to update the state for this operation so now we can copy the corresponding logic from the scan operator and uh place it uh right here in this a new uh function good now we have to create a similar function for the reset operation and this is going to be also the high order function but this time it takes a void because the subject emits the value of type void and returns another function which also can take a state as an argument but it doesn't use it and just simply Returns the empty array you could remove all those uh arguments but I decided to leave it because for some of you maybe this verbos notation will be easier to understand so now how do we use this function first we have to transform values emitted by our source observables to the corresponding Handler functions and for that we can simply use the map operator which I hope you all know how it is working but yeah anyway here for the accumulation operation I have to call the accumulate Handler function which as you remember Returns the state Handler function for exactly this operation so now instead of the pointer event we will be emitting the function that captures this event and updates the state when this Handler function is called perfect so now I have to perform the same thing for the reset Handler so here we go and by the way you can make uh this notation a little bit shorter by providing only the name of the function for the map operator and the result will be actually the same all right so now it means that uh in the scan operator here uh we have not an event anymore but their state Handler function which can be either accumulation Handler or their reset Handler depending on what user clicked reset button or made a click somewhere on the page so I can simply provide the current state to this Handler function and this function eventually handles properly the state for me once we save this change you can see that everything remains working as before and I can still accumulate the state and uh immediately reset it by clicking the corresponding button yes we had to write some additional code but we have now the clear separation of concerns so uh the logic for each operation lives in a separate function which can be easily tested and it will be very easy to add a new type of uh operations and extend our solution for example if you would like to add the logic for removing some certain element from the state you could write a dedicated uh high order function for it create another observable that emits um uh this Handler function whatever this operation has to be executed and then you just have to add this new observable uh to the merge operator and you are ready to go all right so we just learned how to create and manage state in your rxjs streams by using the uh scan operator many of you probably are curious is this knowledge still relevant is it makes sense to invest time in learning RX GS because it seems like RX GS will become optional and here my thoughts about this thing I'm absolutely sure that RX GS will stay with us for for a long long time at least because a huge code base has already written with Eric GS and this code base has to be maintained and I cannot imagine how it can be Rewritten within couple of years I think it's not possible another reason is that RX GS still has uh areas where it really shines when it comes to asynchronous reactivity some event based systems there Rex GS works much better than uh signals at least at this point in time so I believe that investing time into learning RGS still relevant and it still uh pays off in the future with that I would like to say thank you so much for watching this video Until the End I hope this video was useful and if so please share this video with your colleagues and friends because it will help my channel to grow and it always motivates me to create more videos about angular also don't forget to check out my video courses I mentioned earlier in this video and please leave your comments and uh thoughts in the comment section for this video otherwise I wish you productive week ahead guys stay safe and see you in the next video [Music]
Info
Channel: Decoded Frontend
Views: 9,250
Rating: undefined out of 5
Keywords: rxjs scan operator, rxjs scan, rxjs tutorial, angular state management example, rxjs angular, rxjs tutorial 2024, angular state management, rxjs operators, rxjs operators in angular with example, rxjs operators in angular, decoded frontend, angular development, angular 2024
Id: PDpAjf0688Y
Channel Id: undefined
Length: 16min 33sec (993 seconds)
Published: Tue May 07 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.