Learn how to apply the redux pattern used in NgRx and NGXS from scratch. Build a predictable state container with Angular, RxJS and Lodash https://angularfirebase.com/lessons/redux-from-scratch-angular-rxjs/

- Redux https://redux.js.org/
- RxJS http://rxjsdocs.com
2024-02-04T07:28:44.777Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
a3af0792-a357-42c7-8cef-403b1206112f
05270c734b252c974c177314df3607dada4d6badab93fbbe6f9c2e78aa42b5f5
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Why use a state management library in Angular when you can just build your own from scratch?
When you combine RxJS with Angular's dependency injection, it provides a powerful foundation for building your own state management system.
That means you can get all the benefits of the Redux pattern, including the dev tools that you see here on the right.
But you can create your own distractions and conventions to reduce the amount of boilerplate code.
Plus, you'll have a much better understanding of how your app works under the hood.
Over the next few minutes, you'll learn how to use custom RxJS and multicasting to build your own state management library.
But mostly, I just wanna show you how this pattern works at a fundamental level.
If you're new, like and subscribe and grab the source code from angular firebase.com.
In case you're not familiar with Redux pattern, here's a quick refresher.
The whole idea is that we treat our app data or state as a global mutable object.
The only way we can change the current state of the app is by dispatching an action.
So that might happen on a button click, then the payload for that action will go to a reducer function to determine what the next state should look like.
The store itself is an observable, so everything will happen in a reactive way.
So anything that subscribes to the store will be updated with the latest data.
The benefit of this is that we now have a one way data flow that provides a predictable history of all the changes that occur in the app.
So we can do time travel debugging and cool stuff like that.
If we think about this in code, our current state is equal to the stream of actions and the function that reduces them.
A reducer is just a pure function that takes in the current state and the action and then returns the next state.
So let's go ahead and build this thing.
The first thing I wanna do is generate a service called store.
And I'd also like to point out that I have Lodash installed.
Not only will it dramatically simplify our code, but it will also give us better performance then we'd be able to achieve natively.
So first, I wanna show you how our store service will be used in a component.
One really important concept in Redux is that our component should be stateless, Meaning, they should only be listening to data from the store as an observable or dispatching actions.
They shouldn't have any state of their own.
So the service will provide the store itself and then also an action class which will just give us a standardized way for creating actions.
The store can be injected in the constructor.
Then the cool thing about building your own state management library is you can make it behave however you want.
So in my case, I want to be able to grab properties with dot notation.
This differs from, say, n g r x where you'd use a callback function or a pipable operator to select your data.
Then there are 3 fundamental CRED operations that you're probably familiar with you work with NoSQL databases, the first one is set which will completely wipe out the store and set it with new values.
So if we want to reset the store, we'll dispatch a new Action called set and that will include the new data that we want to update.
But we might also want to do a non destructive update.
For that, we'll create an update action and then we'll tell our reducer to only update the properties that are contained in the data payload.
And the last one is delete which as its action payload expects an object property and then it will delete that key from the store.
Now remember, all of our data is just a global immutable object as an observable.
So if we want to view it in the UI, we can just say store dot state and then unwrap it with the async pipe.
And then we also set up a method called select which will select a specific slice of that state.
And setting up that slicing is probably the most complex thing that we'll have to do.
And then lastly, we'll set up a few buttons here just to dispatch our actions.
Then the end result from the user's perspective is just this UI with a few buttons and then when clicked, we get a full history of every state change that occurs.
So So every time we click a button, you'll notice that it changes the state in the UI and then we also have an event in the Redux Dev Tools history.
Overall, this is hugely beneficial for debugging and also a lot easier to test.
Now it's time for the fun part.
We're just here in a regular Angular service which is our store service.
I have a few imports here from RXJS and Lodash.
Then I'm creating my own custom action class just to standardize the way Actions are dispatched.
You could also make this an interface and then create a different class for each action.
That's the way it's done in n g r x.
But an action is super simple.
It's just a plain object that has a type property which is a string that defines the action that's taking place.
And then it has an optional payload that your reducer function can use to construct the next state object for the store.
Now our service class itself only has two properties.
The state itself is our immutable data as an observable, and then our actions are an RxJS subject, which would just be a stream of the action class that we just created.
To make this pattern super readable in the code, I'm going to create a custom RxJS operator that we can pipe into our action stream.
Remember, the state is 100% determined by the actions.
So we can say our state observable is equal to the actions which will convert the actions to an observable And then we can pipe in the reducer operator that we'll create here in the next step.
Rxjs has an operator called scan which will allow you to accumulate values as they're emitted through the observable.
To create a custom operator in RxJS, all you have to do is create a function that returns an existing operator such as scan.
And scan provides 2 things.
1st, the accumulated object, which would be our current state, and also the current action that was emitted through the action stream subject.
Now the only thing we have to do is write some logic to return the next state based on these 2 input objects.
Traditionally, in Redux, this is done with a switch statement where we look at the action and type and then perform some logic based on the type of action that was dispatched.
But you don't necessarily have to do it this way.
So if we have An action type of set will go ahead and set the next state as the action payload which will just overwrite everything in the state.
Then if we have an update action, we'll go ahead and use the spread syntax to merge the payload object into the current state.
That will give us a nondestructive update.
Then if we're going to delete a property, we can use the lodash omit operator.
That's a lot cleaner than trying to iterate through all the object keys on your own.
So you could pass delete either an object property or an array of properties and they would all be deleted from the state in that action.
So that's all there is to it.
We take the current state and the action and use it to compose the next state.
But we're not quite done yet.
We still need to set up a way to dispatch actions and also select a slice of the state.
Dispatching an action is super easy.
All we have to do is write a method here that takes an action as an argument and then we'll go ahead and call actions next and push that next action to the stream.
Now, when it comes to selecting data from the store, things get a little more tricky.
The first issue we'll tackle is that this observable should be shared between all subscribers.
In other words, we don't want to create a new observable every time a new subscription happens on the store.
On top of that, we wanna make sure that a new subscription always gets a value.
When you have a hot observable and it receives a new subscriber, that subscriber won't receive any data that was emitted in the past.
Well, fortunately, we can solve all these problems with one magical operator called share replay.
This will ensure that all subscribers are sharing the same source state, and it will also save the last emitted state so new subscribers will always get a value when they subscribe for the first time.
Now our last major hurdle is figuring out how to select a slice of the state or a nested object property and only listen to changes on that slice.
Once again for that, I'm going to create my own custom RX JS operator.
It takes the path as an argument which is just a string and dot notation that points to the object property that you want to observe.
And again, you don't have to make this a custom operator.
I'm doing it strictly for code readability.
It's going to take the current state observable and then map it down to a nested object property.
Lodash has a get method that makes this super easy.
So we just call git with the current state object and then the path string that we want to grab.
Then as a third argument, we'll pass the default value if it doesn't exist which can just be null.
Now, normally, this would emit the same object over and over again because this nested state is still tied to the parent observable.
But we can create a really beautiful marriage between RxJS and Lodash here.
We take the RX distinct until changed operator which will only emit unique values.
But under the hood, it's using the regular JavaScript equality operator.
That'll work for plain numbers and strings, but it won't work for any objects that get emitted through the observable.
But we can pass it the is equal function from Lodash, which does a deep comparison on object properties.
So now your sliced observable will only emit new values if the data that it's actually listening to changes.
So that's pretty amazing for a single line of code.
But now we're ready for the moment that you've all been waiting for And that's wiring up Redux Dev Tools.
If you don't have it installed yet, you can find it on the Chrome Web Store.
And it's super easy to set up Because under the hood, it's just using the same Redux pattern that we've already implemented in this app.
We can interact with it on the window object in the browser, so I'll create a variable here for the window.
Then when the service is constructed, I'll go ahead and set it up as a property on the window called DevTools, and then we can find the extension and call connect on it.
Then the only thing left to do is pass it the current action and the state, which we already have in our reducer function.
So we can simply call window DevTools Send, pass it the action type, and the next state.
And there's a bunch of ways you can customize and configure DevTools.
This is just your most basic use case.
So hopefully that gives you an idea of some of the fundamental principles behind Redux style state management libraries Phrase like ngrx and ngxs.
If this video helped you, please like and subscribe.
And if you want to learn more about stuff like this to get your Angular app in consider becoming a pro member at angularfirebase.com.
You'll get a free copy of my book as well as 1 on 1 project support.
Thanks for watching, and I'll talk to you soon.

Speaker 0: Why use a state management library in Angular when you can just build your own from scratch? When you combine RxJS with Angular's dependency injection, it provides a powerful foundation for building your own state management system. That means you can get all the benefits of the Redux pattern, including the dev tools that you see here on the right. But you can create your own distractions and conventions to reduce the amount of boilerplate code. Plus, you'll have a much better understanding of how your app works under the hood.

Over the next few minutes, you'll learn how to use custom RxJS and multicasting to build your own state management library. But mostly, I just wanna show you how this pattern works at a fundamental level. If you're new, like and subscribe and grab the source code from angular firebase.com. In case you're not familiar with Redux pattern, here's a quick refresher. The whole idea is that we treat our app data or state as a global mutable object.

The only way we can change the current state of the app is by dispatching an action. So that might happen on a button click, then the payload for that action will go to a reducer function to determine what the next state should look like. The store itself is an observable, so everything will happen in a reactive way. So anything that subscribes to the store will be updated with the latest data. The benefit of this is that we now have a one way data flow that provides a predictable history of all the changes that occur in the app.

So we can do time travel debugging and cool stuff like that. If we think about this in code, our current state is equal to the stream of actions and the function that reduces them. A reducer is just a pure function that takes in the current state and the action and then returns the next state. So let's go ahead and build this thing. The first thing I wanna do is generate a service called store.

And I'd also like to point out that I have Lodash installed. Not only will it dramatically simplify our code, but it will also give us better performance then we'd be able to achieve natively. So first, I wanna show you how our store service will be used in a component. One really important concept in Redux is that our component should be stateless, Meaning, they should only be listening to data from the store as an observable or dispatching actions. They shouldn't have any state of their own.

So the service will provide the store itself and then also an action class which will just give us a standardized way for creating actions. The store can be injected in the constructor. Then the cool thing about building your own state management library is you can make it behave however you want. So in my case, I want to be able to grab properties with dot notation. This differs from, say, n g r x where you'd use a callback function or a pipable operator to select your data.

Then there are 3 fundamental CRED operations that you're probably familiar with you work with NoSQL databases, the first one is set which will completely wipe out the store and set it with new values. So if we want to reset the store, we'll dispatch a new Action called set and that will include the new data that we want to update. But we might also want to do a non destructive update. For that, we'll create an update action and then we'll tell our reducer to only update the properties that are contained in the data payload. And the last one is delete which as its action payload expects an object property and then it will delete that key from the store.

Now remember, all of our data is just a global immutable object as an observable. So if we want to view it in the UI, we can just say store dot state and then unwrap it with the async pipe. And then we also set up a method called select which will select a specific slice of that state. And setting up that slicing is probably the most complex thing that we'll have to do. And then lastly, we'll set up a few buttons here just to dispatch our actions.

Then the end result from the user's perspective is just this UI with a few buttons and then when clicked, we get a full history of every state change that occurs. So So every time we click a button, you'll notice that it changes the state in the UI and then we also have an event in the Redux Dev Tools history. Overall, this is hugely beneficial for debugging and also a lot easier to test. Now it's time for the fun part. We're just here in a regular Angular service which is our store service.

I have a few imports here from RXJS and Lodash. Then I'm creating my own custom action class just to standardize the way Actions are dispatched. You could also make this an interface and then create a different class for each action. That's the way it's done in n g r x. But an action is super simple.

It's just a plain object that has a type property which is a string that defines the action that's taking place. And then it has an optional payload that your reducer function can use to construct the next state object for the store. Now our service class itself only has two properties. The state itself is our immutable data as an observable, and then our actions are an RxJS subject, which would just be a stream of the action class that we just created. To make this pattern super readable in the code, I'm going to create a custom RxJS operator that we can pipe into our action stream.

Remember, the state is 100% determined by the actions. So we can say our state observable is equal to the actions which will convert the actions to an observable And then we can pipe in the reducer operator that we'll create here in the next step. Rxjs has an operator called scan which will allow you to accumulate values as they're emitted through the observable. To create a custom operator in RxJS, all you have to do is create a function that returns an existing operator such as scan. And scan provides 2 things.

1st, the accumulated object, which would be our current state, and also the current action that was emitted through the action stream subject. Now the only thing we have to do is write some logic to return the next state based on these 2 input objects. Traditionally, in Redux, this is done with a switch statement where we look at the action and type and then perform some logic based on the type of action that was dispatched. But you don't necessarily have to do it this way. So if we have An action type of set will go ahead and set the next state as the action payload which will just overwrite everything in the state.

Then if we have an update action, we'll go ahead and use the spread syntax to merge the payload object into the current state. That will give us a nondestructive update. Then if we're going to delete a property, we can use the lodash omit operator. That's a lot cleaner than trying to iterate through all the object keys on your own. So you could pass delete either an object property or an array of properties and they would all be deleted from the state in that action.

So that's all there is to it. We take the current state and the action and use it to compose the next state. But we're not quite done yet. We still need to set up a way to dispatch actions and also select a slice of the state. Dispatching an action is super easy.

All we have to do is write a method here that takes an action as an argument and then we'll go ahead and call actions next and push that next action to the stream. Now, when it comes to selecting data from the store, things get a little more tricky. The first issue we'll tackle is that this observable should be shared between all subscribers. In other words, we don't want to create a new observable every time a new subscription happens on the store. On top of that, we wanna make sure that a new subscription always gets a value.

When you have a hot observable and it receives a new subscriber, that subscriber won't receive any data that was emitted in the past. Well, fortunately, we can solve all these problems with one magical operator called share replay. This will ensure that all subscribers are sharing the same source state, and it will also save the last emitted state so new subscribers will always get a value when they subscribe for the first time. Now our last major hurdle is figuring out how to select a slice of the state or a nested object property and only listen to changes on that slice. Once again for that, I'm going to create my own custom RX JS operator.

It takes the path as an argument which is just a string and dot notation that points to the object property that you want to observe. And again, you don't have to make this a custom operator. I'm doing it strictly for code readability. It's going to take the current state observable and then map it down to a nested object property. Lodash has a get method that makes this super easy.

So we just call git with the current state object and then the path string that we want to grab. Then as a third argument, we'll pass the default value if it doesn't exist which can just be null. Now, normally, this would emit the same object over and over again because this nested state is still tied to the parent observable. But we can create a really beautiful marriage between RxJS and Lodash here. We take the RX distinct until changed operator which will only emit unique values.

But under the hood, it's using the regular JavaScript equality operator. That'll work for plain numbers and strings, but it won't work for any objects that get emitted through the observable. But we can pass it the is equal function from Lodash, which does a deep comparison on object properties. So now your sliced observable will only emit new values if the data that it's actually listening to changes. So that's pretty amazing for a single line of code.

But now we're ready for the moment that you've all been waiting for And that's wiring up Redux Dev Tools. If you don't have it installed yet, you can find it on the Chrome Web Store. And it's super easy to set up Because under the hood, it's just using the same Redux pattern that we've already implemented in this app. We can interact with it on the window object in the browser, so I'll create a variable here for the window. Then when the service is constructed, I'll go ahead and set it up as a property on the window called DevTools, and then we can find the extension and call connect on it.

Then the only thing left to do is pass it the current action and the state, which we already have in our reducer function. So we can simply call window DevTools Send, pass it the action type, and the next state. And there's a bunch of ways you can customize and configure DevTools. This is just your most basic use case. So hopefully that gives you an idea of some of the fundamental principles behind Redux style state management libraries Phrase like ngrx and ngxs.

If this video helped you, please like and subscribe. And if you want to learn more about stuff like this to get your Angular app in consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project support. Thanks for watching, and I'll talk to you soon.
Why use a state management library in Angular when you can just build your own from scratch? When you combine RxJS with Angular's dependency injection, it provides a powerful foundation for building your own state management system.
That means you can get all the benefits of the Redux pattern, including the dev tools that you see here on the right. But you can create your own distractions and conventions to reduce the amount of boilerplate code. Plus, you'll have a much better understanding of how your app works under the hood. Over the next few minutes, you'll learn how to use custom RxJS and multicasting to build your own state management library. But mostly, I just wanna show you how this pattern works at a fundamental level.
software
software development
programming
If you're new, like and subscribe and grab the source code from angular firebase.com.
In case you're not familiar with Redux pattern, here's a quick refresher. The whole idea is that we treat our app data or state as a global mutable object. The only way we can change the current state of the app is by dispatching an action. So that might happen on a button click, then the payload for that action will go to a reducer function to determine what the next state should look like.
systems
The store itself is an observable, so everything will happen in a reactive way. So anything that subscribes to the store will be updated with the latest data. The benefit of this is that we now have a one way data flow that provides a predictable history of all the changes that occur in the app. So we can do time travel debugging and cool stuff like that. If we think about this in code, our current state is equal to the stream of actions and the function that reduces them.
data management
commerce
sales
data
A reducer is just a pure function that takes in the current state and the action and then returns the next state. So let's go ahead and build this thing.
The first thing I wanna do is generate a service called store. And I'd also like to point out that I have Lodash installed. Not only will it dramatically simplify our code, but it will also give us better performance then we'd be able to achieve natively. So first, I wanna show you how our store service will be used in a component. One really important concept in Redux is that our component should be stateless, Meaning, they should only be listening to data from the store as an observable or dispatching actions. They shouldn't have any state of their own.
customer support
infrastructure
systems
commerce
So the service will provide the store itself and then also an action class which will just give us a standardized way for creating actions.
The store can be injected in the constructor. Then the cool thing about building your own state management library is you can make it behave however you want. So in my case, I want to be able to grab properties with dot notation. This differs from, say, n g r x where you'd use a callback function or a pipable operator to select your data. Then there are 3 fundamental CRED operations that you're probably familiar with you work with NoSQL databases, the first one is set which will completely wipe out the store and set it with new values. So if we want to reset the store, we'll dispatch a new Action called set and that will include the new data that we want to update. But we might also want to do a non destructive update. For that, we'll create an update action and then we'll tell our reducer to only update the properties that are contained in the data payload.
databases
programming
data management
home improvement
data
And the last one is delete which as its action payload expects an object property and then it will delete that key from the store.
Now remember, all of our data is just a global immutable object as an observable. So if we want to view it in the UI, we can just say store dot state and then unwrap it with the async pipe. And then we also set up a method called select which will select a specific slice of that state.
programming
And setting up that slicing is probably the most complex thing that we'll have to do. And then lastly, we'll set up a few buttons here just to dispatch our actions. Then the end result from the user's perspective is just this UI with a few buttons and then when clicked, we get a full history of every state change that occurs. So So every time we click a button, you'll notice that it changes the state in the UI and then we also have an event in the Redux Dev Tools history. Overall, this is hugely beneficial for debugging and also a lot easier to test. Now it's time for the fun part. We're just here in a regular Angular service which is our store service. I have a few imports here from RXJS and Lodash. Then I'm creating my own custom action class just to standardize the way Actions are dispatched.
You could also make this an interface and then create a different class for each action. That's the way it's done in n g r x. But an action is super simple. It's just a plain object that has a type property which is a string that defines the action that's taking place.
programming
And then it has an optional payload that your reducer function can use to construct the next state object for the store. Now our service class itself only has two properties.
The state itself is our immutable data as an observable, and then our actions are an RxJS subject, which would just be a stream of the action class that we just created. To make this pattern super readable in the code, I'm going to create a custom RxJS operator that we can pipe into our action stream. Remember, the state is 100% determined by the actions. So we can say our state observable is equal to the actions which will convert the actions to an observable And then we can pipe in the reducer operator that we'll create here in the next step. Rxjs has an operator called scan which will allow you to accumulate values as they're emitted through the observable. To create a custom operator in RxJS, all you have to do is create a function that returns an existing operator such as scan. And scan provides 2 things. 1st, the accumulated object, which would be our current state, and also the current action that was emitted through the action stream subject. Now the only thing we have to do is write some logic to return the next state based on these 2 input objects. Traditionally, in Redux, this is done with a switch statement where we look at the action and type and then perform some logic based on the type of action that was dispatched. But you don't necessarily have to do it this way. So if we have An action type of set will go ahead and set the next state as the action payload which will just overwrite everything in the state. Then if we have an update action, we'll go ahead and use the spread syntax to merge the payload object into the current state.
logic
operations
policy
programming
systems
logical reasoning
That will give us a nondestructive update. Then if we're going to delete a property, we can use the lodash omit operator. That's a lot cleaner than trying to iterate through all the object keys on your own. So you could pass delete either an object property or an array of properties and they would all be deleted from the state in that action. So that's all there is to it. We take the current state and the action and use it to compose the next state. But we're not quite done yet. We still need to set up a way to dispatch actions and also select a slice of the state. Dispatching an action is super easy.
All we have to do is write a method here that takes an action as an argument and then we'll go ahead and call actions next and push that next action to the stream. Now, when it comes to selecting data from the store, things get a little more tricky. The first issue we'll tackle is that this observable should be shared between all subscribers. In other words, we don't want to create a new observable every time a new subscription happens on the store.
customers
purchasing
operations
commerce
programming
On top of that, we wanna make sure that a new subscription always gets a value. When you have a hot observable and it receives a new subscriber, that subscriber won't receive any data that was emitted in the past. Well, fortunately, we can solve all these problems with one magical operator called share replay. This will ensure that all subscribers are sharing the same source state, and it will also save the last emitted state so new subscribers will always get a value when they subscribe for the first time. Now our last major hurdle is figuring out how to select a slice of the state or a nested object property and only listen to changes on that slice. Once again for that, I'm going to create my own custom RX JS operator. It takes the path as an argument which is just a string and dot notation that points to the object property that you want to observe.
And again, you don't have to make this a custom operator. I'm doing it strictly for code readability. It's going to take the current state observable and then map it down to a nested object property. Lodash has a get method that makes this super easy. So we just call git with the current state object and then the path string that we want to grab.
programming
Then as a third argument, we'll pass the default value if it doesn't exist which can just be null. Now, normally, this would emit the same object over and over again because this nested state is still tied to the parent observable. But we can create a really beautiful marriage between RxJS and Lodash here. We take the RX distinct until changed operator which will only emit unique values. But under the hood, it's using the regular JavaScript equality operator. That'll work for plain numbers and strings, but it won't work for any objects that get emitted through the observable. But we can pass it the is equal function from Lodash, which does a deep comparison on object properties. So now your sliced observable will only emit new values if the data that it's actually listening to changes.
So that's pretty amazing for a single line of code. But now we're ready for the moment that you've all been waiting for And that's wiring up Redux Dev Tools. If you don't have it installed yet, you can find it on the Chrome Web Store. And it's super easy to set up Because under the hood, it's just using the same Redux pattern that we've already implemented in this app. We can interact with it on the window object in the browser, so I'll create a variable here for the window.
software
Then when the service is constructed, I'll go ahead and set it up as a property on the window called DevTools, and then we can find the extension and call connect on it. Then the only thing left to do is pass it the current action and the state, which we already have in our reducer function. So we can simply call window DevTools Send, pass it the action type, and the next state.
And there's a bunch of ways you can customize and configure DevTools. This is just your most basic use case. So hopefully that gives you an idea of some of the fundamental principles behind Redux style state management libraries Phrase like ngrx and ngxs. If this video helped you, please like and subscribe. And if you want to learn more about stuff like this to get your Angular app in consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project support. Thanks for watching, and I'll talk to you soon.
books
software
software development
literature
publishing
youtube
reading
Why use a state management library in Angular when you can just build your own from scratch? When you combine RxJS with Angular's dependency injection, it provides a powerful foundation for building your own state management system. That means you can get all the benefits of the Redux pattern, including the dev tools that you see here on the right. But you can create your own distractions and conventions to reduce the amount of boilerplate code. Plus, you'll have a much better understanding of how your app works under the hood. Over the next few minutes, you'll learn how to use custom RxJS and multicasting to build your own state management library. But mostly, I just wanna show you how this pattern works at a fundamental level. If you're new, like and subscribe and grab the source code from angular firebase.com. In case you're not familiar with Redux pattern, here's a quick refresher. The whole idea is that we treat our app data or state as a global mutable object. The only way we can change the current state of the app is by dispatching an action. So that might happen on a button click, then the payload for that action will go to a reducer function to determine what the next state should look like. The store itself is an observable, so everything will happen in a reactive way. So anything that subscribes to the store will be updated with the latest data. The benefit of this is that we now have a one way data flow that provides a predictable history of all the changes that occur in the app. So we can do time travel debugging and cool stuff like that. If we think about this in code, our current state is equal to the stream of actions and the function that reduces them. A reducer is just a pure function that takes in the current state and the action and then returns the next state. So let's go ahead and build this thing. The first thing I wanna do is generate a service called store. And I'd also like to point out that I have Lodash installed. Not only will it dramatically simplify our code, but it will also give us better performance then we'd be able to achieve natively. So first, I wanna show you how our store service will be used in a component. One really important concept in Redux is that our component should be stateless, Meaning, they should only be listening to data from the store as an observable or dispatching actions. They shouldn't have any state of their own. So the service will provide the store itself and then also an action class which will just give us a standardized way for creating actions. The store can be injected in the constructor. Then the cool thing about building your own state management library is you can make it behave however you want. So in my case, I want to be able to grab properties with dot notation. This differs from, say, n g r x where you'd use a callback function or a pipable operator to select your data. Then there are 3 fundamental CRED operations that you're probably familiar with you work with NoSQL databases, the first one is set which will completely wipe out the store and set it with new values. So if we want to reset the store, we'll dispatch a new Action called set and that will include the new data that we want to update. But we might also want to do a non destructive update. For that, we'll create an update action and then we'll tell our reducer to only update the properties that are contained in the data payload. And the last one is delete which as its action payload expects an object property and then it will delete that key from the store. Now remember, all of our data is just a global immutable object as an observable. So if we want to view it in the UI, we can just say store dot state and then unwrap it with the async pipe. And then we also set up a method called select which will select a specific slice of that state. And setting up that slicing is probably the most complex thing that we'll have to do. And then lastly, we'll set up a few buttons here just to dispatch our actions. Then the end result from the user's perspective is just this UI with a few buttons and then when clicked, we get a full history of every state change that occurs. So So every time we click a button, you'll notice that it changes the state in the UI and then we also have an event in the Redux Dev Tools history. Overall, this is hugely beneficial for debugging and also a lot easier to test. Now it's time for the fun part. We're just here in a regular Angular service which is our store service. I have a few imports here from RXJS and Lodash. Then I'm creating my own custom action class just to standardize the way Actions are dispatched. You could also make this an interface and then create a different class for each action. That's the way it's done in n g r x. But an action is super simple. It's just a plain object that has a type property which is a string that defines the action that's taking place. And then it has an optional payload that your reducer function can use to construct the next state object for the store. Now our service class itself only has two properties. The state itself is our immutable data as an observable, and then our actions are an RxJS subject, which would just be a stream of the action class that we just created. To make this pattern super readable in the code, I'm going to create a custom RxJS operator that we can pipe into our action stream. Remember, the state is 100% determined by the actions. So we can say our state observable is equal to the actions which will convert the actions to an observable And then we can pipe in the reducer operator that we'll create here in the next step. Rxjs has an operator called scan which will allow you to accumulate values as they're emitted through the observable. To create a custom operator in RxJS, all you have to do is create a function that returns an existing operator such as scan. And scan provides 2 things. 1st, the accumulated object, which would be our current state, and also the current action that was emitted through the action stream subject. Now the only thing we have to do is write some logic to return the next state based on these 2 input objects. Traditionally, in Redux, this is done with a switch statement where we look at the action and type and then perform some logic based on the type of action that was dispatched. But you don't necessarily have to do it this way. So if we have An action type of set will go ahead and set the next state as the action payload which will just overwrite everything in the state. Then if we have an update action, we'll go ahead and use the spread syntax to merge the payload object into the current state. That will give us a nondestructive update. Then if we're going to delete a property, we can use the lodash omit operator. That's a lot cleaner than trying to iterate through all the object keys on your own. So you could pass delete either an object property or an array of properties and they would all be deleted from the state in that action. So that's all there is to it. We take the current state and the action and use it to compose the next state. But we're not quite done yet. We still need to set up a way to dispatch actions and also select a slice of the state. Dispatching an action is super easy. All we have to do is write a method here that takes an action as an argument and then we'll go ahead and call actions next and push that next action to the stream. Now, when it comes to selecting data from the store, things get a little more tricky. The first issue we'll tackle is that this observable should be shared between all subscribers. In other words, we don't want to create a new observable every time a new subscription happens on the store. On top of that, we wanna make sure that a new subscription always gets a value. When you have a hot observable and it receives a new subscriber, that subscriber won't receive any data that was emitted in the past. Well, fortunately, we can solve all these problems with one magical operator called share replay. This will ensure that all subscribers are sharing the same source state, and it will also save the last emitted state so new subscribers will always get a value when they subscribe for the first time. Now our last major hurdle is figuring out how to select a slice of the state or a nested object property and only listen to changes on that slice. Once again for that, I'm going to create my own custom RX JS operator. It takes the path as an argument which is just a string and dot notation that points to the object property that you want to observe. And again, you don't have to make this a custom operator. I'm doing it strictly for code readability. It's going to take the current state observable and then map it down to a nested object property. Lodash has a get method that makes this super easy. So we just call git with the current state object and then the path string that we want to grab. Then as a third argument, we'll pass the default value if it doesn't exist which can just be null. Now, normally, this would emit the same object over and over again because this nested state is still tied to the parent observable. But we can create a really beautiful marriage between RxJS and Lodash here. We take the RX distinct until changed operator which will only emit unique values. But under the hood, it's using the regular JavaScript equality operator. That'll work for plain numbers and strings, but it won't work for any objects that get emitted through the observable. But we can pass it the is equal function from Lodash, which does a deep comparison on object properties. So now your sliced observable will only emit new values if the data that it's actually listening to changes. So that's pretty amazing for a single line of code. But now we're ready for the moment that you've all been waiting for And that's wiring up Redux Dev Tools. If you don't have it installed yet, you can find it on the Chrome Web Store. And it's super easy to set up Because under the hood, it's just using the same Redux pattern that we've already implemented in this app. We can interact with it on the window object in the browser, so I'll create a variable here for the window. Then when the service is constructed, I'll go ahead and set it up as a property on the window called DevTools, and then we can find the extension and call connect on it. Then the only thing left to do is pass it the current action and the state, which we already have in our reducer function. So we can simply call window DevTools Send, pass it the action type, and the next state. And there's a bunch of ways you can customize and configure DevTools. This is just your most basic use case. So hopefully that gives you an idea of some of the fundamental principles behind Redux style state management libraries Phrase like ngrx and ngxs. If this video helped you, please like and subscribe. And if you want to learn more about stuff like this to get your Angular app in consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project support. Thanks for watching, and I'll talk to you soon.
Why
why
use
use
a
a
state
state
management
management
library
library
in
in
Angular
angular
when
when
you
you
can
can
just
just
build
build
your
your
own
own
from
from
scratch?
scratch
When
when
you
you
combine
combine
RxJS
rxjs
with
with
Angular's
angular's
dependency
dependency
injection,
injection
it
it
provides
provides
a
a
powerful
powerful
foundation
foundation
for
for
building
building
your
your
own
own
state
state
management
management
system.
system
That
that
means
means
you
you
can
can
get
get
all
all
the
the
benefits
benefits
of
of
the
the
Redux
redux
pattern,
pattern
including
including
the
the
dev
dev
tools
tools
that
that
you
you
see
see
here
here
on
on
the
the
right.
right
But
but
you
you
can
can
create
create
your
your
own
own
distractions
distractions
and
and
conventions
conventions
to
to
reduce
reduce
the
the
amount
amount
of
of
boilerplate
boilerplate
code.
code
Plus,
plus
you'll
you'll
have
have
a
a
much
much
better
better
understanding
understanding
of
of
how
how
your
your
app
app
works
works
under
under
the
the
hood.
hood
Over
over
the
the
next
next
few
few
minutes,
minutes
you'll
you'll
learn
learn
how
how
to
to
use
use
custom
custom
RxJS
rxjs
and
and
multicasting
multicasting
to
to
build
build
your
your
own
own
state
state
management
management
library.
library
But
but
mostly,
mostly
I
i
just
just
wanna
wanna
show
show
you
you
how
how
this
this
pattern
pattern
works
works
at
at
a
a
fundamental
fundamental
level.
level
If
if
you're
you're
new,
new
like
like
and
and
subscribe
subscribe
and
and
grab
grab
the
the
source
source
code
code
from
from
angular
angular
firebase.com.
firebase.com
In
in
case
case
you're
you're
not
not
familiar
familiar
with
with
Redux
redux
pattern,
pattern
here's
here's
a
a
quick
quick
refresher.
refresher
The
the
whole
whole
idea
idea
is
is
that
that
we
we
treat
treat
our
our
app
app
data
data
or
or
state
state
as
as
a
a
global
global
mutable
mutable
object.
object
The
the
only
only
way
way
we
we
can
can
change
change
the
the
current
current
state
state
of
of
the
the
app
app
is
is
by
by
dispatching
dispatching
an
an
action.
action
So
so
that
that
might
might
happen
happen
on
on
a
a
button
button
click,
click
then
then
the
the
payload
payload
for
for
that
that
action
action
will
will
go
go
to
to
a
a
reducer
reducer
function
function
to
to
determine
determine
what
what
the
the
next
next
state
state
should
should
look
look
like.
like
The
the
store
store
itself
itself
is
is
an
an
observable,
observable
so
so
everything
everything
will
will
happen
happen
in
in
a
a
reactive
reactive
way.
way
So
so
anything
anything
that
that
subscribes
subscribes
to
to
the
the
store
store
will
will
be
be
updated
updated
with
with
the
the
latest
latest
data.
data
The
the
benefit
benefit
of
of
this
this
is
is
that
that
we
we
now
now
have
have
a
a
one
one
way
way
data
data
flow
flow
that
that
provides
provides
a
a
predictable
predictable
history
history
of
of
all
all
the
the
changes
changes
that
that
occur
occur
in
in
the
the
app.
app
So
so
we
we
can
can
do
do
time
time
travel
travel
debugging
debugging
and
and
cool
cool
stuff
stuff
like
like
that.
that
If
if
we
we
think
think
about
about
this
this
in
in
code,
code
our
our
current
current
state
state
is
is
equal
equal
to
to
the
the
stream
stream
of
of
actions
actions
and
and
the
the
function
function
that
that
reduces
reduces
them.
them
A
a
reducer
reducer
is
is
just
just
a
a
pure
pure
function
function
that
that
takes
takes
in
in
the
the
current
current
state
state
and
and
the
the
action
action
and
and
then
then
returns
returns
the
the
next
next
state.
state
So
so
let's
let's
go
go
ahead
ahead
and
and
build
build
this
this
thing.
thing
The
the
first
first
thing
thing
I
i
wanna
wanna
do
do
is
is
generate
generate
a
a
service
service
called
called
store.
store
And
and
I'd
i'd
also
also
like
like
to
to
point
point
out
out
that
that
I
i
have
have
Lodash
lodash
installed.
installed
Not
not
only
only
will
will
it
it
dramatically
dramatically
simplify
simplify
our
our
code,
code
but
but
it
it
will
will
also
also
give
give
us
us
better
better
performance
performance
then
then
we'd
we'd
be
be
able
able
to
to
achieve
achieve
natively.
natively
So
so
first,
first
I
i
wanna
wanna
show
show
you
you
how
how
our
our
store
store
service
service
will
will
be
be
used
used
in
in
a
a
component.
component
One
one
really
really
important
important
concept
concept
in
in
Redux
redux
is
is
that
that
our
our
component
component
should
should
be
be
stateless,
stateless
Meaning,
meaning
they
they
should
should
only
only
be
be
listening
listening
to
to
data
data
from
from
the
the
store
store
as
as
an
an
observable
observable
or
or
dispatching
dispatching
actions.
actions
They
they
shouldn't
shouldn't
have
have
any
any
state
state
of
of
their
their
own.
own
So
so
the
the
service
service
will
will
provide
provide
the
the
store
store
itself
itself
and
and
then
then
also
also
an
an
action
action
class
class
which
which
will
will
just
just
give
give
us
us
a
a
standardized
standardized
way
way
for
for
creating
creating
actions.
actions
The
the
store
store
can
can
be
be
injected
injected
in
in
the
the
constructor.
constructor
Then
then
the
the
cool
cool
thing
thing
about
about
building
building
your
your
own
own
state
state
management
management
library
library
is
is
you
you
can
can
make
make
it
it
behave
behave
however
however
you
you
want.
want
So
so
in
in
my
my
case,
case
I
i
want
want
to
to
be
be
able
able
to
to
grab
grab
properties
properties
with
with
dot
dot
notation.
notation
This
this
differs
differs
from,
from
say,
say
n
n
g
g
r
r
x
x
where
where
you'd
you'd
use
use
a
a
callback
callback
function
function
or
or
a
a
pipable
pipable
operator
operator
to
to
select
select
your
your
data.
data
Then
then
there
there
are
are
3
3
fundamental
fundamental
CRED
cred
operations
operations
that
that
you're
you're
probably
probably
familiar
familiar
with
with
you
you
work
work
with
with
NoSQL
nosql
databases,
databases
the
the
first
first
one
one
is
is
set
set
which
which
will
will
completely
completely
wipe
wipe
out
out
the
the
store
store
and
and
set
set
it
it
with
with
new
new
values.
values
So
so
if
if
we
we
want
want
to
to
reset
reset
the
the
store,
store
we'll
we'll
dispatch
dispatch
a
a
new
new
Action
action
called
called
set
set
and
and
that
that
will
will
include
include
the
the
new
new
data
data
that
that
we
we
want
want
to
to
update.
update
But
but
we
we
might
might
also
also
want
want
to
to
do
do
a
a
non
non
destructive
destructive
update.
update
For
for
that,
that
we'll
we'll
create
create
an
an
update
update
action
action
and
and
then
then
we'll
we'll
tell
tell
our
our
reducer
reducer
to
to
only
only
update
update
the
the
properties
properties
that
that
are
are
contained
contained
in
in
the
the
data
data
payload.
payload
And
and
the
the
last
last
one
one
is
is
delete
delete
which
which
as
as
its
its
action
action
payload
payload
expects
expects
an
an
object
object
property
property
and
and
then
then
it
it
will
will
delete
delete
that
that
key
key
from
from
the
the
store.
store
Now
now
remember,
remember
all
all
of
of
our
our
data
data
is
is
just
just
a
a
global
global
immutable
immutable
object
object
as
as
an
an
observable.
observable
So
so
if
if
we
we
want
want
to
to
view
view
it
it
in
in
the
the
UI,
ui
we
we
can
can
just
just
say
say
store
store
dot
dot
state
state
and
and
then
then
unwrap
unwrap
it
it
with
with
the
the
async
async
pipe.
pipe
And
and
then
then
we
we
also
also
set
set
up
up
a
a
method
method
called
called
select
select
which
which
will
will
select
select
a
a
specific
specific
slice
slice
of
of
that
that
state.
state
And
and
setting
setting
up
up
that
that
slicing
slicing
is
is
probably
probably
the
the
most
most
complex
complex
thing
thing
that
that
we'll
we'll
have
have
to
to
do.
do
And
and
then
then
lastly,
lastly
we'll
we'll
set
set
up
up
a
a
few
few
buttons
buttons
here
here
just
just
to
to
dispatch
dispatch
our
our
actions.
actions
Then
then
the
the
end
end
result
result
from
from
the
the
user's
user's
perspective
perspective
is
is
just
just
this
this
UI
ui
with
with
a
a
few
few
buttons
buttons
and
and
then
then
when
when
clicked,
clicked
we
we
get
get
a
a
full
full
history
history
of
of
every
every
state
state
change
change
that
that
occurs.
occurs
So
so
So
so
every
every
time
time
we
we
click
click
a
a
button,
button
you'll
you'll
notice
notice
that
that
it
it
changes
changes
the
the
state
state
in
in
the
the
UI
ui
and
and
then
then
we
we
also
also
have
have
an
an
event
event
in
in
the
the
Redux
redux
Dev
dev
Tools
tools
history.
history
Overall,
overall
this
this
is
is
hugely
hugely
beneficial
beneficial
for
for
debugging
debugging
and
and
also
also
a
a
lot
lot
easier
easier
to
to
test.
test
Now
now
it's
it's
time
time
for
for
the
the
fun
fun
part.
part
We're
we're
just
just
here
here
in
in
a
a
regular
regular
Angular
angular
service
service
which
which
is
is
our
our
store
store
service.
service
I
i
have
have
a
a
few
few
imports
imports
here
here
from
from
RXJS
rxjs
and
and
Lodash.
lodash
Then
then
I'm
i'm
creating
creating
my
my
own
own
custom
custom
action
action
class
class
just
just
to
to
standardize
standardize
the
the
way
way
Actions
actions
are
are
dispatched.
dispatched
You
you
could
could
also
also
make
make
this
this
an
an
interface
interface
and
and
then
then
create
create
a
a
different
different
class
class
for
for
each
each
action.
action
That's
that's
the
the
way
way
it's
it's
done
done
in
in
n
n
g
g
r
r
x.
x
But
but
an
an
action
action
is
is
super
super
simple.
simple
It's
it's
just
just
a
a
plain
plain
object
object
that
that
has
has
a
a
type
type
property
property
which
which
is
is
a
a
string
string
that
that
defines
defines
the
the
action
action
that's
that's
taking
taking
place.
place
And
and
then
then
it
it
has
has
an
an
optional
optional
payload
payload
that
that
your
your
reducer
reducer
function
function
can
can
use
use
to
to
construct
construct
the
the
next
next
state
state
object
object
for
for
the
the
store.
store
Now
now
our
our
service
service
class
class
itself
itself
only
only
has
has
two
two
properties.
properties
The
the
state
state
itself
itself
is
is
our
our
immutable
immutable
data
data
as
as
an
an
observable,
observable
and
and
then
then
our
our
actions
actions
are
are
an
an
RxJS
rxjs
subject,
subject
which
which
would
would
just
just
be
be
a
a
stream
stream
of
of
the
the
action
action
class
class
that
that
we
we
just
just
created.
created
To
to
make
make
this
this
pattern
pattern
super
super
readable
readable
in
in
the
the
code,
code
I'm
i'm
going
going
to
to
create
create
a
a
custom
custom
RxJS
rxjs
operator
operator
that
that
we
we
can
can
pipe
pipe
into
into
our
our
action
action
stream.
stream
Remember,
remember
the
the
state
state
is
is
100%
100%
determined
determined
by
by
the
the
actions.
actions
So
so
we
we
can
can
say
say
our
our
state
state
observable
observable
is
is
equal
equal
to
to
the
the
actions
actions
which
which
will
will
convert
convert
the
the
actions
actions
to
to
an
an
observable
observable
And
and
then
then
we
we
can
can
pipe
pipe
in
in
the
the
reducer
reducer
operator
operator
that
that
we'll
we'll
create
create
here
here
in
in
the
the
next
next
step.
step
Rxjs
rxjs
has
has
an
an
operator
operator
called
called
scan
scan
which
which
will
will
allow
allow
you
you
to
to
accumulate
accumulate
values
values
as
as
they're
they're
emitted
emitted
through
through
the
the
observable.
observable
To
to
create
create
a
a
custom
custom
operator
operator
in
in
RxJS,
rxjs
all
all
you
you
have
have
to
to
do
do
is
is
create
create
a
a
function
function
that
that
returns
returns
an
an
existing
existing
operator
operator
such
such
as
as
scan.
scan
And
and
scan
scan
provides
provides
2
2
things.
things
1st,
1st
the
the
accumulated
accumulated
object,
object
which
which
would
would
be
be
our
our
current
current
state,
state
and
and
also
also
the
the
current
current
action
action
that
that
was
was
emitted
emitted
through
through
the
the
action
action
stream
stream
subject.
subject
Now
now
the
the
only
only
thing
thing
we
we
have
have
to
to
do
do
is
is
write
write
some
some
logic
logic
to
to
return
return
the
the
next
next
state
state
based
based
on
on
these
these
2
2
input
input
objects.
objects
Traditionally,
traditionally
in
in
Redux,
redux
this
this
is
is
done
done
with
with
a
a
switch
switch
statement
statement
where
where
we
we
look
look
at
at
the
the
action
action
and
and
type
type
and
and
then
then
perform
perform
some
some
logic
logic
based
based
on
on
the
the
type
type
of
of
action
action
that
that
was
was
dispatched.
dispatched
But
but
you
you
don't
don't
necessarily
necessarily
have
have
to
to
do
do
it
it
this
this
way.
way
So
so
if
if
we
we
have
have
An
an
action
action
type
type
of
of
set
set
will
will
go
go
ahead
ahead
and
and
set
set
the
the
next
next
state
state
as
as
the
the
action
action
payload
payload
which
which
will
will
just
just
overwrite
overwrite
everything
everything
in
in
the
the
state.
state
Then
then
if
if
we
we
have
have
an
an
update
update
action,
action
we'll
we'll
go
go
ahead
ahead
and
and
use
use
the
the
spread
spread
syntax
syntax
to
to
merge
merge
the
the
payload
payload
object
object
into
into
the
the
current
current
state.
state
That
that
will
will
give
give
us
us
a
a
nondestructive
nondestructive
update.
update
Then
then
if
if
we're
we're
going
going
to
to
delete
delete
a
a
property,
property
we
we
can
can
use
use
the
the
lodash
lodash
omit
omit
operator.
operator
That's
that's
a
a
lot
lot
cleaner
cleaner
than
than
trying
trying
to
to
iterate
iterate
through
through
all
all
the
the
object
object
keys
keys
on
on
your
your
own.
own
So
so
you
you
could
could
pass
pass
delete
delete
either
either
an
an
object
object
property
property
or
or
an
an
array
array
of
of
properties
properties
and
and
they
they
would
would
all
all
be
be
deleted
deleted
from
from
the
the
state
state
in
in
that
that
action.
action
So
so
that's
that's
all
all
there
there
is
is
to
to
it.
it
We
we
take
take
the
the
current
current
state
state
and
and
the
the
action
action
and
and
use
use
it
it
to
to
compose
compose
the
the
next
next
state.
state
But
but
we're
we're
not
not
quite
quite
done
done
yet.
yet
We
we
still
still
need
need
to
to
set
set
up
up
a
a
way
way
to
to
dispatch
dispatch
actions
actions
and
and
also
also
select
select
a
a
slice
slice
of
of
the
the
state.
state
Dispatching
dispatching
an
an
action
action
is
is
super
super
easy.
easy
All
all
we
we
have
have
to
to
do
do
is
is
write
write
a
a
method
method
here
here
that
that
takes
takes
an
an
action
action
as
as
an
an
argument
argument
and
and
then
then
we'll
we'll
go
go
ahead
ahead
and
and
call
call
actions
actions
next
next
and
and
push
push
that
that
next
next
action
action
to
to
the
the
stream.
stream
Now,
now
when
when
it
it
comes
comes
to
to
selecting
selecting
data
data
from
from
the
the
store,
store
things
things
get
get
a
a
little
little
more
more
tricky.
tricky
The
the
first
first
issue
issue
we'll
we'll
tackle
tackle
is
is
that
that
this
this
observable
observable
should
should
be
be
shared
shared
between
between
all
all
subscribers.
subscribers
In
in
other
other
words,
words
we
we
don't
don't
want
want
to
to
create
create
a
a
new
new
observable
observable
every
every
time
time
a
a
new
new
subscription
subscription
happens
happens
on
on
the
the
store.
store
On
on
top
top
of
of
that,
that
we
we
wanna
wanna
make
make
sure
sure
that
that
a
a
new
new
subscription
subscription
always
always
gets
gets
a
a
value.
value
When
when
you
you
have
have
a
a
hot
hot
observable
observable
and
and
it
it
receives
receives
a
a
new
new
subscriber,
subscriber
that
that
subscriber
subscriber
won't
won't
receive
receive
any
any
data
data
that
that
was
was
emitted
emitted
in
in
the
the
past.
past
Well,
well
fortunately,
fortunately
we
we
can
can
solve
solve
all
all
these
these
problems
problems
with
with
one
one
magical
magical
operator
operator
called
called
share
share
replay.
replay
This
this
will
will
ensure
ensure
that
that
all
all
subscribers
subscribers
are
are
sharing
sharing
the
the
same
same
source
source
state,
state
and
and
it
it
will
will
also
also
save
save
the
the
last
last
emitted
emitted
state
state
so
so
new
new
subscribers
subscribers
will
will
always
always
get
get
a
a
value
value
when
when
they
they
subscribe
subscribe
for
for
the
the
first
first
time.
time
Now
now
our
our
last
last
major
major
hurdle
hurdle
is
is
figuring
figuring
out
out
how
how
to
to
select
select
a
a
slice
slice
of
of
the
the
state
state
or
or
a
a
nested
nested
object
object
property
property
and
and
only
only
listen
listen
to
to
changes
changes
on
on
that
that
slice.
slice
Once
once
again
again
for
for
that,
that
I'm
i'm
going
going
to
to
create
create
my
my
own
own
custom
custom
RX
rx
JS
js
operator.
operator
It
it
takes
takes
the
the
path
path
as
as
an
an
argument
argument
which
which
is
is
just
just
a
a
string
string
and
and
dot
dot
notation
notation
that
that
points
points
to
to
the
the
object
object
property
property
that
that
you
you
want
want
to
to
observe.
observe
And
and
again,
again
you
you
don't
don't
have
have
to
to
make
make
this
this
a
a
custom
custom
operator.
operator
I'm
i'm
doing
doing
it
it
strictly
strictly
for
for
code
code
readability.
readability
It's
it's
going
going
to
to
take
take
the
the
current
current
state
state
observable
observable
and
and
then
then
map
map
it
it
down
down
to
to
a
a
nested
nested
object
object
property.
property
Lodash
lodash
has
has
a
a
get
get
method
method
that
that
makes
makes
this
this
super
super
easy.
easy
So
so
we
we
just
just
call
call
git
git
with
with
the
the
current
current
state
state
object
object
and
and
then
then
the
the
path
path
string
string
that
that
we
we
want
want
to
to
grab.
grab
Then
then
as
as
a
a
third
third
argument,
argument
we'll
we'll
pass
pass
the
the
default
default
value
value
if
if
it
it
doesn't
doesn't
exist
exist
which
which
can
can
just
just
be
be
null.
null
Now,
now
normally,
normally
this
this
would
would
emit
emit
the
the
same
same
object
object
over
over
and
and
over
over
again
again
because
because
this
this
nested
nested
state
state
is
is
still
still
tied
tied
to
to
the
the
parent
parent
observable.
observable
But
but
we
we
can
can
create
create
a
a
really
really
beautiful
beautiful
marriage
marriage
between
between
RxJS
rxjs
and
and
Lodash
lodash
here.
here
We
we
take
take
the
the
RX
rx
distinct
distinct
until
until
changed
changed
operator
operator
which
which
will
will
only
only
emit
emit
unique
unique
values.
values
But
but
under
under
the
the
hood,
hood
it's
it's
using
using
the
the
regular
regular
JavaScript
javascript
equality
equality
operator.
operator
That'll
that'll
work
work
for
for
plain
plain
numbers
numbers
and
and
strings,
strings
but
but
it
it
won't
won't
work
work
for
for
any
any
objects
objects
that
that
get
get
emitted
emitted
through
through
the
the
observable.
observable
But
but
we
we
can
can
pass
pass
it
it
the
the
is
is
equal
equal
function
function
from
from
Lodash,
lodash
which
which
does
does
a
a
deep
deep
comparison
comparison
on
on
object
object
properties.
properties
So
so
now
now
your
your
sliced
sliced
observable
observable
will
will
only
only
emit
emit
new
new
values
values
if
if
the
the
data
data
that
that
it's
it's
actually
actually
listening
listening
to
to
changes.
changes
So
so
that's
that's
pretty
pretty
amazing
amazing
for
for
a
a
single
single
line
line
of
of
code.
code
But
but
now
now
we're
we're
ready
ready
for
for
the
the
moment
moment
that
that
you've
you've
all
all
been
been
waiting
waiting
for
for
And
and
that's
that's
wiring
wiring
up
up
Redux
redux
Dev
dev
Tools.
tools
If
if
you
you
don't
don't
have
have
it
it
installed
installed
yet,
yet
you
you
can
can
find
find
it
it
on
on
the
the
Chrome
chrome
Web
web
Store.
store
And
and
it's
it's
super
super
easy
easy
to
to
set
set
up
up
Because
because
under
under
the
the
hood,
hood
it's
it's
just
just
using
using
the
the
same
same
Redux
redux
pattern
pattern
that
that
we've
we've
already
already
implemented
implemented
in
in
this
this
app.
app
We
we
can
can
interact
interact
with
with
it
it
on
on
the
the
window
window
object
object
in
in
the
the
browser,
browser
so
so
I'll
i'll
create
create
a
a
variable
variable
here
here
for
for
the
the
window.
window
Then
then
when
when
the
the
service
service
is
is
constructed,
constructed
I'll
i'll
go
go
ahead
ahead
and
and
set
set
it
it
up
up
as
as
a
a
property
property
on
on
the
the
window
window
called
called
DevTools,
devtools
and
and
then
then
we
we
can
can
find
find
the
the
extension
extension
and
and
call
call
connect
connect
on
on
it.
it
Then
then
the
the
only
only
thing
thing
left
left
to
to
do
do
is
is
pass
pass
it
it
the
the
current
current
action
action
and
and
the
the
state,
state
which
which
we
we
already
already
have
have
in
in
our
our
reducer
reducer
function.
function
So
so
we
we
can
can
simply
simply
call
call
window
window
DevTools
devtools
Send,
send
pass
pass
it
it
the
the
action
action
type,
type
and
and
the
the
next
next
state.
state
And
and
there's
there's
a
a
bunch
bunch
of
of
ways
ways
you
you
can
can
customize
customize
and
and
configure
configure
DevTools.
devtools
This
this
is
is
just
just
your
your
most
most
basic
basic
use
use
case.
case
So
so
hopefully
hopefully
that
that
gives
gives
you
you
an
an
idea
idea
of
of
some
some
of
of
the
the
fundamental
fundamental
principles
principles
behind
behind
Redux
redux
style
style
state
state
management
management
libraries
libraries
Phrase
phrase
like
like
ngrx
ngrx
and
and
ngxs.
ngxs
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
want
want
to
to
learn
learn
more
more
about
about
stuff
stuff
like
like
this
this
to
to
get
get
your
your
Angular
angular
app
app
in
in
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
a
a
free
free
copy
copy
of
of
my
my
book
book
as
as
well
well
as
as
1
1
on
on
1
1
project
project
support.
support
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
In this conversation, the speakers discuss the benefits of using a state management library in Angular, including reducing boilerplate code and improving app performance. They also explain how to use the Redux pattern and create a library for store, setting up variables and actions, and sharing variables and actions. The speakers provide guidance on creating a custom operator, selecting a slice of the current state, and configuring variables in the current action and current state. They also discuss how to interact with a window object and set up a property on a dev environment.
Redux from Scratch
Why use a state management library in Angular when you can just build your own from scratch? When you combine RxJS with Angular's dependency injection, it provides a powerful foundation for building your own state management system. That means you can get all the benefits of the Redux pattern, including the dev tools that you see here on the right. But you can create your own distractions and conventions to reduce the amount of boilerplate code. Plus, you'll have a much better understanding of how your app works under the hood. Over the next few minutes, you'll learn how to use custom RxJS and multicasting to build your own state management library. But mostly, I just wanna show you how this pattern works at a fundamental level. If you're new, like and subscribe and grab the source code from angular firebase.com. In case you're not familiar with Redux pattern, here's a quick refresher. The whole idea is that we treat our app data or state as a global mutable object. The only way we can change the current state of the app is by dispatching an action. So that might happen on a button click, then the payload for that action will go to a reducer function to determine what the next state should look like. The store itself is an observable, so everything will happen in a reactive way. So anything that subscribes to the store will be updated with the latest data. The benefit of this is that we now have a one way data flow that provides a predictable history of all the changes that occur in the app. So we can do time travel debugging and cool stuff like that. If we think about this in code, our current state is equal to the stream of actions and the function that reduces them. A reducer is just a pure function that takes in the current state and the action and then returns the next state. So let's go ahead and build this thing. The first thing I wanna do is generate a service called store. And I'd also like to point out that I have Lodash installed. Not only will it dramatically simplify our code, but it will also give us better performance then we'd be able to achieve natively. So first, I wanna show you how our store service will be used in a component. One really important concept in Redux is that our component should be stateless, Meaning, they should only be listening to data from the store as an observable or dispatching actions. They shouldn't have any state of their own. So the service will provide the store itself and then also an action class which will just give us a standardized way for creating actions. The store can be injected in the constructor. Then the cool thing about building your own state management library is you can make it behave however you want. So in my case, I want to be able to grab properties with dot notation. This differs from, say, n g r x where you'd use a callback function or a pipable operator to select your data. Then there are 3 fundamental CRED operations that you're probably familiar with you work with NoSQL databases, the first one is set which will completely wipe out the store and set it with new values. So if we want to reset the store, we'll dispatch a new Action called set and that will include the new data that we want to update. But we might also want to do a non destructive update. For that, we'll create an update action and then we'll tell our reducer to only update the properties that are contained in the data payload. And the last one is delete which as its action payload expects an object property and then it will delete that key from the store. Now remember, all of our data is just a global immutable object as an observable. So if we want to view it in the UI, we can just say store dot state and then unwrap it with the async pipe. And then we also set up a method called select which will select a specific slice of that state. And setting up that slicing is probably the most complex thing that we'll have to do. And then lastly, we'll set up a few buttons here just to dispatch our actions. Then the end result from the user's perspective is just this UI with a few buttons and then when clicked, we get a full history of every state change that occurs. So So every time we click a button, you'll notice that it changes the state in the UI and then we also have an event in the Redux Dev Tools history. Overall, this is hugely beneficial for debugging and also a lot easier to test. Now it's time for the fun part. We're just here in a regular Angular service which is our store service. I have a few imports here from RXJS and Lodash. Then I'm creating my own custom action class just to standardize the way Actions are dispatched. You could also make this an interface and then create a different class for each action. That's the way it's done in n g r x. But an action is super simple. It's just a plain object that has a type property which is a string that defines the action that's taking place. And then it has an optional payload that your reducer function can use to construct the next state object for the store. Now our service class itself only has two properties. The state itself is our immutable data as an observable, and then our actions are an RxJS subject, which would just be a stream of the action class that we just created. To make this pattern super readable in the code, I'm going to create a custom RxJS operator that we can pipe into our action stream. Remember, the state is 100% determined by the actions. So we can say our state observable is equal to the actions which will convert the actions to an observable And then we can pipe in the reducer operator that we'll create here in the next step. Rxjs has an operator called scan which will allow you to accumulate values as they're emitted through the observable. To create a custom operator in RxJS, all you have to do is create a function that returns an existing operator such as scan. And scan provides 2 things. 1st, the accumulated object, which would be our current state, and also the current action that was emitted through the action stream subject. Now the only thing we have to do is write some logic to return the next state based on these 2 input objects. Traditionally, in Redux, this is done with a switch statement where we look at the action and type and then perform some logic based on the type of action that was dispatched. But you don't necessarily have to do it this way. So if we have An action type of set will go ahead and set the next state as the action payload which will just overwrite everything in the state. Then if we have an update action, we'll go ahead and use the spread syntax to merge the payload object into the current state. That will give us a nondestructive update. Then if we're going to delete a property, we can use the lodash omit operator. That's a lot cleaner than trying to iterate through all the object keys on your own. So you could pass delete either an object property or an array of properties and they would all be deleted from the state in that action. So that's all there is to it. We take the current state and the action and use it to compose the next state. But we're not quite done yet. We still need to set up a way to dispatch actions and also select a slice of the state. Dispatching an action is super easy. All we have to do is write a method here that takes an action as an argument and then we'll go ahead and call actions next and push that next action to the stream. Now, when it comes to selecting data from the store, things get a little more tricky. The first issue we'll tackle is that this observable should be shared between all subscribers. In other words, we don't want to create a new observable every time a new subscription happens on the store. On top of that, we wanna make sure that a new subscription always gets a value. When you have a hot observable and it receives a new subscriber, that subscriber won't receive any data that was emitted in the past. Well, fortunately, we can solve all these problems with one magical operator called share replay. This will ensure that all subscribers are sharing the same source state, and it will also save the last emitted state so new subscribers will always get a value when they subscribe for the first time. Now our last major hurdle is figuring out how to select a slice of the state or a nested object property and only listen to changes on that slice. Once again for that, I'm going to create my own custom RX JS operator. It takes the path as an argument which is just a string and dot notation that points to the object property that you want to observe. And again, you don't have to make this a custom operator. I'm doing it strictly for code readability. It's going to take the current state observable and then map it down to a nested object property. Lodash has a get method that makes this super easy. So we just call git with the current state object and then the path string that we want to grab. Then as a third argument, we'll pass the default value if it doesn't exist which can just be null. Now, normally, this would emit the same object over and over again because this nested state is still tied to the parent observable. But we can create a really beautiful marriage between RxJS and Lodash here. We take the RX distinct until changed operator which will only emit unique values. But under the hood, it's using the regular JavaScript equality operator. That'll work for plain numbers and strings, but it won't work for any objects that get emitted through the observable. But we can pass it the is equal function from Lodash, which does a deep comparison on object properties. So now your sliced observable will only emit new values if the data that it's actually listening to changes. So that's pretty amazing for a single line of code. But now we're ready for the moment that you've all been waiting for And that's wiring up Redux Dev Tools. If you don't have it installed yet, you can find it on the Chrome Web Store. And it's super easy to set up Because under the hood, it's just using the same Redux pattern that we've already implemented in this app. We can interact with it on the window object in the browser, so I'll create a variable here for the window. Then when the service is constructed, I'll go ahead and set it up as a property on the window called DevTools, and then we can find the extension and call connect on it. Then the only thing left to do is pass it the current action and the state, which we already have in our reducer function. So we can simply call window DevTools Send, pass it the action type, and the next state. And there's a bunch of ways you can customize and configure DevTools. This is just your most basic use case. So hopefully that gives you an idea of some of the fundamental principles behind Redux style state management libraries Phrase like ngrx and ngxs. If this video helped you, please like and subscribe. And if you want to learn more about stuff like this to get your Angular app in consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project support. Thanks for watching, and I'll talk to you soon.
In this conversation, the speakers discuss the benefits of using a state management library in Angular, including reducing boilerplate code and improving app performance. They also explain how to use the Redux pattern and create a library for store, setting up variables and actions, and sharing variables and actions. The speakers provide guidance on creating a custom operator, selecting a slice of the current state, and configuring variables in the current action and current state. They also discuss how to interact with a window object and set up a property on a dev environment.