Video details

Observable Services to Observable Store | Dan Wahlin

Angular
09.23.2020
English

Dan Wahlin

Observable Services (also known as Subject in a Service) provide a great way for components to subscribe to changes that occur in a service. But how do you step your app up to the next level and create a state store that also supports notifications?
In this talk Dan Wahlin will show a simple yet powerful option called Observable Store that works across all front-end applications (Angular, React, Vue.js, and more). Learn how to store your state, access it, work with immutable store state, provide state change notifications, the role of RxJS and Subjects, debugging options, and more.
Watch all the ng-conf: Hardwired presentations/videos at https://videos.ng-conf.org
ng-conf is a three-day Angular conference focused on delivering the highest quality training in the Angular JavaScript framework. 1500+ developers from across the globe converge on Salt Lake City, UT every year to attend talks and workshops by the Angular team and community experts.
ng-conf: Hardwired is brought to you by: - https://thinkster.io/ - https://herodevs.com/ - https://xlts.dev/
Follow us on twitter https://twitter.com/ngconf Official Website: https://www.ng-conf.org/

Transcript

All right, everybody. Well, it is exciting to be here, I'll have to admit, I would have rather seen you in person, but we'll have to wait for next year, I guess, for that. But I hope everybody stay safe and healthy. So my name is Dan Wiley. And last year and I talked about something called Observable Services and specifically talked about different types of Barksdale's subjects that are available. So we talked about things like subject and behavior, subject subjects, async subject and replace subject. And I'm not going to go rehash that. You can go to YouTube for that if you want to watch. We're going to talk about taking it up to the next level, though, and project called Observable Store. And this is a state management solution that's very simple to get going with, but very powerful, too, but not a lot of code. So I'll walk you through it. And that's what we'll do over the next twenty five minutes or so here. All right, so there's a quote out there that I really like by Al McGuire, and you can see it here, so keep it simple. When you get too complex, you forget the obvious. And I think it's a great quote. I like to take it up a notch for anyone that does maintenance keep it simple because someone has to maintain this crap. And it's a true story if anybody out there does production support, you know all about this. It's great to have solutions that work, but it's even better to have solutions that aren't super complex that we can maintain. So we're going to talk about how observable store can help you out with that. All right, so we're all accustomed to services and angular and we know they work great for sharing data and we could even store data, of course, in the service and exchange that with other areas of the app using things like subjects. Again, that was the topic last night. But as a service starts to proliferate throughout your application, it ends up looking like this. And at this point, I'd argue that's not that big of a deal. Pretty easy to follow, but as soon as services start getting data from multiple locations and components, getting data from multiple locations, this is generally when, you know, you have a statement. The problem is you're confused. Have you ever been sitting there going, I have no idea what is going on right now. You're sending breakpoints all over and you're just trying to figure out what is the flow of the actual data. Well, one way to resolve this is to kind of have one service that becomes your store and then have all services interact with that to actually store the data, something like this. Now, there's a lot of solutions out there, obviously, that do this and they're all very good. But this is not a talk about which one is better and which one's worse. This is a different alternative. And I'll explain more about the project and kind of how it came about here in just a moment. So if we're going to do that, though, if we're going to have a store that multiple services in other parts of the Afghan Iraq with, we definitely need a single source of truth. We need immutable state. That's going to be important because otherwise some of our change management doesn't like Ingunn changes unless the reference changes. We need notification because if you change my store over here, but I have a component over here who never interacted with the store but wants to know when it changes. We need to know about that, of course. From a debugging standpoint, it'd be really nice to build a track, change history now show you a little bit about this at the end, but you can either use observable stories, you'll see to actually have everything just in the console if you want to just watch the flow or you can even use the redux dentals if you want. And then finally, wouldn't it be nice if it was simple to implement and maintain, it's not really hard and bonus? What if it even worked with anything, not just the angular, but even some of those other ones react to view and spell that whatever you want to do. So observable store came out of a prototype a couple of years ago, I was working with a larger company and in working with that company, they wanted the equivalent of an observable service. So in other words, something that could notify other parts of the app that something changed. But they also needed store functionality with it. And kind of the story behind this is they had gone with another solution, but they had a bunch of new hires and they were just having a little bit of problem with productivity because not everybody knew what was going on. So myself and another person there, we started to put together a prototype that eventually grew to what is now this library called Observable Store. So this is kind of my definition of it. It provides a simple way to demonstrate in front of an application while achieving many of the key goals of the more complex solutions out there. And again, that's not to say any of them out there are bad or worse or whatever. Not at all. I'm a big believer in right tool for the right job. And so there may be some apps out there that don't even need a statement. But I'm going to argue there several probably that don't. And then you have the apps where, you know, you need state management because you have state following all over the place in your app. So the way this works is really simple, when we initially kind of worked on this and prototyped it and by the way, a lot of the concepts that are now in observable score came from people like yourself, came from pull request and ideas I'd hear about on GitHub. And so I definitely won't take all the credit for some of the different things that does. The way it works, though, is a component we're used to that calling into a service. Let's say that service maybe retrieves data from the server, maybe with a line or something like that, and then we need to store that in a store, maybe just for cash purposes, possibly. So what we can do is extend customer service so that it is able to interact with this store and you're going to see in a moment, we can get state by state, we can do state sleights selectors and all kinds of fun stuff like that. And then likewise, we might have another component that has an order service or an invoice, and they need to also interact with the store. Now, who knows? Maybe they just read the state. Not every service, of course, is going to be updating the state. But the bottom line is we need state to be able to flow through the app. We need that single source of truth immutability track, what's going on so that we're not lost and make it really easy to work with. That's kind of the overall goals here. So how do you get started with this? Well, you would install it, this will be the easiest step and you can simply install code within observable store, sadly observable store. The package was taken, so I had to create my own kind of sub here. But it works one now. Once you've installed it, it's tiny. By the way, I'd have to double check last night. I think it's less than two hundred fifty lines of code. Most of the functionality is coming from outer space. So it's really wrapping a lot of that and just exposing the simple to use API. So the next thing you're going to do is if you're using typescript and this is optional because you can use this with react or view or anything as mentioned, but if you use an typescript, we have support for things like interfaces so we can define a store state. In other words, what's going to go in our store? Now, in this case, I have a really simple example. You'll notice I have customers, a customer and orders right now. It could be really small like this. It could be really big. It's fully up to you. And you could have some properties in these properties, of course. Now, once you've done that, now we need to hook observable store up to our regular services, and that's an extremely simple step. All we have to do is derive from observable store, so here be an example. Notice we have a customer service that extends observable store of store state right here. Now, that alone makes your service capable of interacting with the store. Now, if you did this on, let's say, 10 services, you still have one store. All right. It creates a single thing behind the scenes and all of them can then share the same data and interact with that store. Now, because we're extended in this case, you, of course, have to call super and there's some settings that you can do down here and we can track state history and we can lock state changes. And there's even more you can go to the repo. I'll give you a link at the end if you want some of the other properties that you can use. Now, that's all it takes to get it registered because observable score is not specific, Danila, we don't have to go in and register module's or anything like that because, again, it can be used anywhere where there's JavaScript or types, actually. OK, so let's say that we've done this now, now one. Well, now the service may use to be quiet that you see here in the constructor and it may need to go call out and get data and maybe capture the data or just pull data from the store. Who knows? Maybe there is lookup data, for example, that we want to catch. So then we need to get set straight to the store. Now, this is very simple to do because we extended observable store. We can call into a very simple API. There's a set state and there's a state. Now, on the set state, in this case, we're fetching some customers and I'm going to assume I want to cash them so you'll notice the first parameter there is customers and that will become the property name, of course. And then you'll notice the second one is I made an enumeration, but you can pass a string if you wanted. This is the action I need to track the actions, because if I go into the history, I need to know exactly what happened at what stage. And so the action that you put here, that will take care of that. Now I'm using what's called a string them. So this enumeration just saved me typing magic strings that don't like strings a whole lot. But ultimately behind the scenes is Renton's. Just save me from typing that. All right, so now customers will be added to the store. That's all you have to do. Very, very simple. And you'll do it in a cloning kind of immutable way. Now, from there, if you want to get state, so let's say we call this get all function, and if we already have customers in the store, I'd like to use those. I don't want to go back to the server in this case. Well, we can call get state within that service. And because the state is part of observables score, we'll have access to that. And now if we have some state which you'll see right here and we have customers, we could go ahead and just return those. In this case, I'm happy to make an observable course. And then if we don't, we'll call the customers that you just saw previously. So very, very simple. Now, there's a lot more you can do with the get in state, I'll have to admit in twenty five minutes. I can't do that part justice. But that's how easy it would be to get data in and out of the store, at least to get started to begin with. Now, what if you have a component or a service or some other aspect of your application that needs to be able to know about when this door changes, what would you do that? Well, I mentioned earlier that last time I talked, it was called mastering the subject, and we talked about all these subjects like behavior, well, observable store uses of behavior, something behind the scenes. And what it will do is when somebody subscribes to a behavior subject, you'll get the data that comes down. Now, what if somebody subscribes later to be down here, well, with a behavior subject, they'll get the last piece of data and that will now slow down as well as any future data. So really nice. And that's really what's going on with the observable storm. So what we can do then is observable store exposes a state change observable, we can then subscribe to that. Now, in this case, I'm assuming I'm going to use an async pipe that is this this that customer's here. And I put the dollar there to kind of signify more of a streaming operation. But I call customer service, which extends observable store state change. And then I'm going to pipe the data that came in and only grabbed it. Now, this is the most primitive way to do that. There's several other ways as well you can do state selector, it's called, and some other things as well. But this is the kind of easy way to do that, and then let's assume we would bind our customers that you see a popular to, who knows, maybe four and we're going to use the async pipe to do that. All right, so that's kind of a quick overview now let me jump over to sample map here, and this is part of the observable store sample, so you're welcome to go to that project. You'll see the samples folder and then you can take a look at this. So you'll notice here that we now have a simple service that extends observable store. And I'm not sure how big that is on your screen. So I'm going to go even bigger. But here we go. So here's my store. That's just an interface. And then if I scroll on down in super, I can pass in things like state selectors that 10 times I can pass in settings for the store and you can even register settings globally for the app as well. Now, you'll notice in the user settings, I'm demo this in just a moment, I am going into set state and I'm going to set a property called user setting. So let's imagine that the user can interact with user settings, maybe change like their preferred name or email their scene. And until it goes back to the server, you want to store that. And maybe those changes are used throughout the app. Maybe up on the toolbar, for example, you want to show preferred name or maybe the theme is for the whole app, of course, if they change it. Now, in this case, you'll notice I'm calling ad user settings when I set the stage and I'll show you where this is used in just a moment. Now, if we go to update the settings, I could also call set state. In this case, I have a different action. And then we can come on down and any time the state changes, I can be notified about that. Now I'm making a little wrapper around that to make it even easier for components to subscribe. And I'll get to that in just a moment. So if we go into the application itself. All right, you'll you'll notice it's a pretty simple app, has customers and orders, but if I go into settings here, these settings are now in the store. Just retrieve those. Jimbo apparently is the preferred name here. Let's say it needs to be Jimbo, too. And I did a kind of blurry event here when it updates the server and the store. So as soon as I blur, you'll notice to as expected updates here. And then as I change the theme, I need to notify the components of that change. So it's going to subscribe to the state change of the service. And now when I go to dark and I know you're going, wow, damn, that is the most phenomenal dark team I've ever seen. I know I put a lot of work into this. Thank you. Anyway, you'll see that that's able to change. And that's all being done by updating the store right then. Then the chain fires and then we could notify. So again, it's almost like a memorial service, but with a whole bunch more bells and whistles going on there. So to wrap up, let me go to the component now for this, so the one that's actually receiving some of these changes is the app component because it actually changes and set some stuff. So you'll notice I'm injecting the user setting service and customer service, but in this case, what I'm doing is any time the user settings is called or the user settings change files, these are both observables that's going to update my user settings. And then in there I can use that to do things like update the theme. Now, of course, this is a pretty simple demo. I can move that somewhere else. But the whole point of this is now I have a way to easily know when things change. If you go in and delete a customer, there's a little red bubble up in the bar you saw. And that will show the number of items, the number of customers. Well, we can influence that right here. And notice I can grab the customers and subscribe. And again, this is just one of several ways you can know when the store changes. There's also some selector type things you can do. So to wrap up, that is the fundamentals of how you get started with observable store to kind of review the overall goals here. Maybe come on, PowerPoint. There we go. All right, so the overall goals are not that fast. It's flat, single source of truth, immutable state superimportant. Again, there's a lot going on behind the scenes with observable store to ensure that the state is not being mutated because that can mess up all kinds of things. We have notifications and we have a history as well. Now, actually, I just realized don't show one more quick thing there on the history. So let's see if I can go back. I don't know where I put that tabs, so we'll go in this way. All right, so when I go in another nice new feature, this has recently been added. Let's switch the dark and then I go back and I go to edit, maybe change the customer, something like this. Well, we can come into the redux dev tools and we also get support for replacing all those actions. Or as of right with this demo, it's actually going into the console and also writing out everything that's going on. So even with the really simplistic kind of API you can use, you can multiple ways see every little thing that's going on, as you'll see down here in the console. Pretty cool. All right, now I want to emphasize, is this the way like I have spoken? If you're a Mandalorian saying, no, it's not the way. There is no the way. The way is what's ever best for your team. So if you're looking for something, I would highly encourage you evaluate this and the other solutions out there because everybody has different needs. This is worked out extremely well for us. And a lot of the companies we work with are using it as well. But it doesn't mean it's right for you. You need to build your own prototype, go through the samples and try it up. So with that, thank you so much. Have a great rest of the conference. Stay safe and healthy and keep positive and appreciate.