Transcript for:
Understanding Angular Signals and Their Benefits

so signals is something we have already since angular version 16 at the time of this recording we are at 17.3 and we see that the signals are becoming more and more integrated into the angular framework with the latest version we see a new API which is responsible for all the things in terms of component communication and it replaces the old decorators like input output the few child the content childart with functions that most cases return you a signal so the advantages that you get with signals are first of all some applications will gain significant Improvement in terms of performance not all of them especially those who don't have any performance issues especially those very simple ones they will definitely benefit from the lightweight reactivity compared to rxjs because signals are also like a reactive data structure then what we also get is that the expression has changed error so some kind of error messages will also go away and as we will see later especially the developer experience is really improved and we are also quite safe for the future for the upcoming features for example if Zess goes away if we get the signal components we will not have to touch our code that often most of the features of the signal signals are still in developer preview there are now different opinions on should you wait should you not wait I have a clear opinion I say yes please start using signals right now I will say something about the detailed reasons at the very end in the summary but this video should really give you a guide it should kind of really I want to really explain you to all the main features all the functionalities everything you have to know in order to use signals but also this kind of this new apis which are based on signals already this video is very long so you don't have to watch it in one go the on YouTube the chapters are marked but we have four main parts first one is the basic about the signals then we then we cover some advanced stuff like the ref effect and so on and so forth then interoperability for rxjs and at the end this new API where we don't use the old decorators anymore a little bit of an introduction so my name is R Hanam I am a Google developer expert I'm also part of ingula Architects so if you're looking for a training workshops Consulting in terms or in the area of angular then I hope we might be a good candidate but now let's start now before we start some words about the change detection in angular whenever we change a property in a component then this change CH is triggered bya an event listener so a Dom event or via an asynchronous task like response from an HTP request what angular is doing then is that there is a library The Zone chess which is aware of these kind of events and then triggers the change detection angular starts from the top of the component Tre which is the app component it goes through the complete component Tre and it also always checks the typescript class of the component properties the values of the properties of the typescript class with those that are currently rendered in the Dom and if it sees that there is a certain change then it updates only that particular Dom element now this kind of approach is a little bit costly not in terms of access to the Dom this is very efficient you can't do it any better because when there is just a change in the in the text node then only the text node is updated and nothing else so how can you improve that the problem is more that that the change detection has to run quite often even if there was no change if we click on a button and it starts an asynchronous task then we didn't change anything uh but still the change detection needs to go through and of course always this kind of the requirement to search for a change it would be way better if the change detection when it starts knows that there is now a change and not that it just knows about the change but also where the change has happened and this is what signals will improve because with signals the future the signal component the last version of it where we are only working with signals in our component it would be like this so the signals themselves they are reactive data type so there is a reactive graph an internal reactive graph where the signals know if they are depending on somebody on another signal or what kind of consumers they have so that they also have to update to notify them and these signals are then used in our template and then inula the framework itself is also or acts also as a consumer of those signals so the signals will update the framework in that sense will tell it hey look I just been updated you might want to do something about it and with every reactive model that we have there is also an option for side effects and in a way very simplified put we could say the only thing that angular has to do when a signal changes in the template that it just says okay I'm running the change detection on that particular part where that signal is used so the rendering the Dom update is just a side effect of those signals which also means the perspective will change from a componentry to that signal graph because this is where the data comes from and this is also where the change detection where the update of the Dom needs to be triggered so that's it for that's it for the theory and now let's take a look at a real application all right so this will be our application for the rest of this video as you can see here it is a list of different holidays it's my usual application that I use uh we have here some additional buttons functionalities so I could for example click here on I want to have more information I can mark it as a favorite but I can also say here I want to put it into my basket those holidays they come with a filter possibility so I can say I want to search for example for those that start with n o then we see it's only Norway and I can also differentiate between a typical City only holiday or a complete country a visit to a country which obviously takes a little bit longer than just one day now the way how this has been implemented is we have here one holidays component this is what we see here as we see it also works with template D with template driven uh forms and at the very top at the very bottom if we come to our component to our code we see here no signals and this is what I'm going to do now so first of all we need to be able to use signals for a simple component so so how do I do this well I say I have here my query and if I want to make it as a signal then I just call here signal I put my initial value into it and then this query becomes a writable of a string writeable signal of a string so you see signal just the function call but you have to provide an initial value so a signal will always have a value available will never be without one the type in appearance here works very well as we see we don't have to provide here the type but typescript just infed from this initial value which we provided there next thing we have here um holiday type which is a union type of strings so if I say here again signal and I remove the type because I have to it's not read right signal we are getting a little bit of a problem because here it says yeah it's a wle of signal of type string although it should be holiday type but let's leave that for now let's also do here the last one which is the holidays this is the list of the holidays that are shown once they have been loaded and I say here again uh signal and I provide the empty list to it and now we see the problem again type inference works like with any other empty array it just doesn't know what type it is and that's why it says it's never so what can we do about it there are are two options the first one is that you apply type assertion which means you say here as and then you say this is now of type holiday and uh it would be that one type of holiday array I don't like this to be honest I usually go with the other one where I can make use here of the generic function so I put the type here so I say here holiday and it more or less it ends up with the same result the question is though why did I go with that one and why didn't I stick to the type assertion with this approach I in a way Define that I say this should be of type holiday array and then I'm providing a value to it and then typescript needs to confirm or needs to check if this empty array could end up being of type holiday array if if I do it the other way around like saying as this is always kind of overwriting the typescript compiler I don't like this there is actually a video a very old one from my where where I'm discussing kind of type naring function if you're interested yeah please watch it and the same in terms of of generic types is then also true here here I say okay this is actually of type holiday type so again I'm defining the type that I want to have and then typ script confirms if this all value is all right or not so this is about how we can generate our own signals the next question of course is how can we access them or how do we deal with them so if we scroll here a little bit to the to the to the search function we see first of all the search function is triggered in the ngon in it so that we see already immediate some holidays immediately some holidays and here the search functions CH function says I'm using your holiday service find and it uses the old query and the old type which used to be normal strings now the way how we can get out the value of a signal is that we use or the signal as a normal function we just call it I have to do the same also to to the type there and the reason why this was necessary or why we have to call it as a function was that the angular team I mean they did this on purpose there are different ways on how you can access a value of a signal but what they said is that they want to make sure that when we call it like a function that in a way we also are aware that it's not just like a property access we are doing something internally as well so there is something which happens if we do that and if it the the function syntax is is used then we kind of understand that a function can do something it's obvious and that's why they went with it the next thing is of course how can we now update a signal because here we have holidays and I can't assign it so I can't say here okay those holidays which this holiday service provides me I can't assign the array to it because it's not the same type but for that we can go and we can say okay I use the set function and I put then the weight into it and of course I can also say let's do it like this I move it out and I say okay uh holidays like this if this reads a little bit better the set is not the only function how you can update a signal there is also another one which is holidays update uh what the update function is doing so it is a it would EX expect another function an update function in that sense and in this update function you get the current value of the signal and then it is expected that you provide an immutable value an immutable change and this means if I would return here just the value then the complete reactivity which we still have to see will not work so you really have to provide here always like this cloning feature or like structured clone modern browsers support Port cloning already natively but you put this then here inside of the of the update function in our case we don't need it because we say we are not interested about the former holidays we just want to override or want to override it with the new ones what is also interesting here is the usage of the promise and of the AC incubate because this is something which is not a common thing in inula let's call it like this we typically would use RX sh yes we would have here an observable where we would try to use the asnc pipe in the template and if there is no other way then of course we would subscribe to it and um fetch the value then in that way now with signals and its reactivity and also the requirement as I've explained before that the signal is the one data type that ends up in the template we will see that we will have signals in the component most of the time or I would say even always and rxjs is yeah it will be there there will be some use cases for rxjs but I would be surprised if I see it that often in a component I see the place for rxjs more in the logic layer so more in the in in the services and then the services might expose and observable but they might also expose already a signal so transform a map and observable into a signal and in our component we will then have most of the time a signal and that's also why for some simple use cases for simple HTP requests we might not need the power of the hdp client power of the observable in that case and we can also go with the oldfashioned um AE async I don't want to continue this kind of discussion rxj where the signals this would be a whole new video so let's um let's postpone that one good so this is the way how I can access a a value of a signal I just call it as a function and I use the set or the update method in order to update a signal and again this has to happen immutable so I really need to provide a new value otherwise I will not get an error message but this reactivity that the signal will update will notify it consumers will not happen good so is there something else we have to change I don't think so we now come to the template so here in our template we see there is already an error message and it tells me hey look you have here a full loop and you give me a writeable signal what should I do with it and well we access we need to access the value again of the signal and we do it in the same way as we have done it incription now you might say okay that's easy but there is something you have to be aware of there is a huge difference between calling a signal in template versus calling it in typescript the template is something that we call reactive context this means when a signal is used inside of this reactive context then this context in a in in a in a way is updating its consumers automatically so in this case this would mean when the signal changes here it is updating the consumer which in this case could be angular or will be the will also be the trigger for angular's change detection at the moment it's a little bit embedded in zone ja but I think it's safe to say it will update inula itself and will tell it hey look there was a change of holidays you might want to Mark me as D he and in the future it will run the change detection if you call the signal in the typescript code here like this then it's not in a reactive context and context that's a one timer you just access the value now and that's it um and of course it also makes sense because we don't want that this kind of function or whatever we would see here maybe as a reactive context is executed whenever the query or the type changes good y let's check uh if there's something else which we might miss yes here Ang model might also be a little bit interesting but I would say let's first go back to the to the webite web page and see if it's still working so if I say here e enter yeah that looks very nice so we didn't destroy everything it's still working we are now working with signals about this engine model I mean as I said before we are now running on 17.3 but if you're using um different versions of before 17.3 you might have an issue with this kind of syntax here the two-way binding the banana box where a signal is involved so usually this should not work because normally we have here a property binding part and then also an event binding part and the property binding part this one will not work because again we would not assign here the value to the engine model we would assign a signal to the engine model and if I go back and um you reload the page we see that in the input there is a strange value yeah because it's a signal so what we have to do is that we have to call it that we would have to call it and then when it comes to the changes so when I say here the input has changed because I have typed something in then I could use this event here and I could say Okay query set dollar event and this would then update the signal as well this used to be the way how you had to do it until 17.2 and with 17.2 this banana box style was upgraded and it also now understands the signal type so if it sees that there is a signal there if we assign a signal to it then it's doing the code that we see here automatically uh for us it's just the old banana syntax so I just type it in like this of course don't call the signal that's important and now the rest is done for us by angular right now we have for our search again good so what else um we have of course now the power of reactivity which we haven't seen so far but let's say we want to show the amount of holidays we have found and we might also want to print out the the query in a in a in a in a nicer way in a user friendly way so I would say here uh pretty search equals and this would be query let's use these ones these I would access here the the qu signal itself yeah we know now how to do it and and I would say with type and then this type calling it as a signal and I want to have a holidays count where again I would say I'm accessing my holidays and I want to have the value from them the prce search and the holidays count is something I want to use now in the template so I go here and I say have near a diff with uh two paragraphs in the first one I just say pretty search in the second one I say holidays uh account and maybe also a little bit of a a more user friendlier text holidays found like this good so I think or I hope you aren't surprised if I tell you there's no reactivity now so if I type here something in um maybe not uh like an N then we see we see some holidays it still says zero we see here an a query although I have just typed in an N that's not how it works but with signals we can now say I want to produce now another signal with some dependencies which should then produce me the pretty search and also the holidays count and the second command there are three of them that you have to know when you want to use signals is the computer so with computed very easy to use I can say hey look I want to use I want to run this kind of function where I'm accessing these two signals and I do the same with the other one with the holidays count so I also say here computed and um add them this formatting function into the computed itself what computed now is doing first of all it's quite a smart implementation because we don't really need to tell the computed explicitly what kind of signals we want to listen to it just finds it out on its own so we just need to call the signal then the computed knows that we want to listen here for query end type computed is another signal yeah so we see your pretty search is now a signal of type string and the same is true for holid count as well and this is now reactive in that sense that's now very important if it's used in a reactive context yeah so just by using computed you don't have a reactive signal there you still have to use it in a reactive context and by now we only know one and that's the template so this mean to it short if I would call the pretty search somewhere in my in my in my typescript class it would have no effect it would give me the value back which it has right now again the signal it always has has a value there but not more so it will not reexecute if the query for example changes yeah and I think it's also I hope it's obvious that it's not a writable signal what should I write to a derived signal I have to write to query and type yes but not to pretty search a holiday discount since it's a signal I also have to use it like a signal so I have to go here back to my template and I have to call it here so I have to say yes you are a signal uh please now also behave like one and now I'm putting the signal into the reactive context which means again if now pretty search or holidays count if their one of their producer signals change they will again notify inor itself and will say hey look there was a change you might want to update the D yeah so holiday is found 13 and if I type something in we see immediately here the feedback that it's updates automatically also here of course good the last thing I said before there are three of them the last thing of course is now the side effect so what's missing is I've now said multiple times the reactive context is the template but still what if we require something like this reactive context in typescript in our typescript class what do we have to do there in for that we have the effect function so the effect function is exactly that part which gives you a reactive context in for your class for in typescript the way how we do it let's say we have here a Constructor and there I have to say effect like this works exactly in the same way as the computed at least from the syntax internally it's something else because it's reactive context uh we say here pretty search I call it in I say log and this should now mean that whenever I change something here with the pretty search that I also see here the output in my console so if I type here something in we see the output is immediately there if I change something in the type then it's also there with this kind of reactive context that we have there are of course some requirements how often does run or how long does it live this how often does it run is something for later more important thing now is how how long does it live and angular does this for us automatically so where we had in RX CH the subscription we also were forced to use an unsubscribe in Engle this is done automatically but there is just one requirement we have to use the effect function in the right place if I move it to the engine in it and I'm now rerunning my application then first of all we don't get a compilation error but what we get instead you see it here already it's a runtime error and the reason for that is that the effect is not running in an injection context why that well because somebody needs to close this reactive context and if we don't do it then angular has to take care of it because otherwise that one L will live forever and the effect automatically tries to crap the current yeah in injector or the current injection context and then also is destroyed when the current injection context also gets destroyed and the current injection context is the one from the component so it gets away or it gets destroyed with the component itself we don't need to do anything we don't need to call it explicitly as I said before we just have to make sure that the effect is in the Constructor or if you don't want to put it into into the Constructor you can also do it here when the fields are initialized but then of course you need to assign the outcome of the effect to a variable yeah you can't do that much with a variable with this ref variable but that's just the way how you would have to do it outside of the Constructor there is a third option but I wouldn't recommend it you could put it into the engine in it you can then put it wherever you want as long as as you provide the injector manually so if you say here injector and you of course you need to provide another the injector you need to get it from somewhere so you could say your inject uh injector like this and if you then say here please take this injector which I already have uh then we will see that now the effect is also working but of course again I would say don't don't start doing these things we still or patterns for signals are still evolving but it's already very clear that this might not be the best choice this might not be the best pattern that you should use so please as I do it put it into the into the Constructor or use the effect reference much better okay so I think we have now covered the signal function the computed function the effect function we have also covered the term of reactive context where I said it's the effect or it's the template and we have also seen how the signal computed how they behave how we can access a signal and so on and so forth what's also important the banana box style also works now with the signal as well and I think that this is it for the very beginning this ends the basic unit and we are now ready for the more advanced stuff so we come now to the advanced part and there we will discuss things like the clear tree effect like the dynamic dependency tracking and also things you have to be aware of when you use the effect function quite often especially in combination with calling other services and that stuff it is not really important that you remember or understand everything in detail but you should be aware of those kind of behaviors that we that I'm going to show you because you will definitely stumble upon them and then it's very important for you that you know that everything's all right and that it is just as it is supposed to be let's go back to our application and let's just say we have here some kind of search so I say your H I click on enter and uh we see that all the time whenever I I type something in we get here a query in the console and that's coming from this effect which we have here now what I'm going to do now is that I'm going to change my effect and I say whenever the holidays are updated then I want to print them out so I say here holidays um oh and I say okay access my holidays like this F I'll go back uh then we see that here the holidays list is always shown good and now I'm starting to do something very strange I go to the search function and I say before I'm setting the new search uh the new holidays I say first of all they are empty that's not enough then I say okay I create now a new holiday could can do this with the create holiday function I also need to add here a certain property which is is favorite I say no it's not favorite and I'm running them the update function because then I might have here a use case where I say I'm kind of doubling the entries of my holiday array so I say here value and then another time value and then again because I'm funny or think it looks interesting I'm again updating my holidays so what we see here that we have five updates of my signal and well we would of course now expect that we will see now quite a lot of console logs so if I now go back nothing happens of course I didn't do anything in terms of search but here we have just one so if I remove everything which we had so far and if I now type in Vienna it's just one I see e now it's six okay then we we see a six holidays what's going on we could now say well maybe the signal doesn't have the value at the moment well we can we can try this out so I can say okay what happens if I do here a console lock where I say okay I want to show here the holidays like this one time two time three times maybe they are not there or maybe I don't know what what is possible so I say here again B then we see 1 2 3 4 and then the fifth which is the final update of course it shows up and we also see here that it contains those values which are supposed to be in the holidays but our effect looks like it it's only aware of the last holidays that we have there again Vienna we only find three it's only here the last one that's the glitch free effect so the best way at least for me how I understood it and also the reason why we have it which is more important is if we see the signals from the perspective of angular because angular says I want to have a data type where I can provide the an optimized dumb update a d and optimized rendering I mean we shouldn't use the term rendering together with angular but you know what I mean and if we think about it about this use case here if we would say well every signal change should result in a re-execution of the change reduction updating the Dom it doesn't make any sense here because how should this work we have here set and then I say okay stop right now what you have done I don't continue I now go to the Dom and remove all the holidays then the next code here is executed where one holiday is added I say stop again I now need to go to my dom and I need to add here this holiday card and so on and so forth these changes these D manipulations will happen so fast that we don't even see them what we see though is at the very end that this holiday is coming from our aimo ass set so it's not necessary to start here all the change detction to start here the Dom update if I know it's already changed in the next split millisecond or so and the glitch free effect guarantees us this the glit free effect says I am only going to activate or request the data from the signals if I'm running in the change direction so if I'm running asynchronously and only then will I take the last value that I have or the current value and this also has an impact on the computed and on the computed based on computed and on the effect because they will only run once in the change detection and that's the reason why the change detection when it runs when this search here is over soj kicks in and then angular says okay give me now the value all everything has already been executed and now the effect says the same thing so the rendering starts only with the last holidays and the effect also only gets the last holidays and if there would be some further signals involved like a computed it would be the same for them as well so for example if I would say I have here a computed of holidays F and I do something which you shouldn't do that you say here hey from computed would be a side effect in this case then we will also see this also only runs once so if I now go back and if I say here V uh search then we see hey from computed of course the effect here is also there because again works in the same way so if you really try to understand it to see it from angular side then this is just natural it has to be like this this is very efficient why should I update the Tom in a split millisecond if this is actually technically possible because the browser will not even render it um yeah so that's the way how it is there's of of course there's also a consequence of the out of this Behavior you can't expect that every change will be processed by an effect so if you want to implement something and you rely there that every effect knows about the changes of the signals then you will not be very lucky here in this in that case or in these cases you should definitely go and use rxjs for that so this would been the done by rxjs but in the end again we want to render only the necessary parts we will map the observable to the signal Y and um before I remove that code there there is one important question what happens if I move the set here uh before the first a weit what does this now mean for the effect will it now be executed only once when the hor are set or would it be executed first with an empty array and then second with the holidays let's try it out so we need to wait until the page is reloaded right then I see here Vienna click on enter and we see two times and again from this kind of EXP explanation from before it hopefully makes sense so I click on search the holidays are set to empty and in the same time or right afterwards I'm starting with an HTP request now why should angular wait until this request comes back it wants of course it needs to render now because it says yeah now I'm R the change detection and it will then say okay this holidays have being set to empty we don't know about the rest that's asynchronous will happen sometime later so this first one will be will then be triggered or will then be processed by the effect and also by the by the by the template then the response comes back which is where we are there and they all run asynchronously and then only the last one will be taken into consideration and that's why we see then only the last execution that's what this free effect is all about so have here again just for summary there is here an animation so we have here some kind of caller this is the reactive context on the right side the caller goes to a in this case it's a computed it requests the value the computed executes its internal function it goes it activates the signals it's it's its producers in that case and at the same time the computed also registers itself as an active consumer and when those producer signals are accessed so producer signals is just another term for the relationship it's it's a normal signal so there is no type like producer signal but if those producer signals are then accessed they will first of all look if there is an active consumer there and if that's the case then they will store this Active consumer internally and of course will send the value the current value back to the active computed the computed will do the processing and then will'll send it back to the consumer to the reactive context now the producer signals are now aware of their consumers which means when the next time one of those signals producer signals are changing then they are notifying their consumers that there was a change but this doesn't happen or this doesn't mean sorry that these consumers are now starting to do the processing they are just remembering the computer remember that it is in that case dirty which means it knows when somebody accesses it the next time it has to do with this internal processing so when this reactive context comes around second time which could be another change deduction run very likely this is the case how it is these days then angular will go to the computed and will say do you have a new value for me and since the computed knows it's dirty it starts to do its processing and then it sends the last value back because obviously with the processing it starts requesting the producer for their current value which in this case is what we see here in line 111 and it will use only that value and this is what the consumer will also or the reactive context will eventually get this kind of clitch refact uh because of that is also called the pushpull principle because the signals The Producers push to the consumer but the consumers still depend on the on on the reactive context on their callers that they actively pull the value from them and only then do they start their internal processing good so now uh where we know what's what's going on here I can remove it and let's yeah leave it as it was initially yeah like this now we'll take a look at something else which is called the dynamic dependency tracking what is this let's say we are extending here our effect let's say I say here at the very beginning running effect dot dot dot sorry and I say here lock and I say okay I have here an if condition and I say if this type equals all or maybe not let's not put the type in there let's put the query in it and let's save the query equals Vienna then I want to console walk a second time this type okay I have to do it by the shortcuts obviously I'm unable to type in the console log good you might not say okay what's the speciality what's so special about it well we see a running effect which has now a conditional dependency with type this is the special thing here is there something which changes now because if I type something in we see the running effect happens all the time yeah that's true but what happens if I click now on these buttons there well the the the pretty search changes but we don't see here this kind of running effect yeah obviously because we have to use Vienna and now all of a sudden if we click now here between the holiday types then we see that the effect is now also executed along the console lock for the city or for Country Now the interesting thing is if I'm going to change Vienna to remove the a it's not Vienna anymore and if I click here again no console log if I add the a there is a console log for the for the Hol type very strange but the way again how this works and this is this this kind of dynamic dependency tracking is that with every execution the effect in this case checks if it actually requires those producers anymore which it has maybe saved from a former run so when quy is Vienna then we would go here into this if condition and then all of a sudden this kind of subscription to the type signal shows up and then in the second in the third run the goes to the type and says hey I also want to have this kind of information from you I'm also now your consumer of course and the type is you know registering the consumer and will then of course updated it and this happens dynamically but also the unsubscription happens dynamically because if it's not not Vienna anymore then obviously the effect would have to go to the type and would have to tell it hey look I'm not interested in you in you for any reason or I don't know the reasons this is the dependent this is implementation specific but she but just please remove me from your consumer list and don't notify me anymore I don't want to run uh the console lock there again this comes it might might look strange like the glitch free effect but this is something which is first of all very good and in terms of contacting updating the Dom very efficient because why should something update when the type updates when I'm not interested in the type anymore because my conditions have changed so it's really a dynamic change of the dependencies which is buil in and we don't have to care about them we just provide our code or conditional code in angular order the signals will do the rest for us good and now let's do something uh strange let's say I say here const query this query and now for some reason mean this is not so Unthinkable actually I would say if the query is V then I want to say from now on the type is of type City now I can do that so I go back everything looks all right I say I search wonderful but now I type in Vienna and then we see all of a sudden we have an issue because now what angular has detected that there is a circular dependency it says hey wait a second you are an effect you are on the on the outer end you are you are not allowed to start updating a signal because then the signal might trigger another kind of um notification cycle and that could go on and goone so you could we could end up here with in an infinite Loop and that's why angular by default says this might not be what you really want but there is something where there is a feature for it where we can disable it and there are definitely some use cases where we have to say we have to disable it because there is no other way around the effect we have to use the effect in order to update another signal so what we have here is that we can say allow signal rights and then we set it here to true so if we do this and if I type then in here Vienna we see it changes back to City yeah and if I then click here on all and if I type in again Vienna it switches back to City again what happens now if I say I don't care about Vienna I say update it always to city like this would we have now an infinite Loop so I can type something in we see that for some reasons obviously the all is not updated anymore which is strange type City oh yeah sorry we setting it to city um then let's say here all sorry my mistake and then I type something in and then we see as soon as we do this it jumps back good the interesting question now is does it now update the city all the time time or is there some kind of protection for an infinite Loop we can try to find it out everything that I have to do is that I have to come up with another effect where I say hey um I am afraid that this type there is updated all the time please log it out once there is a real update going on and then we will see if we are in an infinite Loop or not so we have here the first update of City I say okay I'm typing something in I say all it is it is now saying all obviously because it has changed typing in another letter it jumps back to City another letter nothing happens why that I mean the query has just changed I have now typed in another letter well the reason is immutability I explained it before city is a string value it's City I it was City it I want to set it now again into City and then internally the signal says what do you want to do I mean this is the value which I already have why should I update why should I notify my consumers about this change it's the same value nothing has changed so it's not an infinite Loop in this case because we are always over writing we're always the setting the same value nevertheless be aware that these things exist be careful about them be cautious and if there is a need for it then of course you can say allow rights there is not there is now something else you can also start to trigger here for some reason another another signal or you can open up a reactive context for another signal here without even knowing it and this usually happens in the effect obviously and this happens when we calling here some kind of functions so if I say here I don't know I want to um say here when the quity changes I want to print out um maybe the maybe the type again then I would say Okay um print out search and what that one's doing it just says Okay um pretty Search print out the loog so I start here by saying let me remove it one remove move that one now I start now by saying here I want to have the query I want to have some kind of an implicit subscription to the query and whenever the query changes I just have to call it I don't even have assign a value uh to a variable it's just the calling is already enough then I say pretty search like this print out pretty search sorry so just call another function happens quite often you might be surprised how often this works when you use signals in real life and if you now go back and if I now type something in then we see here query with type all the problem is if I click here on City if I click on Country then for some reason the effect is now also executed and the reason is that although we didn't open up here the query in the effect directly we call the function and the function call what was inside of the effect and that's why the pretty search and not just the pretty search but also all the signals which the pretty search is using the query and the type were also included in this reactive context of the effect which means when the two changes this effect is also executed and of course it's also dangerous when a signal is updated there as well so for these use cases the pattern that we see is that we use the untrack function so we have two parts of the effect function where the first part we would say here comes the subscription subscription it's not we shouldn't call it subscription that's an rxs uh term more or less but nevertheless we have here those kind of accesses to our signals let's call it like this and then we have here in the Second Step the processing and the processing if we say it should not trigger any side effect or start with a new um kind of um it shouldn't yeah listen for for for for any further signal changes we use the untrack function so we put it in here and then we can say here print out search this is safe and whatever happens now in print out search will not affect the effect let's try it again so I say here okay I have here some kind of of a query they will all print out that's fine that was expected but not if I click here on City yeah then we see the city country that's of course coming from this effect which is still there but if I remove it then this print out search will not have an impact anymore yeah so I can then switch between here and only the console loog happens there as a nice side effect you can also then say you want to um update here a signal that also works so if I say here uh this two uh this type sorry this type set it to City and I do this in an untrack function then it will also not cause those kind of issues that we have seen before so if I say here all and if I type something in we see it switches back to City yeah so we will see but but this kind of untracked function is something which is very important please remember that you will definitely require it defect function is the moment is still in developer preview we will see if maybe there is not an additional change coming which deals with this kind of things a little bit better there have been some discussions on GitHub where some people including me uh kind of suggested that maybe we want to do an explicit um um signal tracking in in in that case uh yeah didn't happen but what what the engr team did is that some of their internal apis when they are called inside of an effect are that they are untracked automatically so we can do it automatically in this k sorry we can also do it on our own if we write if we write those effects um ourselves that will work and I will also recommend you to do it so whenever you see an effect please think about the untracked part first and um that you are on the safe side yeah and that was the advanced part and now we will take a look at the rxjs interoperability part so now about rxjs and signals first of all maybe some kind of background information cuz some of you might ask yourselves well what you have seen so far with signals this is something which is is very similar if not the same that we can also do with RX CHS maybe with RX CHS we can do way more yes true but why use signals why not why did we actually have to invent or why did the angular team actually bring in signals the reason is that first of all maybe RX CHS is a little bit hard to learn but there are some things which you can't or which is very you would have to go with a compromise in order to achieve it uh because this kind of effect that you have seen before that's very hard to implement with rxjs you might come up with special pipe operators but in the end uh so this pipe operator would say I am blocking until the change detection runs and then I'm taking the last value out of it but you have to be able to make sure that this pipe operator is used everywhere which is not easy and then the other thing is of course the signal always have to Prov provide a value and an obser doesn't Ober can produce multiple values but if you ask it the the very beginning maybe it says yeah there is no value yet you have to wait what should anger do then so if I'm a rendering engine and I say I want to start rendering now and the Observer tells me I don't have a value wait maybe in two seconds you will get one that's not an option so that's also a reason why signals are there but we still will have some use cases where we use RX chest and that's why it's important to know how to jump between RX chest and signals and there are some functions for that from angular itself so let me quickly start here by saying I have let's say a pretty date and I use for that a signal so I say here not the signal but an observable so I in the beginning the predate is a string and in my Constructor I say okay I have an interval where I emit every second in this interval first of all I want to see something so console lock tap driven development as it's also called and then I say I have my subscription in this case where I get my value or I'm not really interested in the value I just say this pretty date equal equals new date to local time strain of course you could not say hey hey hey wait a second why do use a subscribe please go with a w w with with with with an observable would be possible but in my case I decided to go it with to go like this so how do I use the pretty date well I just say here in my template here we have already some space I say here pretty date and it's another signal so if I now go back to my application we will see that it runs perfectly fine so here we have our current time now the thing is and the reason why I used here this subscription was the unsubscription that's always an issue so if we are dealing with observers we always need to find a way how to properly unsubscribe now if you use the Asing pipe we are always on the safe side because with the Asing pipe angular will do the UN subscription but we can now and this is the first of three elements from this interoperability Library we have now an operator where we can also do it if we subscribe manually and that one is take until destroyed yeah so if I save it now maybe sorry uh let let's do something else before let's rerun it um because the problem obviously here is that this interval is continuing so this this is now this kind of subscription problem which we have is the interval is still continuing although I have already left my component and it gets even worse because if I enter the component a second time a second one starts and this is why we need to use something like the take until destroyed so here I say okay whenever the component is destroyed then I also want that this observable and therefore also the subscription ends so if I now go back we see the console log is putting out printing out the numbers but as soon as I go to home it stops and if I go back then it starts of course again but now the other one is not there anymore the take until destroyed works in the same way as the effect before it is only possible if it has access to the current injection context otherwise it will fail again so if I would say here I'm taking here this interval and I move it into my engine in it uh then we will have a problem uh not because of the Observer but because of this pipe operator there yeah you see take until destroyed can only be used within an injection context that's the problem good there is of course one option you can provide the so-called destroy ref not the injector as it was in the effect but here the destroy ref manually the way how it works destroy ref I'm requesting it here by the dependency injection I say yes this is the D destroy ref and I'm providing it here as a parameter and now everything's safe CU now I can say okay the take until this destroyed knows now when the component is destroyed obviously and if I leave it the UN subscription also happens and you've seen it before uh this is safe so as soon as you use to take until destroy it you will get either a runtime era or it will work good but now I want to move on uh so what we want to do now is that we want to say actually it's nice that this is in observable but I'm want to have a signal out of it how we do how do we do this so I say here this pretty Tate actually should become a signal so I say here interval I'm assigning this interval to it I still have here my console lock I don't need the take until destroyed that is not necessary anymore and I also can't do anything with the um with the subscription here I need to produce the value like I would do it with any other observable namely with the map operator so I say here okay I have my map in I then just say okay new date in to local time stream time string like this another problem is how do we get from the observable string to a signal of string well we just say to signal is it's as simple as that yeah say h maybe not so first of all the pretty date is not used as a signal in the template so we call it like one we save it again and then Engler says you from my side From typescripts perspective everything's all right I would be able to render it but we see that the pretty date is a signal of string or undefined and this is something I don't want I want it to have to be a signal of string and the reason again comes from the observable because the observable doesn't give us a guarantee that it has every time we access it a value so we have now two options we can say I it's my responsibility but I now say um require async oh sorry not here but here there is an option for that require async true and this now really means as I said it if something fails then it's my responsibility which means we will get a runtime error so if I now go back and if the page loads we see here now a problem that so here we are that now angular says well you said it is a synchronous observable that the value is there from the very beginning it wasn't and that's why I'm throwing here a rtime error so maybe that's not the best thing that you can do a better option would be that you just say okay okay I am providing an initial value in this case it's the new date to Local's time string and then everyone is happy nothing will happen and in case the signal or in case the observable emits immediately it's also not a problem yeah without runtime exception and the nice thing is of course also the unsubscription from this in from this internal observable also works so if I go back to home then we see here it stops the counter is not increased anymore and if I go back to holidays we restart again from zero and for obvious reasons the same is also true for the other way around so I could say okay I have here my predit tate and I would say here I would get from this existing signal I want to have now the observable version of it it so I say here pretty date with a dollar and then I can go back to my async where do we have it pretty date dollar US theing pipe and it's the same um pretty date a think did I use the pretty search yes sorry sorry um should be pretty date yeah now it's working pretty time is actually a better better term for this but uh we see no issues and also if we go back uh then yeah the UN subscription of course also ends or also happens Y and that's it so these are the three functions which are available already since angular 16 the T will destroy the pipe operator the two signal and the two observable okay so with angular 17.3 we have this new API available which replaces those functionalities which were responsible for the component communication and that was the input the output decorator but also few child few children content child and content children the new API replaces them with normal functions that in most cases actually except the output always returns a signal and of course everything's backwards compatible so you don't you're not forced to use the new API but if you w to make use of the advantages of signals then of course it's a it's highly recommended and we are going to use them now in our holiday component and also the holiday card which is a subcomponent of our holidays component so let me switch to the holidays component back again and well let's start with the F chart because here we have a use case for it I say I want to access the NG form because I want to first of all verify if the NG form is valid or not and if it's not valid then I don't see any reason why I should start with the search method so I say here I have a required attribute and I also have a minan length attribute so I require at least three character now in order to verify it I I'll say Okay I want to have access to the NG form so the way how this used to work in the past that we had a few child and I said NG form NG form this is the type that I want to have and since I only have one form element in my template I can also use the class itself now I see already the problem typescript says no that's it's not going to work you can't just say it's an Eng form you need to initialize it so in this case I have to say undefined and of course I don't do this this is this is forbidden or is not forbidden but if if it would be up to me I would I would not allow it let let it put Let it put Let it put like this so what do we have to do now with this few CH because it is undefined we have to find a way how to access it safely so I can say here in my search of course that I say yes there is this en form and I know it could be undefined but I want to know if the if the if the form itself is valid and then do I want to start with the search itself which means at the moment the engine in it starts the search it's not available a few ch run later which means we shouldn't see any holidays so if I go back this is exactly what we see I can reload them no holidays are shown good so what can we do we can use the other life cycle hook the after few in it but there is some Modern approach which we have already since the major 16 of inula and that's after next render so this is a function that we can call one time after the rendering was completed and it is called not a life cycle hook hook of the component it's an application hook because we could also use it for example in a service it also requires the injection context by now we know why this is the case because of the unsubscription so the after next render if we run it in a component we don't want that it continues to run once we leave the component so that's why we have to run it in the Constructor so I say here after next render and I say well once this is done once the rendering is finished I say please search please start the search then form should be ready and we shouldn't have any issues I can remove it here I can also remove the Eng on in it it's not necessary the other one is now taking over like this let's see what happens ouch uh it works we see at least the holidays but we have here this expression has changed after it has been checked error and if you remember in the very beginning I said that signals will remove them as well and by now what we know about the signals it's also maybe understandable the way how they do it because the signal access only happens in the change detection it means it doesn't really matter when before the change detection runs some parts of the properties or the signal changes multiple times it doesn't matter because that will that won't have any effect it's always the last value that counts this also means that this error has to come from something which is not a signal and it is it says here loader component and it's a good opportunity Maybe before we continue with the F chart that we might want to refactor the loader component to signals as well because until now we have only seen signals how they were used in a component but it's not forbidden that we use it also in a service so I go to my loader component and there we see we have it this loading and observable with an acing pipe coming from the loading service okay good sounds good let's go to the Loading service and here we have our Behavior subject the observable and we say whenever I start with the loading I call start and once I'm done I say end or stop and this should now become a signal it's as easy as that so in our case we say well we have already the behavior subject so from the patterns from the signal patterns it's the same behavior subject gives us this guarantee that a value is every time available so I just have to say okay now I have my new loading it's now a signal of a false so by default we are not loading and to the outside I will expose normal signal a read only signal in that case so I say here loading and I say yes read only don't need the dollar there and when somebody says I'm going to start loading well then I just say Okay loading set um loading loading set to true and I also need this of course then here in the stop where I would then say false yeah and then I need to go back to my loading component where this error has happened and I say well loading is now is now a signal just call it and just check if it's loading then say visible is true otherwise say it's hidden the angular application compiles we go back to our template we reload our holidays and we see no runtime error anymore the signals have removed those kind of things good so now the loading uh the the kind of uh the holidays component is working again so I can go back and we still have here off you child and in this case we can now say okay we want to use another the new API and the new API says okay don't need the F decorator anymore what you do now is that you just say fart you call a function where you can say this is required and then you just provide me the value that class that you have done in the past to The Decorator so very simple so I say if you and form and you see that this is required is now something which is really great because with the required I get rid of the undefined of the Union type with NG form and undefined that's now only a signal with an NG form careful though this comes again with um with a requirement you are not allowed to access the signal before it's internally actually available so the same rules apply as they have done before if you access this engine form maybe in the Constructor maybe in engine in it then you are too early and then it will fail so if I say here in the Constructor uh maybe wait a second uh the form can go away or it should go away ah yeah have to call it of course now it's rebuilding and if I say here in the Constructor I want to access now my in form too early with lock so I need to really access the value just just just just using n form doesn't have any effect and if I now go back to my application we will see now an error because now it says hey look this view query was way too early you have to do it differently because it is a signal we have ways on how to react on it in a proper way we can say we want to run a side effect so the search could be a side effect but we can also say we want to maybe in this case is not but we could also run a computed for it we have those functions there we don't need to introduce new life cycle hooks we don't have to learn them we also don't know don't want don't need to know when this signal has now a value we just say look um we have now an effect and I say whenever this NG forms available I want you to run the search method this is what I want to do I don't need to after after next turn anymore it's nice that we have it but we can also do this with an effect I'm now going to remove the validators that we have so that the search always works and also starts with the holidays first let's see if that works writing to signals is not allowed in the computed this looks like now A Familiar use case a familiar error and if you remember I explained that four where I said hey maybe um be careful where do we have it when you have an effect that always kind of is a little bit sounds like trouble smells like trouble so just go here with the unra function uh put the here the the the search in it and then we should be always on the safe side yeah and in this case that's what what what what happened so again you have seen it with the effect careful when you call function I would just recommend by default always add an anract to it and before you do it Define here explicitly those kind of signals that you want to react to so my holiday component uses an app holiday card as a subcomponent in order to visualize the holiday itself as we see here this app holiday card contains an input with a holiday to eventers in the problem we know this already the input requires it to have an assigned value or it has to be holiday or undefined now with a new API I can say I'm going to remove here this input and as I have done it before with fart I have a function where I see input and this function now gives me three different versions the first one is that I could come up with an initial value in this case if I provide a string the holiday is of is of is a a signal of type of type string I can also say it's of uh the generic type string then this would be a signal of string or undefined what we had before or I just say required and say it should be a string then it will be an input of of type string and the same rules apply now what we have seen before in a few chart you have to make sure that you don't access this signal before it's there and again if you do in a computed or if you do it in a reactive context like the effect like the template then you're always on the safe side otherwise you are running into an you have the risk that you run into a runtime error and the same also what we had with the few child it's now the what there it was the enform which was then a signal of En form and with input we have the same thing again the holiday now becomes a signal again remember let me quickly switch this to a holiday remember what I said in the beginning when a signal component comes the signals will be the one that trigger the change detection so we have to make sure that everything that we use in the template is a signal because otherwise uh we might miss some dumb updates so if I now go into my template we see here some kind of issues this is something from the past where we had to access if or or request if the holiday was actually a holiday and not an undefined I don't need this anymore and in my template for the holiday here I can just call it it's a signal and I could not say if holiday call it and then as value or I just call here the holiday multiple times I think I would go that path so I'm done maybe not the best choice but the problems that I or the problem that I had with the other approach would have been you can say if you can say you call just the holiday and uh then you have here something where you say okay what do you say now it's holiday is it now the value should I also store it on the holiday or should I use it should I use value instead yeah we don't know we don't have fortunately no conventions for a signals with an observer it would have been a dollar would have been easier but here yeah we will have to find something out in the future for us the important thing is it works so the the holiday card at the moment is saying an input required of holiday and if I go back we have this kind of safe access to our signals because we are using it inside of the template what else uh we have an output so what we applied for input we can also apply out to Output so I can remove it here here here and I say instead of a new eventer I just say you are now an output of type number like this and to the outside nothing changes except we have to use now the output a little bit differently I mean little bit differently not really it still has the emit method so let's quickly go to our uh template we have here remove Favorite and we have here ad favorite the output is still this kind of provides still this Emit and to the parent components it's still an event so nothing has really changed here except that the output does not have this kind of binding to rxjs anymore and it's not a decorator why is the output not a signal well because it's an event and maybe putting a signal together with an event might not be the best choice we have also seen this by the way in our holidays component as well so here we had this search function which where do we have it the find didn't return a signal of holiday but it return return the promise of holiday but we use the signal as a container for the final result so this is the way how you can do it if you don't want to use rxjs for for more complicated use cases there will definitely be here an observable but for this it's enough if we say this is a signal and we fetch the value and put it into it but for output it's an event so there is no it might not be the best option to return here a signal type good so this is this is input this is output good are we done now we are not done there is something else I want to show you let's just say we have here this kind of basket um there it is so we can kind of put this holiday into a basket and let's just say we can only do it for one particular holiday now in my holiday holidays components I say I have here a basket or I say this is the selected holiday ID and I say it's uh the IDE is is one which is in our case the Norway holiday that one's now selected and I also want to print that out so I say here where do we have it we see here we have another paragraph where we say selected holiday um selected holiday it's not a signal but this will change and yeah now I want to provide this selected holiday to my app holiday card so I say here okay you will now get or as just a selected and I say you will get the value from selected holiday ID by the way if you're if you're wondering why I have here this kind of errors that comes from a former version of intellig that doesn't or at least now it doesn't support the new output function but that's going to change very soon good so I say here I have selected we know by now how this is going to work we say we have a required of a number and what I'm going to do is that I will say now if my holiday ID is the same ID as selected then I want to bring up the red background color or something like this so I go into my component there and I say yeah maybe here NG style yes I want to import that one and I say if there selected equals holiday ID then I want to return background red or BG red we will see it in a minute and if not then yeah it's just it's just nothing and I also have to put this into an array let me quickly check what the right CSS class is um BG is it red yeah BG red is there a five just a red let's use a 500 as most of you will probably know it was the wrong directive so it should be NG class and not NG style sorry for that good let's go back now let's retry it again it's going to work so here we have now no way what's missing that my holiday card now needs to tell my holidays component if somebody clicks on this shopping icon here because now it should switch from Norway to India so we need an event going back to our holiday card I could now say well selected change I say this is now an output of type number good and in my template I need to say where's the shopping cart there it is if somebody clicks on it then I want to say select a change Emit and I say holiday give me the ID and this is what you want to emit so far so good so this is maybe your output input is a little bit different different but this is something you have already done in the past and then of course the question now comes up how do we how do we deal with this here well it's two-way binding so I could use here that the banana box syntax the the longer version would have been that I say selection not selection change uh selected change and I would then say selected holiday ID equals event yep of course also the red thing here comes because of the not supported output and if I now click here we see that it's working good since this is two-way binding I can also say you know what you should also update the holiday ID when this event is fired so now again it's also working good but now I can do two things with the signals the first one I can say well this is two-way binding so there is now a new Tye for it and that's the model so I say I can I allow that this selected is also updated is also changed uh via my VI my parent component but I also want to be able when I change it here in my component that it fires a selected change event to my parent component and with model I don't need to Define this event anymore and it will still work except I have to be careful because in my holiday card now when I click on that button I'm not emitting an event anymore I need to update the signal itself so I say here selected not emit also not call the value but I say I want to use here the holiday ID to the outside to my holidays component nothing has changed it's still the old selected and selected change event it still works so if I click here again on India and click back on Norway we still everything works but what I can do now in my parent component because in the child component I'm already done that's already fine don't need to do there anything just model input and output but here I cannot make you I cannot use a signal for the select holiday ID especially if I want to run a side effect so I could say okay you know what this holiday this selected holiday is now a signal of one and I want if that one's going to change that it should rerun maybe it should it should maybe send a request to the back end or I want to have a computed which doesn't say selected holiday ID is is one but that says the name of the holiday and this is what I'm doing so I say your selected holiday or the pretty selected holiday holiday I say you are not computed and um I need to get access to the current holidays which I have so holidays I also want to know the selected one so this is the selected holiday ID and then I just say okay in my holidays find me that holiday where the ID is the same as the selected so holiday and then I say well if it's actually there could happen that nothing's there then um I want to return an empty string but if everything is all right then I say selected holiday uh holiday and um access the title so if a comput it of uh string return so signal string and then I go into my template and I say okay where do we have it here I say we have something better the pretty selected holiday it is a signal so we have to call it we save it we run it um we'll see selected holiday Norway yes so I click here on India we see India and then it's Norway back again okay and and this is everything that you have to know about this new API you can now work with signals you can make use of all its its effect computed functions reactive functions you don't need to remember the old life cycle hooks anymore and you're very well protected as long as you stick to the rules accessing the signals try to access it in the reactive context or in computed and yeah so input model output replace the input and the output decorator model is both so where we had in the past to come up with an own input and output decorator in order to provide two-way binding we have now one command that makes sense and the two-way binding as we have already seen before but also now the two-way binding also works if you provide a signal to it so that was quite a long video we have seen that signals are actually very easy to use especially if we compare it to rxjs there are some match cases for example that glit re effect and this implicit or hidden kind of reactivity which might emerge from the effect function so in that case as I've shown it you have one part where you kind of activating the signals that you want to listen to or where you want to be a consumer of and the rest then goes in the unrack function we have also seen that that RX Shar doesn't have to go away you can still use them maybe not in the components more in the services and it's very easy to jump from signals to observables but also to jump back so we have these kind of methods from the interoperability uh module available last thing is also then this new API and I think you have seen how easy it is when you have only to work with signals and you might not even have to remember the life cycle hooks anymore it's just is a better developer experience and we can expect that this continues and this leads me now to the last point I mentioned at the beginning that I highly recommend you to switch to signals although some of the the majority of those features are in developer preview now I understand that some say okay we want to wait yeah or maybe some say we want to wait until the complete signal kind of transition is finished we are done and we don't expect any changes anymore in terms of the angular framework because at the moment we see with every major with every minor version we see new features which requires you to update your code base quite often I would not recommend you that you wait until everything is in a way kind of done might take a very long time because at the moment if we look at it we know that on the in the road map or on the road map we have the signal components which will come out hopefully soon hopefully this year if you have that the next step would be the signals forms what those new forms module which has also already been announced next steps are already in terms of authoring format so maybe the import property goes away and we have still this optional rxjs strategy where again quite huge parts of the angular API will change HTP client the router for example where we have an obs available so we will there are some changes as well and if you say you want to wait until everything of that is done and only then you start with the implementation and maybe you say also if those features leave the developer preview then I'm afraid we are talking here about three 4 years and I don't think that you want to wait that you want to have a code base which you don't touch which you don't use the latest feature there cuz yeah I mean it's not something you want to have you have have a very very old codebase at the time so what I would what I would recommend is just the typical thing that most of developers do which have to deal with an existing code base that you just say okay when a new feature has to be implemented or when an old one has to be refactored or extended then you just uh come up there and and provide the signals or use the signals there or the latest feature that you can and of course over time we hope that that our application our code base will become more and more signalized in that sense but we will still have a mixture but that's I would say that's the way it is good so if you have liked this video then please give it a like I would also be happy if you subscribe to my channel and if you have any questions then please just ask Below in the comments section of this video thanks for watching and goodbye see you in the next video