AngularAir - NGXS: Power of Selectors With Mateus Carniatto

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on welcome to another episode of angular air i am your host justin and on today's episode we are going to be learning about and diving into ngxs selectors and some special stuff around that should be pretty cool looking forward to it let's say hi to our panelists then we'll meet our guests and then we'll get into the content joining us today we've got mike mike what's going on oh mike's mike is not ready [Laughter] mike turn your like on sorry i was bringing up the youtube chat and i didn't want there to be an echo of you coming through from the audio so hi justin how are you today happy to be here i'm doing wonderful happy to have you and i'm thankful for the non-echo of the youtube channel playing on your machine while we're talking alyssa is with us alyssa how's it going great so excited to be here awesome and bonnie bonnie what's going on i am very excited uh about the topic tonight and the guest who i'm not gonna spoil i'm gonna i called on you last so that you could introduce him all right all right all right i will uh everybody matt carneato hello matt how are you i'm good thanks very happy to meet you you're this is your uh second or third time on angular air actually the first the second time the first one was about angular connect uh and i was angular houston as well yeah the connect was like a panel discussion right and we were doing a bunch of yeah yeah yeah one day that was his debut baby all right now this is your episode we're excited to have you why do i tell our viewers a bit about yourself what you got going on that sort of thing yeah yeah so i have a slide for that actually uh just introduce myself but uh so uh i'm an angular architect uh in a startup in belgium i'm from brazil currently live in belgium um actually currently leaving russia for because of the currency um so yeah i'm also a part of the ngb organizing team i'm writing for in-depth dot dev i'm also a coach for hacker future belgium um and recently i i was invited to be part of the ng access core team which is a great team um i'm very passionate by njxs i think is a very interesting approach to state management and that's what i want to share with you guys today so have you cloned yourself because that's like a lot of stuff to be doing that's awesome how do you know all that to be honest nowadays is very difficult but uh my company my company starts working just three days a week during the the corona situation and yeah i had to fill my time with something now we are back full time and i still have all these things to do so yeah that's why awesome all right so ngxs yeah um i i i can't share my screen then just start do it okay cool so as a as i said i think we can skip this one no problem uh so why inject says right there is a lot of state management i don't want to enter in any kind of discussions one versus another um i just want to show some reasons that i this that brought me close to njxs and why i like this uh this approach so it levers typescript decorators to reduce the boilerplate um it allows you to use angular dependency injection inside your state it's progressive in a way that you can have just a core state and add plugins to improve the add new functionalities progressively you don't need to bloat your software since the beginning and change completely your approach and has a very great community uh i started engaging more with the njxs right channel and it's amazing you you post a question there and it's very hard to be the first one to answer because we just have a lot of amazing people answering there so these are the reasons that brought me to njxs a couple years ago um and so i think we can start so the very base concept is very similar to other state managements the issue is basically you have um you have a your visual component and to when you change something you dispatch an action uh to your state this action mutates your star or can also fetch something from your back end we have the concept of async actions um and then if you if you want to get something from your start to showing your component you select a slice of your store so it's very basic so how we can start with ngxs so it's a state management for angular so the base is you're using angular to be able to use and success and it's very simple you just have to install the package so you can install ngxs store save and then you have to create your state your state is basically a class that you're going to decorate with the state uh decorator right so i have a small example here so i just create a interface to describe how my state is in this case we're doing it to do is just like a name strain completed boolean and then our state is just this class that is injectable because we we can inject in in the in your components or services and the real magic that transforms uh adds some metadata to this class to make it a state is this annotation so state is a generic of type to-do array uh i give a name that i'm going to see in my the dev tools and the default in this case just right here then i just need to add this state to my root model so i just do ng-access model for root pass my state and i like to enable development modes when not in production and what this does it's going to raise an error whenever you change your state in a no immutable way so in production you of course you don't want your user to see your air horse but while developing unless you have some library that enforce immutability you can enable this flag just to be sure that you're not changing the states state in a no immutable way so i always enable this flag so with this you have your state run right but just having the state is not enough we need to mutate the state somehow and for this we create actions actions in ngxs they are simple classes with static prop with a static property type uh which is just a string of your of your action uh i like i really like this pattern of wrapping your actions in a typescript namespace so in this case i have a namespace to do actions and then i can do to do actions.loads or to do action dot ads when i use this these actions i'm going to show how to use these actions but this is basically the definition uh we have a simple action here which is just a load or you can have also a action that receives a payload in this case our payload is described as arguments to our constructor of this class so okay i have my actions but how do i react to them right what happens when these actions are fired so njxs is very more inclined to it's more based on cqrs so it's really you have commands and you have queries your commands are your actions and your queries are your selectors so whenever you fire an action you can have a handler for this one or more handlers for this action so inside our state we can use again another decorator action at action passing here the type of action in this case to do actions had to do and and then i have the handler which is the function that's going to be run when this function this action is dispatched so energy access is going to based on the the type of action that you that you've dispatched is going to by reflection uh find which handler has to be ranked so in this case i'm just uh completing a to-do so i just have to set the complete to false and then i update my state or i can also in engxs i can have a synchronous action and this is very simple i can just in the line 8 here inject my back end service as a angular dependency and then i can return observable and ngxs is going to automatically subscribe and unsubscribe to this observable after the first edition so then with the pipe tab i can update my stats so it's very clear yeah what real quick so what well ng xs since it automatically will handle an observable would also automatically handle promises or not yes that's a very good question yes so if you have something like uh ng angular router and you do a navigation you can return a promise and also ng-access can handle promises same way it's very very exciting so in this in this case you can have either a synchronous or synchronous uh actions uh and they and also uh interesting thing when you access is that not necessarily your action has to result in a change in the state you can have an action just to um fire a banner or to show up a model or something like this so this is a small difference from other state dimensions okay so now i have my action handlers how can i dispatch these actions actually it's very simple we just need to inject the store on the constructor and this store is imported from njxs core and then we can do this.patch and when we dispatch an action we actually passing a new instance of the action because if you remember our actions are classes so with this injections can by reflection say okay this type of action i can connect to this sentence or another example here if i have a payload i pass on the constructor of this action when they do the new statement so with this uh we already have actions and we can change our state the next step as i said like we have commands to change the state or possibly uh do some side effects and then we can we have to withdraw this uh information from the state so this is what we call select so it's very simple as well you can use a decorator add select and you basically pass to this decorator of a function that slicer states in this case i'm taking the to-dos this returns an observable uh of to-do array and i can use this with a pipe sync on the on the template or even subscribe to it and do some changes another option is to inject the store and then we can for instance create an observable completed that's going to return me only the completed to dos so i can easily just pipe since this observer i can just do a pipe map and filter the completed ones there is a way more extensive api for selecting you can select a snapshot you can select only once if you want as well but here i decided to show just the more normal use case because i really want to show the real deal about selecting stuff which is not with this store that select is really leveraging selectors which is the next slide uh so basically what's the selector selector is a memoized function that slice your state free the cool thing about selectors is that they they're automatically recalculated when you do changes on the states and they are automatically memoized so you're never going to execute a selector more than once unless needed so how we can create selectors for example again another decorator you can see that ngxs is heavily reliant on all decorators to to eliminate a bit of boilerplate so we just have to say to decorate with uh add selection hey matt can i jump in and because i want to add something here this was really confusing for me when i first learned ngxs the selector because i was working with uh austin uh when he was writing this we had switched over from ngrx and we were writing actions and and all that kind of stuff and the selector was something like i didn't understand where that was coming from and when he said memoization i had not even heard of memoization before this and austin had to explain it to me can you explain to us what the memoization is because it was very mysterious for me i was like where the heck is this coming from and i know it's something that that comes in from huh i know because this was well and i mean yeah so it's it's uh and he's telling us what it does but i just wanted to elaborate a little bit more because this was something confusing for me yeah it's just so it's just the idea the idea of memorization and i'm going to give a very simple explanation here right so the idea is if you have a pure function which is a function that only relies on its inputs to so for the same so the same inputs you have the same result uh you can memorize this function which means you can cache the result of this function using the inputs as a as a key so for the same inputs you don't have to re-run the function because you already know what the result will be so you can already return the episode right so that's what memo is memorization does it creates a hash map based on the inputs with the results that were calculated before so unless the inputs of this function change you have no reason to recalculate you can just retrieve this from memory that's what memorization is and usually and i think the thing that was crazy for me was it's doing it for you so you don't even have to do anything it just it just handles all that for you under there which is actually really nice because you get uh state management and it's really not that much code which is really why ngxs is nice i think that's why it's become popular is because it's not that much code really that you need yeah yeah it's hilarious sorry all right go ahead no problem uh i i definitely think that the the beautiful thing is the selectors in state management especially ng xs i'm going to show some advanced um examples that where they really shine but indeed everything goes boils down to having this automatic memorization that you don't have to really care about it the framework does it for you so a good example here is like if i want to get completed instead of doing all that rxjx magic in the front end i can just create a selector here using add selector that's going to filter my to-do's and interesting interesting thing is that inside the selectors i don't have to think uh reactive so i don't have to put pipes and maps because here i just get the state and as i build a synchronous pure function right so it's very it's way simpler than the code that i showed before so if you if you see here you have to know that you have to put a pipe and have to do a map and and and do and finally you do your filter right when you do this in a selector you can just do like very simple synchronous code and this is memoized for you so in this case unless the reference of the state changes or you have some change in the state this this uh the result of this selector will never change so even if i have multiple components subscribing to this selector it how is going to be returning the memoized that in the in the further examples are going to show how we can improve improve a little bit more how we we do this memorization to avoid different more running unnecessary calculations before you move on so you have the get completed method or function on the inside the to do state class yeah and down below where you're using it on line 16 it looks like it's using it as a static method there yeah i think i think there is a small stake here it's a it's aesthetic it should be okay that makes sense yeah i think i have a small typo my on my slides here thanks for pointing out this one i just want to clarify yeah it's aesthetic definitely yeah cool and that makes sense okay uh your method yeah so now the important thing to note here is that when you declare a select or inside a state class uh you have automatically injected the container states right uh this can can have some uh issue it can cause you some issues so in the next slides i'm going to show how we can improve this because sometimes you want to have a selector that relies only smallest lives of the state instead of the whole state but we can we can improve this um and i'll show how so then as soon as you create this selector don't forget about the static flag there nice point and then we can use the select uh decorator on your component and pass a selector so that's why it needs to be static because we're not distantiating a new to-do state we're just using the function and we're going to have our completed uh observable here or we can also use with our disk.store.select in a more declarative way uh if you don't want to use the decorator to simplify your life i i personally like the fact that for some components that only breeds for the star you don't even need to inject the star you can just have your selects in the beginning of your component right so this is basically how to use injectas right so it's basically you have this state which is a class and you can register action handlers dispatch actions using the the store or and select using uh this add select notation right can i ask a question really quick about unit testing yes so like in that case i i like the point that you just you guys are so amazing because you guys you guys are really asking things that i i'm prepared for so that's amazing cool so that uh line 16 where you just mentioned that like the simplicity of that makes it so that you don't have to inject the store into your component right um so if i was going to unit test that then i guess the approach would be that if i needed to mock out the get completed i would just in my unit test mock the to do state get completed method for that class spy on it or whatnot and say hey i'm going to return this value and then i'd be able to test my component with mocking that part out right exactly you don't need to create a store initialize and inject your constructor you you can just do component instance dot completed and pass a mock-up server so this also makes it easier for you yeah that's nice that's nice the selectors are also a very good way to improve your unit testing but we will get there in a minute so just a quick um suggestion before uh we moved to the to the main thing which is nhxs has uh mike mark whitfield had this a very interesting feature to it in the 3.4 i think uh version of energy access which is state operators because whenever you doing working with states and you want to just change one slice of the state you always have to to do some spreading and be careful that you're only changing what you want if you want to keep it immutable right so from the 3.4 version of njxs we have state operators which is just very simple pure functions that allow help you to to update your state in uh in a mutable way very simply so we have all these guys we have insert i can remove eye contact and append for dealing with arrays and we also have patch and compose to to patch to to mutate your objects and compose if you want to do more than one of these guys at the same time and you can also create your custom ones we actually have a thread on github with some community built uh custom operators that are very interesting and the most voted ones they they might make to the core of nhxs so just to show um so before uh what i did maybe i can even show before what i did when i when i was changing my action so you see when i'm adding a completing yet to do i have to spread my state here because i don't want to change anything else that was the state in this case it's a very simple state but when you have a state with mutual properties i have to spread my state and be sure that i'm only adding one to do right uh when i when i have when i use the state operators sorry for the back and forth uh i can just say update item so i'm going to play just the item that has this id this is a selector and then from that item i don't want to play the name or anything else i just want to play it completed so i can just patch that object passing only the the the changed object to to patch so this creates a way more readable semantic when you doing your changes on the state so that's really really nice ergonomics for that api because if you ever got down and like you could imagine that your state object could get very deep in in nested properties right and to just update one piece in one thing way down the tree can be a lot of verbosity i don't even know if that's a word i'm throwing it out right yeah very very 50 cent word there we go uh very very both to update that one property just to write the code to get there and so now these helper uh methods make that really nice clean elegant that's awesome yeah there is another big advantage is since you can do a sync a sync function a sync operations in your actions if you take your state before your synchronous action and then you use this snapshot of the state to spread when you set your state after a sync function this state might have changed by another action right so this kind of inconsistencies if you're using this state operators you're always getting this latest snapshot of your states to make these operations so you don't need to do to care about this the the situation will do it that's right so it's like the memoization right it the the framework provides that for us we don't even have to think about it but we get this magic awesomeness yeah that's cool there is there is another interesting thing mark told me to to make it clear here is that this state operators they don't need to be used only with set state so basically they can be used even without ngss because they basically you basically pass when you do patch completed you can it's a genetic so you can pass a genetic here of your object object and it basically returns a function that tells you how to update your object so possibly you could even use these state operators to keep immutability in other parts of your code that's not exactly ngxs so they are very very powerful uh so this was just an addendum because i really like this feature to to make her code very readable now comes the the big guy i think it's going to take a bit of time to start up on stack blitz usually it takes i have it running on the sides can you guys see yes okay so i did uh to do a to-do app is like almost everybody does and it was very good to show very the best things but it's not enough to show the power of selectors which i really want to talk about so i did an interesting app so without the covet situation i start cooking more and more at home trying to be more healthy and not get super fat without things and the the quickest thing is to make a shopping list based on the recipes that you want to cook right so i decided to make this very simple app where you can filter by which meal you want to see your recipes and i can't believe you didn't put carrot pancakes on there matt uh i just did them recently but they are amazing there's a picture on his twitter and it looks really good so you can filter them here and add the recipes that you're planning for that week you have a counter here and then you can either clear a list if you not satisfied or you can view the shopping list you can print screen this go to the market and you sure that you're buying everything you need so it's very simple app but really helps to demonstrate um some of the the ideas that i want to bring with the stock so basically we're going to be building these features in each slide oh no we have to render here so just to to start okay before we do what sorry to an egg well on the the shopping part you're talking about eggs in you in minutes so i was just curious what was that one egg hey matt fergus wants to know uh why there's no recipe for mammoth curry mammoth curry uh i didn't try this one yet uh don't mind him he's a troublemaker it's an obscure ingredient oh we love him though he he asks really good questions and he's just here to give us hard time so uh the model for this this guy is very simple so i basically have a recite recipe state model with a recipes array and the selected recipes which is just array of ids and then just scrap here what's a recipe and what's an ingredient because i i need the structure and also the the types that i can have of recipes so it's very simple um so let's start with this app so before before i start with the features i just want to to show some adjustments that i recommend for when using selectors heavily in gxs so by default like like i showed you guys um i have i can define my selectors aside by state and this is good and all but i always going to have my state injected as the first argument this means that my memoization is based on the reference of the state so whenever i change anything in the state since i'm keeping my state immutable i'm going to update the reference of the states and all my selectors going to be recalculated that's not exactly what we want but we can improve that so we can go to ngxs options and set two options uh these options for now in the version 3.6 which is the the current version they are they come as true by default but they're going to be false by default on the ver the next version 3.7 uh we in this form this options are suppress errors so by default whenever you have an error in your selector it's just going to return on the files in your stream that's not what we want when we're going we want to start using selectors extensively because we want to know what's the the issue with our select so we can fix it and the second one is injector inject container state false because i don't want my container state to be injected implicitly all the time because i want to be more strict in what what are the parameters of memorization that i'm going to use in my selectors right so setting these two guys to false we have to adjust so just as two guys and i have to adjust my selectors to work with this because now since my my selector is not injecting this state by default i have to pass my dependencies to my selector so the selector decorator receives an array uh with my dependencies in this case sorry the recipe state and then this is going to be the first argument so here i didn't change i'm still relying on the state i just wanted to show that changing that flags to false we need to do this change another recommendation that i have is to extract your selection selectors outside of from outside of the state why because as your state grows you're going to have more and more selectors hopefully you should at least and your state fire can become very large uh and grow out of control so with any access we since these selectors are nothing more than static per functions we can extract this to a state selectors class right so this i just create a new class in another file and i have here i have the static the uh static um mic i didn't forgot here uh and it's the same syntax i just declare in another class and since this parent class is not a state i always have to explicitly tell what army dependence is so setting the flag if you have couples a couple selectors inside your state you should set this flag to false and do explicitly your dependencies if you have a selector already in an external class nothing's going to be injected anyways because there's no container state so you have to to use this notation here so this this is just like a preparation to start using and then to use is the same as before we're just passing a static method from the state selectors class so not uh not a big change there so just uh some uh recap from this this point enabler selector air horse controller dependencies and structure selector their own class because they become way more easy to test so if you look here this is a class with static functions which are pure functions so testing this you don't even need test bed or create your model you can just test as a pure javascript function so it's very very easy to test right so that's why i like to extract them and also the separation concerns you have if you need to change any of your selectors you have a file for it you can easily find your selectors there you you also avoid your state uh class to grow out of control so would it be fair to say that you you also get this ability to do these composition selectors where you say you have two pieces of state right your recipes and maybe something else from somewhere else because that takes an array of state objects or state classes you could inject in two different state objects and then make a composition selector that pulls data from paul exactly that that's what we're going to touch on the next point thanks jesse so yeah you have great content i'm just helping to set it up yeah you're amazing man actually i i'm happy to come back to angular anytime but indeed see where we keep him around he's handy yeah but indeed uh a big advantage here that i'm not going to show is that you can actually pull two two different states so you can have a meta selector as we're calling njxs where you pull like a preference state and recipe state and create a selector out of these two states because this this class is a third file is a third class so you don't have any container state injected here you can just pull two different states or even selectors from other states so that's what we're going to touch next so the first feature i'm going to do this show these three cases building features of this app that i showed to you guys so the first one will be the recipe counts so as we select our recipes i want to just show a count of these recipes right so a very initial approach like let's do the simplest way as possible i just okay now i know how to create selectors and i know that selectors are are memoized so they're very good i can just come here and create another selector i take my recipe states uh call it select count and and then i just take my selected recipes dot length so not nothing wrong with this but we still can improve a little bit because what happens here since this guy relies on the state when any change in the state is going to recalculate discount but what we actually want is that discounts is only recalculated if selected recipes change right so how can we improve this and this is exactly what justin said we can compose selectors right so basically i have a selector here for state dot recipes and i have a selector for selected recipes and then i can create a third selector that gets this state selectors selected selected recipe and then i based on only the selected recipes i returned account the bigger difference here is this the selected recipe selector will only embed if the result is different than the previous result and this is based on reference in this case is uh is a reference of object so even if my state reference change if the the reference of the property selected recipes didn't change this selector will not emit what this gives us is that the selected count is going to have is going to to be a selector that only emits if the account the selected recipes array changes so we can limit a little bit how how many how we do our memorization because now our memorization is on top of just selected recipes not on the whole state so this is very easy to to be seen so in this case even when i select a new recipe here i have my my recipe updated but if i move to another tab when this this selector is not emitting because it's not recalculated i'm not changing my my recipes and how to use this guy okay is the same way that i showed before you can use just add select select that count and that's it and because you broke that down into smaller pieces right and you mentioned each of these are pure functions if we wrote a unit test around that one that you have highlighted right now all we have to do is pass the selected recipes object into it we don't have to mock out the entire state to test that one function which is awesome exactly uh i another another cool thing is that when you build selectors like this you're kind of creating an api for your feature so if you have a ng access state for each one of your features and you want to expose actions and selectors your consumer doesn't need to know the structure of your state it just know that he can take this properties right so if if later you have to refactor your state and change your state structure you create this very nice facade that isolates your state your your consumer from your state structure so you can see if you keep the the the contract of your selectors intact you can change your state structure and that don't impact any of your consumers so this is a very nice pattern to have i want to just uh piggyback on that comment because i had a conversation a while back with mike ryan and a couple other people were talking about this concept of assad's and a lot of people think in terms of i need to wrap my state management in a facade to abstract that layer right but if we really get down to exactly what you just explained the the state library can provide that facade experience by the actions are the methods and the selectors are the getters and that becomes our facade that we already have like you know and because it's decoupled rated a bit you know with that api signature then that really is a facade that we can utilize and mock and do all the things we need to do in terms of what we think about for a facade yeah exactly so if you have a big application like let's say you have a nx monorepo with multiple features and libraries you can just expose uh on your index uh in your index dot yes only your selectors your selector class in this case and and your actions and you don't have to know anything about that state how it's handled what how is the action handlers how is the structure of the state it just use the facade which is your selectors and actions so this is this really boils down to the concept of cqrs which is you have commands and queries and how everything is handled inside is a black box for you so it's that's a very nice separation of concerns when you when you combine this with the high high testability of selectors it's very easy to have a consistent uh test if you change your state and you have your test assuring the contract of your selectors you just have to fix your your code to match your test and your contract is preserved so none of your consumers have to update their code so i recently refactor a big codes that we have in my company with ngxs and since we use selectors readily we could change the structure of the state and breaking smaller bits and make it more more readable without having to change any of the damp components that i have in my ui because they are using selectors so i just need to keep the contracts and a lot of times when it comes to selectors there's a lot of business logic that could end up at that level right where you have to determine this combination of data returns right and so by putting that into the selectors like you mentioned you have that nice isolation where at the component level at that application level that thing doesn't even have to be touched and you can fine-tune the underlying business logic as as needed yeah i think i usually think of selectors as the home for your business logic because then it's very easy to test as we discussed and if you have your own business logic here your your dump components can be extremely done and they don't have to think how for each change on your state you have to recalculate something so selectors give you the control to say when your business launch has to be recalculated and also memorize this to you to avoid recalculating that doesn't need to be recalculated so it's a very good home for the business logic for application it's so funny to me because when i sit here and look at this code i just it makes me think of austin mcdaniel and i remember being so frustrated with him when i first saw the selectors because i was working with him on a project and he was writing these selectors everywhere and i kept going what is this where is this coming from and i didn't understand because he wasn't there wasn't anything going on and uh and then he explained oh i wrote this library and i was like i need to know that uh but the thing is it was frustrating because he didn't explain it to me and i kept stumbling across it and getting confused but once he showed it to me and how it works uh it really was beautiful and the the it's like you were saying the components uh really were very small uh not that much code it was really nice code yeah uh the the two takeaways from this for me is uh you can control when you compose selectors you can really control fine-tune when they are recalculated and that recalculates only when needed and also reduce your code repetition because if you have a selector to take your completed uh your selected recipes in this case it's just doing dot length but you if you have a more complex selector you don't need to rewrite this code you just need to reuse the selector in another selector so you can really break your coding small reusable bits so this these are the two main takeaways of this this section the next one is adding and creating the shopping list right so it's just like i add my my my my things and i can see the shopping list so i issue a pro actually before the initial approach i i just wrote this very ugly function here just to show that sometimes our business lodge can be very tricky and full of fines and maps and reduce and all so this is just like to to retrieve the shopping list using selected recipes and my recipes right so this clearly this looks like i have very limited amount of recipes but if you have something like myfitnesspal we don't want to run this every time right we only want to run this when really needed so but from now on we're going to call this just retrieve shopping list i just want to show like uh get sometimes your business launch can be just a bit more complex code right so uh i initial naive approach for this would be okay uh wait i think i jumped too much uh i'm going to select recipes right i'm going to select rest so select my selected recipes and then in the ui i'm going to do a combining latest of these two because my two slices i'm using selectors i'm seriously selected but to combining on the ui and then i have to put a pipe and do a map and then apply this function what's the problem here uh whenever i have a new emission i'm going to do all this rxjx for if i change my recipes or if i change my recipe my selected recipes this is always going to run there is no mobilization right and on top of that i have to have no should i use combine latest should i use fork join should i use zip or map is good enough for me or should i do something else so there is a lot of rxjx flying here right we can remove almost all of it just using selectors so we move to selectors in the selectors world everything is synchronous right because we always dealing with snapshots so it's very simple we can create a selector that gets our two previous selectors recipes and selected recipes and then i have these two guys here and i just applied a function advantage of this is very easy to unit test right because i just have to mark two arrays and second i'm memorizing this so unless i change my recipes or i change the selected recipes i don't need to retrieve a new list so even if i have change whenever when i do something like a same type of sync in the in the ui if i have a refresh because of a parent component or something like this i would in the other approach i would have to recalculate this or if i navigate to another page and come back i would always be doing my engineering needs and recalculating this guy if this isn't a selector it's memoized even if i navigate to another page and come back it's going to returning in one uh clock is going to return the result because it's memoized right unless i change one of the input parameters all right so if you already just want to call out really quick for our viewers and listeners uh rewind that and listen to that part again because there's a nice golden nugget in there for uh like what that benefit is it takes a minute to sink in so just after we're done go replay it listen to that one moment again because uh that scenario with the async pipe and stuff is is a great point so take aways keep you it really helps to keep your presentational components very damp you just have to select a selector you don't need to put a lot of rcx uh mobile jumbo there uh improves your maintainability because yeah you have one place to change your code uh and also reduce the need of manipulating streams you you can build your code more synchronous instead of should i use combined latest fork join or something like this you can simplify your your life a lot just moving your logic to selectors in the last one this is a very interesting one the other benefit uh because we talked on uh testing as well is that it improves testability it's a lot easier to test the service or a static class than it is to test the component so the last one is one that i really really like and i think is quite unique for njxs so we're going to be building this filter by type because sometimes in this case we have a state on the component which is what's the tab that's selected and we want to match this with something in the state right so a very naive approach would be let's save my filter in the state right so i create i can create another uh selector i'm not showing here like we have to create an action set filter we have to save this filter on this on the state uh this this kind of implicit here and then we can once we have this state the filter on the state which is this guy here uh we can create a selector that takes the recipes the filter so we're doing a composition of selectors great but we have to save this filter which is a very local state of your components in this in the global state to be able to do something like this to filter by type gladly there is a better way of doing this we can use a base selector so a lace selector is basically a selector that returns a function the cool thing so in this case i'm just injecting recipes is the only thing i need and i return a function that gets the filter which is a result type and do the filtering for me there is a very interesting point here which is the the function that returns the the selector that returns a function is memoized based on recipes and the inner function is memorized based on the filter which means for if i pass the same value for filter this inner function that's highlighted right now also going to be memoized so we have a double memorization here and we don't even need to to know about memorization right that that's very great so with this what we can do in our in our component we can't just select our get recipes by type function which is going to return observable of a function and then we can just use the we can have a filter on the damp component instead of saving our state we can just keep this state on the on the components and of course when we select we have to save the in the state of the component and then in the in the template we can just unwrap with piper sync or you can use something like rx angular which has a rx lat which is better than a type of sync in this case to get your function and apply on the filter so the cool thing here is the filter never makes to the global state it's a local state of your component your your global state and your energy access state doesn't need to know about filter it just provides a function that you can run for different filters right and this function is memoized so even if you go back and forth on the steps it's going to run only once for each step after this it's memoized you don't need to calculate this anymore right so this is a very interesting way uh and this can be used as well if you have a structure uh like i had a case where i had a three ma a three table that had a structure that that could not be immutable because i need to keep reference of all the nodes all the time uh so what i did but i needed to update some nodes eventually using my state so i just had a lace a lace selector that returned me how to update a node based on the id and i could keep in my visual components this huge tree structure and i just you pass the id to this function to update each node so there is very interesting things that you can do with lace selectors so basically how to think takeaways to leverage lace selectors which are very great there is other types of selectors in inch xs as well that are not covering here but this is one that is very dear to me uh you want to run your code when needed because again you you take a next step on your memorization you memorizing not only the selector but also the inner function from your selector and if i never change my my filter here if i never if i load my app and i mean all and i never go to the other filters i'm never going to run for these other filters right so i avoid running the same code twice because i have double memorization and you keep your state link you instead of adding everything to the state because this is something that happens sometimes you start using state management and you you just put everything on the state right because you have to to use this in your selectors you have to use this in the other place uh with this is very you can keep your estate link and only put your state things that really need to be shared in a known parent child um fashion there is a bonus tip uh it's very small one uh but yeah with energy ngxs you can use the redux devtools as well uh i i start putting these on my slides because we see this question very often in the slack french xs because they know that nhrx has it and other statements has it uh ngxs also has and very simple to do you just have to add uh install ng access devtools blocking and then you can add the plugin you give it a name just to show in the in the extension and i recommend disabling for production so no one can mess around with your state introduction and you can use the regular extension redux has as left tools so just a quick recap uh of things that uh i think is the main takeaways of this talk use use type script name space for your actions it's very nice to create uh it's like creating a barrel file for actions so it's very you just have to import it it creates a very nice alt complete for your actions uh use state operators to make your codes more readable and also don't have to care if you really updating only what you want is way more simple somatic adjust your selection options just to be sure that you not injecting the container state where you don't want structure selectors to their own class this makes it more testable separates uh has a better separation of concerns and also you it makes a good house for your business logic composer selectors so you can separate in smaller bits your your code so you don't have to repeat yourself and you can really reuse this logic and be sure that this logic is only run when you need it move your business logic to selectors we talked several times mike and austin also made very convincing points how this becomes more testable and how to create this facade where you can really have an easy contract that decouples the state structure from the api that you're building your with your selectors and the last one leveraged last selectors to keep your and be sure that you want to calculate um you only run a business logic for things that really needs to be run instead of running for for all the options if the user never called them i'd like to thank you the the opportunity uh i also thank you the njxs core we have a i have a a nice image that i would like to share here this is also our ng access core uh around the world the ngxs team map thanks alexa for for building this we're working very hard to bring new features the version 4 is going to be very interesting we also improving our documentation to to make it more accessible uh yeah try try and actually ngxs out and pingas on slack we're going to be very happy to bring you guys that's all awesome very awesome all right well we're at the top of the hour so let's uh do some final picks if anybody has any picks and then we'll wrap it up i see hands being raised bonnie's andre's uh first our panelist oh i have two really really quick picks uh first one is angular air episode 153 which actually quick trivia was the debut of ngxs with austin mcdaniel and danny blue back in 2018 and my second pick is uh mark whitfield who actually just jumped into our chat he took over the ngxs project when uh austin left and also brought in matt carneato and mark whitfield is really a nice guy uh super sweet i i i think everybody i've ever known that knows mark just thinks he's a great guy and he's really nice so uh the support team on ngxs is really good if you ever have any questions so uh matt tell mark we said hello well he's here in the chat so everybody say hi to mark whitfield and great show matt thank you nice all right mike alyssa you got any pics today or i do mike you mind if i go awesome uh thank you matt so much for coming on i'm about to head over to the twitch channel code it live to do some ui stuff so come hang out awesome mike i just have a reminder pick i picked it i may have been two weeks ago now the umbrella academy coming out i'm super excited it gets released in two days um on netflix so season two be sure to check that out if you haven't already it's a pretty cool show nice nice right our guest matt did you have any pics that you want to share i have two actually uh one of them is not super new but uh i'm very happy that i started reading is a book it's actually a series of books the first one is called we are legion we are bob so it's a fiction book in a dystopian future so it's very cool for someone that likes tech it's very very interesting it's extremely captivating it's it's incredible i really recommend uh there's three books uh is a trilogy but it's incredible i could not stop reading it and the second big since we uh mike said about uh umbrella academy i would recommend dark dark just uh aired the third and final season on netflix and it's mind-blowing like if you like time travel if you it's amazing and it's a german show so the production is very unique so i highly highly recommend um these are my clicks nice nice i'll have to add that to my watch list another one of the mini ones that i have along with umbrella academy but awesome hey matt uh thanks again for coming on the show sharing your time sharing your knowledge we really appreciate it and it was great having you on and really look forward to having you on in the future too if you have any other times you want to come back thank you all right thank you awesome all right that's a wrap have a good one everyone catch you next time see ya cheers
Info
Channel: AngularAir
Views: 1,887
Rating: undefined out of 5
Keywords:
Id: y3F99IsnNvI
Channel Id: undefined
Length: 61min 34sec (3694 seconds)
Published: Wed Jul 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.