NGXS - Angular State Management

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

I really like all that decorator magic, but I am really not sure why pure function concept in Reducers was ditched. Side-effects make great concept separation between mutating state, and working with outside world. It's making the code more stable and testable. As soon as that decision made, it's no longer about implementing Redux on top of TypeScript. It's about making more sloppy concept with better language concepts.

👍︎︎ 1 👤︎︎ u/bopm 📅︎︎ Apr 16 2018 🗫︎ replies
Captions
[Music] today we're going to take a look at ng XS a new state management library that reimagines the way the Redux pattern should be applied and angular it gives us a global and mutable data store then components can select data from the store as an observable then dispatch actions to mutate the store the end result is a circular predictable flow of data that is especially beneficial for apps that have a complex data state in this episode we'll go through the basics of ng XS from the ground up if you're new make sure to LIKE and subscribe and grab the full source code from angular firebase comm so first we need to address the elephant in the room there's already a state management library for angular called ng R X which has become very popular by taking the implementation details of react Redux and applying them to angular but the problem is that angular has a type system and makes heavy use of object-oriented programming while react has no type system and makes heavy use of pure functions in order to strong type everything and maintain a strict separation of concerns and ng Rx we have to write a ton of boilerplate code code that is often very difficult to read especially for someone without an rxjs background while I'm a big fan of ng rx and one of its top donors I think ng XS addresses some of these concerns in a very elegant way so what I've done for this video is I built an app with ng XS and then I built the same exact app with ng Rx so we can compare them side-by-side the rest of this video will focus on the basics of ng XS but occasionally I'll flip over to this ng rx app just so you can see that differences and how the code is implemented and I'm not recommending one over the other just showing you a comparison between the two the app itself is called ng XS salad bar and it allows the user to create and customize a salad order if you look at the UI here you'll see everything highlighted in green is saved in the app store and everything with a solid outline border is triggering an action so you can see here we trigger actions that add toppings to the salad and then it computes the price in response to those actions to get started we'll generate a new angular app with the CLI then we'll install ng XS store and also a couple plugins for development so we can Redux dev tools or console.log state changes directly in the browser the next step is to go into the app module and import ng XS you'll also notice that I've created a shared folder which is where we're going to keep the app state in the router state we're going to build these out later but you can think of the state as a combination of an ng rx reducer and effect in a single class then we'll import the state classes here in the app module and add them to the ng XS for route and then we'll also add our ng XS plugins here as well then just a quick side note the plug-in system is really awesome because it allows you to tap into the state changes and the action that triggered them to extend the library with your own custom functionality now just to do a quick comparison our app module and ng rx would look more like this where we have a storm module for route with a couple of reducers and then an FX for route with the effects classes now back to our ng access app we're going to build our first action inaction is just a class that has a type property and an optional payload the only difference from an ng RX action is that the type property is static using a static property here is a clever way to reduce boilerplate because we don't actually have to instantiate an object we can just pass in the class name when dispatching an action now I'm going to jump into the app state and that's where all the action happens the very first thing we'll do is model our data as an interface which should look very familiar if you use ng Rx for the app state will set a username order ID and a status the next step is to drop in the state decorator which replaces a reducer and ng rx it's a class decorator and we can strong type it to the interface that we just defined then we'll give the state a name so we can slice it from the global store based on that name so this will be our app slice and we can also pass it some default values in this case I just give it an empty string and a random number as the order ID so as you can see here we now have a slice of the state that's clearly defined with default values the next thing we'll want to do is listen to actions and then handle them as they're dispatched for that we have this action decorator that takes the action class as its argument in our case set username then you define a method to handle this action the first argument in this method is the state context which allows us to get and mutate the state within this method in this case here I'm going to use patch state to update a single property in the state without updating other items then the second argument is the action which may or may not have a payload in this case it has the username as its payload at this point we want to update the current state with the new username and we can do that by calling patch state with The Associated data in ng rx normally you would compose a new object by using the spread syntax inside your reducer function but here we're calling patch state which does the same thing under the hood but makes our code a lot more readable and there's actually a few other tricks that we can do within the state context patch state will only update the properties that are specified but if we want to update everything within the context of this slice of the state we can call set state and that will reset the state to the new specified object we can also dispatch other actions from inside this action which is especially useful when you start working with asynchronous data and the other thing you can do is you can get the current state as a plain object let's say we want to look at the current user before we actually update their user name we just call get state and that gives us this slice as a plain object now let's quickly run through a more concrete example let's say we have an action that navigates with the angular router first we'll set up an action called navigate with a static read-only type and the payload is the actual path that we want to navigate to then we'll set up our state to just be a string where the value represents the actual path that the user had navigated to then we can inject the angular router directly into our state which is a really awesome feature of ng XS one thing that you really miss in a reducer function is the ability to use angular's dependency injection and yet another cool feature is that we're not just limited to observables the angular router returns a promise when we navigate so we can actually just make this an async phone then await the router navigation and update the state afterwards async/await provides huge gains and code readability and avoids the callback hell that you would normally have in an NG rx effect for dealing with a simple asynchronous operation that's promise based that being said you can still listen to a stream of actions and handle them just like you would in an NG rx effect what you're looking at here with this route handler is a stream of actions that is filtered to our navigate action so you do have the option to do things the ng RX effects way if you prefer that and there are certainly use cases for doing so now that we have all this code in place let's go into a component and look at how we can select slices of the state and dispatch actions let's say we want to select the app state in our app component the most familiar way to do it is to declare a property and then inject the store in the constructor and then call store select and use a callback function to select that slice of the store so that's all good but in a second here I'm going to show you a much better way to do this with an NG access select decorator but first I want to show you how you can dispatch actions to do that you can simply call stored dispatch and then either pass in a single action or an array of multiple actions in this case we want to set the user name and then navigate to our lazy loaded module that's cool but let's see if we can make some of this code magically disappear let's delete everything from the constructor and instead we'll use the select decorator and then point to a property of app followed by a dollar sign by convention the library will automatically look for a property named app - the dollar sign on the root Store and that's all you have to do to get observable data from the store but if that's a little too magical you can still pass a function in to select a slice as well the next thing I want to show you is how to set up lazy loading which is really easy to do with ng XS after the user selects a name for their order it's going to redirect them to a lazy loaded route and update the state with this new data if we look at the app routing module you can see that we have a lazy loaded salad module in order to get this working we just need to tell ng XS which state to use inside is lazy module in this case we'll call ng excess module for feature and then pass it the solid state for this lazy module the implementation details for the lazy module are very similar to what we set up in the app but I still want to show you how selectors work when we need to select complex slices of the state this is common when you have to do things like client-side filtering if you imagine you have an array and you want to sort it alphabetically or something along those lines you can create a selector by using this selector decorator and then attach it to a static method in this example we'll just do something really simple like transforming the dressing property to locale uppercase now we can combine the static method with our select decorator in the actual component if you remember the select decorator takes a function so we can just pass it our class followed by the function name and then that will select that slice of the state in whichever format we want it let's go ahead and compare this code to ng our X building the selector will look something like this with ng XS on the top and ng rx on the bottom we have the functional approach on the bottom and the object-oriented approach on the top if you look at how we select state in the component you can see we get by with about 60% less code and ng XS the last thing I want to show you is an asynchronous action in ng XS jumping back to the app component will create a new action and pass at this confirm order action class and then notice I'm passing this cancel uncompleted true option in the action decorator I'll show you how this comes into play in just a second inside this action itself we're going to first patch the state with an order status of pending then we'll return an observable that represents the async activity that we want to perform that would most likely be an API call over the network but in this case I'm just returning a mock observable that has a 50/50 chance of returning true or false inside the observable we'll pipe in the tap operator if the observable resolves are true then we'll go ahead and dispatch the order success action otherwise we'll dispatch or failed now if we dispatch this action it's going to subscribe to that observable automatically normally it would subscribe to every single one and resolve to a value but because we added the cancel uncompleted true option in the action decorator it's going to cancel all the previous requests automatically let's say pretty common requirement when you have something like a type-ahead where you're making multiple asynchronous API calls and this is just one simple way that the library tries to make things easier for you I'm gonna go ahead and wrap things up there if you have any questions or want to see more energy excess content please let me know in the comments thanks for watching and I'll see you soon
Info
Channel: Fireship
Views: 72,470
Rating: undefined out of 5
Keywords: angular, angular 2, firebase, webdev, app development, typescript, javascript, lesson, tutorial, angular 5, angular 6, ngxs, ngrx, state management, redux, cqrs, ngrx-vs-ngxs, flux, rxjs, ngxs tutorial, ngxs lesson, ngrx alternative, angular redux
Id: SGj11j4hxmg
Channel Id: undefined
Length: 11min 59sec (719 seconds)
Published: Tue Apr 10 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.