In this lesson, create computed properties for deriving state-based values in NgRx Signal Stores.
Computed properties allow you to encapsulate complex logic to maintain clean component architecture.
[00:00] Go back to the file which includes the definition of the signal store. And at the very end of the definition, add a call to the with computed, which is also imported from ngrx slash signals. Now the with computed will accept a callback function. The callback function will have the [00:20] state, which is injected by ngrx signal store, and this includes everything that we have built so far. And since we have called only the with state one providing the 4 properties, then the only things that we can use is basically the 4, properties which are either signals or deep signals, the [00:40] things that we have seen before. What we return from here is an object that will include a computed 1, computed 2, whatever we provide over here. Now the first computed which we are going to provide over here is simply going to be a count. So the count is going to [00:59] be the length of the items array. Now this is just going to be a plain old Angular computed imported from Angular core. And the definition is simply going to use whatever we've got within the state. So what we're interested in our case [01:20] is to consume the item signal so we can destructure the state object and basically fetch the things that are interesting to us. So what we're going to do here is return items, call the items since this is a signal, and this returns an array. And [01:39] from this array, we can simply get the length. Now having this one created, we can go back to our component and display the computer that we've created. We can already use this one here with the count, employees dot length. So here we are referencing [01:59] the variable, but we can replace it with the store dot and here comes the count. Now since this is a signal, a ridomi signal, nevertheless, a signal, we still need to just call this as if it was a function. And here we can see that the computed has [02:19] also already been read. Let's create one more computed. And this is going to be the items which are going to be filters by the value of filters dot name. Now we have the collision of the name since items has been already used somewhere over here. So what we can do is to [02:39] do a very simple refactor that items are going to be replaced with loaded items just to denote that this comes from the external API. As you can see, everything over here is type safe, so we can do refactors safely. And the items is going to be just another computed [02:59] call. And here, we will just create the function that clears whatever is going to be the expression returned. And as you can see, the object returned from the with computed just returns a pack of whatever computed we need to define. We're going to start our calculations with defining [03:19] what are the items that have been already loaded and depending on whether the name filter has been created or the salary filters has been, created or defined, we're just going to filter them out. So the first if statement is going to depend on what [03:39] is the filters dot name value. So for this reason, we also need to destructured here within the with computed. Know that all the computers that we create here, they kind of share whatever is going to be used from the definition of the state. So right here, we just need to access the [03:59] filters. And we're going to walk into the if statement only if the filters dot name is truthy. So in this case, we can also check whether the length is being positive. So it doesn't make a big difference. In this case, still, what is important is that instead of [04:19] unwrapping the entire filters deep signal, what we're going to do is to unwrap the very little thing that we need. In this case, basically, the filters dot name signal. And if this is truthy, which means that the user have created the filter's name [04:38] value, it's been defined, then we're just going to filter all the items that have been loaded. So that would be result dot filter. And now, for every employee that is available within the dataset, what we're going to do is the search name that we have created [04:58] is the filters dot name, and let's dump it into the 2 lowercase. So as you can see, this is basically plain JavaScript or plain typescript. And the thing that we return from here is that either this is the first name that included or the last name that includes it. So e [05:18] dot first name dot to lowercase includes whatever is the phrase that we are looking for, and this is the search one or, basically, the very same thing but using the last name. So here, we're just going to [05:38] replace the first name with the last name. Let's save it and let's see what we've got here. So there is a slight error with the property ID that doesn't exist or never. This is caused because from the items computed, we don't return what we should return, which is the result itself, and now everything should be [05:58] up and running. So the last thing that we need to do is actually to display the items over here, which has already been done. So let's see what would happen if we changed the value of the filters here, let's say, to make it, let's say, Bert. Let's see whether the [06:18] items get filtered, and yes, they do. And the very last thing is making use of the filters dot salary, which is going to be yet another if statement here and there, which is if filters dot salary dot from, [06:38] if there is a value like this, then what we're going to do is simply result, reassign result dot filter. And for every employee, we're interested in e dot salary being either greater or equal than filters dot [06:57] salary dot from, so the lowest possible salary, and a very similar formula. I'll just copy it. If the 2 is defined, then what we're checking here is that the e dot salary is lower than or equal than [07:17] salary dot 2. So what is important when it comes to the design is that the computed could include quite a bit of all this logic as we can see over here, but it really isn't important for the component itself because the component is just going to consume it. [07:37] So there is quite a bit of encapsulation.
Member comments are a way for members to communicate, interact, and ask questions about a lesson.
The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io
Be on-Topic
Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.
Avoid meta-discussion
Code Problems?
Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context
Details and Context
Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!