Simple State Management in Angular with Ngrx Component Store

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone i am seb khan and i am a front end engineer in this video i am going to show you a simple way to introduce date management into your angular apps the ngrx team has recently introduced a package called component store on the face of it it is meant to manage state at the component level but with little effort we can use it to maintain our global application state as well this makes our code much more readable and maintainable so let us see how we can add the component stored to our apps i have here a simple contacts app where you can store your list of contacts search for them add a new contact and delete a contact oh and you can also call a contact directly using the phone button now this is built without any state management so let's go through the code a bit i have here a header component and a contacts component the header has a title it has an add button and it has a search button for the search and add functions we need to emit an event because our data is contained in the main component then we simply have some handlers in the main component which do the necessary changes in our data in the contacts component we take in as input a list of contacts and we send back an event when we delete a contact this is then handled with the delete contact handler in the main component now this is a simple app but if you have multiple nested components then you tend to get a lot of events and event handlers and it can quickly get very messy with the global store however you can avoid this issue entirely we'll see that in just a bit now that we know a bit about our app we can introduce the component store first let's install it with ng add at ngrx component store latest great let's then create an interface for our contacts data so we can use it throughout our app we'll create a new folder called models and we'll create a new file called contact.model.ts we will define here an interface called contact with just two properties name and phone next we will create our global store itself so we'll create a folder called store and we'll create the or contacts.store.ts file inside of it the first thing we do here is to declare a contact state so we have an interface called contact state which would have our contacts below this we will add an injectable decorator and create a new class for our store calling it contact store we are going to extend it from the component store with the type of contact state great in component store you can initialize your state with a constructor so we'll define a constructor and use the super method to specify our initial values in our case we'll shift the contacts that we have in our main component here now we'll go in our main component and get our contacts from there copy and paste it here great so we have our data in our store now but how do you get that data to your component we can define a selector if you're familiar with redux you'll realize it's the same concept so let's define a contacts selector here this will be an observable so we are going to say observable and we give the type of array of contact we'll use the this dot select function in the store where we have the state passed in and we can return whatever part of it we want in our case it will be state dot contacts great so let's then switch over to the store in our component now component store is meant to be used with a component in its state but since we want to use it as a global store we'll just bind it to the app component since that will mean it will be available to all components inside of it so let's go ahead and specify our contact store in the provider's array for this app component providers and we'll give the contact store at this point we can access the store anywhere in our app so let's first remove our existing data variables quickly then we create i will also comment these out then we will create a new variable which will be observable and we can first then obviously have to include our contact store and we can assign it to the contact store selector that we created lastly let's just update our inputs to the contacts list since this is an observable we are going to use the async operator which will subscribe and unsubscribe to it automatically great so it's time to test this out now so as we can see the data appears fine and we are using the store now okay so what's left now is our app functions let's see how we can use the store for each of them first the search so as you can see we send an event back to the app component with the search term entered since we don't have the data there now we can instead send the search string to the store for that let's add the search string to the contact state so we will go in our store and we can add the search string which would be a string and then we also have to give an initial value to it so we'll give an initial value of an empty string then we can create a new selector called filtered contacts this returns the contacts but filtered with the search string so we already have that logic in our component and we'll copy it from there we copied the contact here we are going to restructure the state object here which is always a good practice and makes things clearer you're going to replace term with search string great now all we have to do when the user enters the text is to update the search string in the state and the data should be automatically updated nice isn't it now we can remove the search contacts and we can remove this reference to the event handler as well because we don't need it and we go into header component now let's change the event emitter to a normal handler called search contacts and we'll define a handler here and we'll include our contact store above and we will just call the contact store patch state method passing in the search string now component store provides multiple ways to update the state in your store there is set state but that will replace the whole state with the new value if you just need to update a part of the state patch state is a good way to do this now all we have to do is to change our contacts to refer to the filtered contacts instead and it should all work let's do that we go in app component and we're going to replace this with filtered contacts right let's test this out yeah it works and all of it we have contained in our selector instead of the component next let's see how to use the store for the add contact functionality so for add contacts we'll be adding a contact to the contacts data instead of the event let's just add a handler here as before we can then use patch state as before but let's see something different component store also provides another way to update the state that is to create an updater if you are from a redux background this is similar to a reducer basically it's a function which updates the state and exactly how that is done is a part of the store itself which means the business logic will be encapsulated there instead of our component so let's create an updater in our store called add contact we'll call it add contact this will be the updater function and it will take in the current state and our argument which would be our new contact it should then return the new state immutably that is in a different object here we'll use a spread operator to first specify the previous state and then we will define a new contacts which will have the new contact at the top of the array and then the previous list of contacts before it we just have to change the type here to resolve the typescript error then all we have to do is to call this updater in our header component let's go in our header and we'll copy in the dialog code and we'll just remove all of this include the add contact component add the dialog service as well because that's missing in our component and then we'll we're just going to simply call the updater here contact store dot add contact we're going to pass in our new contact here so you'll notice it is a lot like just calling a new function testing it out let's see we add a name to it we add a number to it and we click add yes we can add our contact now through the store now we can continue like this for the delete function as well i'm going to skip it here because you already get the idea let's jump to the completed app and see how it looks as compared to the original app so as you can see now the delete has also been added and it has some business logic to it you'll notice two things in our new app one that there are no event emitters required now since we can call the global store for any functionality as i said before as well this makes the app cleaner especially as it gets larger second you'll also notice that the components are now basically devoid of any business logic in fact components are used to do what they do best that is display the ui the business logic is now contained in our store so as you can as you see the app component it's empty there's no business logic here all of our business logic now is stored in one central location called the contact store so you have your add contact and how it's been added delete contact and how the filtered contacts are being shown what filtration is being applied on them so all of this makes it easier to change it in the future and this makes testing a lot easier as well so there you have it a simple state management solution for simple to moderate sized angular apps do try it out and give me a shout out if you enjoyed it as much as i did if you like this video do subscribe for more as i'll be covering the concept of effects in components so in a future video thanks for watching
Info
Channel: Zoaib Khan
Views: 2,617
Rating: undefined out of 5
Keywords:
Id: anjpJnn4dB4
Channel Id: undefined
Length: 13min 46sec (826 seconds)
Published: Thu Aug 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.