Data Composition with RxJS | Deborah Kurata

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] good afternoon we're gonna talk about data composition with rxjs or in other words we're gonna cross some streams what our goal is for this session is to talk about a declarative approach to collecting combining and caching with rxjs streams with no subscriptions what is no subscribing mean no unsubscribing so here's our little sample application that we're going to use we've got on the left thing to pick something from and on the right the detail for whatever thing you picked you've probably used similar UIs in your application and we're going to go through how to make this app in a more reactive way so before we can get data on that page we need to collect that data so we might have seen the standard pattern that we learned way back when we started that in our service we and went too far okay in our service we have a method that gets products and that method just simply returns our HTTP GET in our component in the ng on in it we call this method we map it to some type of array or something and then we bind to that and that's the common pattern that we all learned at the beginning but there is another pattern that we can use which is much more declarative and the idea of this pattern is that we can simply use that observable stream and keep it as a stream throughout our application so here we're defining products dollar kind of the informal convention is to stick a dollar on the end if it means that it represents an observable and all we're doing is assigning it to what to our observable that's returned from an H ttp gun by doing this then we don't need the ng on a knit lifecycle hook we simply set a local property here in our component we call that products dollar as well and we set it equal to the value that's in our service okay good so far all right in our template then our template now has to bind to a I think I'm hitting that a little bit and that's making a little noise in our template then sorry one more time in our template then we bind to our observable by specifying the async pipe what is the async pipe doing for us well first of all it's automatically subscribing and best of all it's automatically unsubscribing so we don't need those gazillions of different options for unsubscribing we don't have to unsubscribe because we're never going to subscribe the other thing that the async pipe does then of course is it kicks off our request because it's subscribed so it kicks off a request it goes and gets our data it brings it back and it populates the variable so as products it's going to populate that products with that set of products and then we can use it in our template now the other really cool thing about binding directly to our observable is that we can then use the on push change detection strategy so we don't need to use the default change change detection what this means is we can minimize our change detection cycles which could have a big impact if your of view is doing lots of different things now on push then we'll only check for changes if an input variable has changed if a event is emitted using event emitter or the one that's important in this scenario if we have a bound observable that emits a value we have now bound to our observable so we can use pushed change detection strategy and it will check for changes and redisplay itself every time something is emitted from the stream ok that's an important point as we go forward here so why that's always an important question right why why would we want to do this well for one thing we can compose our streams we can merge all of the bits together that we need for a particular view we can leverage rxjs operator so that we can do things like filtering we can do things like accumulating we can improve change detection as we just saw and we can also more easily react to user actions which we'll see here in just a moment all right so that's collecting now we're into composing how do we compose our streams well and it turns out that when we get products back from our server it has a category number a category ID that comes with the product so if we look at the product data it has a category ID and we could just display that to the user and hope they know what a category 3 means or a category 47 or whatever but it would be much nicer if we also retrieved a lookup table and brought that down so we collected the product category data and brought that down so we could instead display the category is toolbox which would be much more user friendly so how do we go about doing that well the code to actually get that is going to be the same that we just looked at for our product we have our product categories we are getting setting it equal to our the result of our HTTP GET easy enough all right then we are going to use combined latest and we're going to combine those two streams so we're going to combine our product stream which has our products with our product category stream so that the code underneath this has both sets of data to work with okay so combine latest combines multiple streams into a new stream it uses the last emitted value from each stream and it won't emit anything until all of the streams listed and combined latest have emitted at least once so the other nice thing about this is it's going to sort of wait for us so if you ever had code that you were written in that you want to get some product data and then you sort of want and you want to get the category data and you want it to wait to get both of those before it does something combined latest will do that for you it then emits an array that looks like this look they're pointing over here can you see that right there so it emits an array the first element of that array is the result of that first stream that you pass in so with this products it's going to be an array of products the second element of that array is the result of the second argument that you pass in to the combine latest if you add a third one it would be providing that as well and so the combined latest emits this array to the rest of our code here so we can establish a pipeline that uses both of these things so that we can do the mapping between them what does that look like well here's my map the first thing I'm doing is I'm using a raid destructuring in my map so that I can assign a name to each of the elements of the array so the thing in that first element of the array which happens to be my array of products I'm assigning to be products and then categories for the second element to make it easier to work with then I have whatever other code that I need to do my mapping in my case I'm using the arrays map method because now my products is an array so I'm using the array map I'm taking my existing product that I got from the server that has my category idea it and I am using the spread operator to copy it over so now I have a copy of it and I'm adding then a category property and doing the mapping you with the find to find the name for that ID lastly I'm telling it hey I really want this to be a product so what comes out of here what's emitted out of here is going to be a product array just like products dollar would which is exactly what my UI wants only now it has this extra property called category in the component then I just change it instead of saying this dot product service dot products it's this dot product service dot products with category and that's then I don't have to change my UI because it's already binding to products dollar ok alrighty so we end up with our category of toolbox so much nicer now when we build user interfaces they're interactive right otherwise it's not an application if it's just a static page so we also need to be able to react to user changes for example when the user clicks on hammer we want to display the detail for hammer when the user clicks on saw we want to display the details for saw so how do we deal with that selection we want to be able to combine our streams such that they can react to user actions how do we do that there are three steps that we can follow to make our code react to changes when we're following this declarative approach first of all we create a new stream that I call an action stream thanks to someone on Twitter I was trying to find a good name for it and an action stream seemed perfect we need to combine our action stream with our data stream and then every time that action occurs we need to emit something into that action stream ok so those are our three steps let's walk through how to do those first of all we create our action stream so we do that using a subject or behavior subject or some things similar what is a subject what's a behavior subject well a subject is just a special type of observable and a behavior subject is a special type of subject the only difference between subject and behavior subject is behavior subject takes in a default value so when you call the constructor new behavior subject you have to pass something in as a default initial value the other primary difference oh wait okay I'm gonna stop my talk then right now and can you back over there can you call me I'm gonna give the rest of my talk just to you and if someone over here if you could call me I'm gonna give my talk just to you that would be unicast right that's how our observables work our UI subscribes to that observable and at that point it fires all emits all of its stuff directly to that one subscriber the difference between a subject behavior subject and a normal type of observable is it's multicast it's what allows me to talk to all of you all at the same time otherwise it wouldn't be very efficient all right the other big difference between a subject behavior subject and an observable is that a subject can be both an observable and an observer what does that mean well subject can behave like an observable stream it can emit values but it also can behave like an observer an observer is that piece of code that we pass in to our streams on a subscribe when we do it the old-fashioned way on a subscribe we pass it in a object that basically says I'm going to watch the stream and this is what I want to do on next this is what I want to do if an error occurs this is what I want to do if when the stream completes so a subject behavior subject acts both as an observer and has these next air and complete methods okay so the second step now that we've got our I let's go back a second there now that we have our action stream created there it is product selected action and notice that it's a number okay so we want to be every time a product is selected we want the product ID that number emitted into the stream okay well I'm pointing my thing at that like that's an idiot all right so anyway alright so now I'm combining my streams this time though I'm combining my action stream which is my number it's my product idea of the one the user picked with my products with category because I want my detail to also have that category string available I'm again using a map I'm using a ray destructuring again for the two different streams and then I'm using a fine to find the product that they requested and then this thing emits a new product and what happens to the UI when we emit something in the stream it's going to update the UI by the on push change detection okay so how do we kick this whole thing off well our third step our first step again was to create our action stream second step was to merge the streams third step is to make sure we're emitting these actions so our when the user clicks that click is tied is bound to a non selected method and our component which is calling a method in our service and that method in our service executes the next method which throws out emits that next product ID and that causes it to re execute our pipeline so I have it kind of Anna marble diagram ish way my first line there is representing our first stream which is our array of products the second stream is representing the actions so my first action the user clicked on the fund the product with an ID of one recall that I said that was buying latest it won't aim it until both streams have emitted so now I've got in my code a saw a rake and acts in array and then the one then when the user clicks on something else I get another ID in the action stream which causes the combine latest to re-emit and then I can process that data ok caching when I first get the data for the page I have it displayed here you can't really see it display but the idea is that I'm getting all that data when I when my user interface this async pipe actually subscribes and then I get that data down if the user then moves somewhere else like to the home page and comes back it's gonna do it all again so I've got two of these where it went out and got all that data again wouldn't it be better if we cashed it and yes we can cache the array so this is kind of a way that we might have learned to have done it we just cache it into our service and then we can share it but the problem with this is we've just lost our streams so what we instead want to do is use something like share replay and what share replay does is it shares the observable with all of the subscribers so the next time that the user comes to the page it just reads the values that it already has ok the last thing that I want to cover then is observable all of the things our page our page on the right there our detail page has more than just product and category information on it it also has a list of suppliers and it has a header at the top that is also adjusting for each product that's displayed so lets observable those things as well so here we can do in our component we can make our page title adjust automatically every time the user picks a new product by used the product dollar observable and piping it transforming it with the map from a product stream into a string and then for our product suppliers we can do something similar to be did with the categories and the products and we can define that as a stream then we can merge all the streams using this code so we're going to use combined latest and we're going to merge all of the streams required for our UI so we've got the product detail the products suppliers and the page title and notice the variable I'm using there VM dollar is that feel retro angular one ish so what we're doing then is we are taking all of that and piping it through first a filter and we're piping it through this filter because when the page first comes up the user has not selected anything there is no product and we are filtering out and jumping out of the code if there is no product to process if there is a product then we do this map we're again using a ray destructuring what we're doing in this case is we're converting an array with three elements to an object literal with three properties because that makes it easier for our template to work with the values then because we've taken every stream that our view needs and put it into one our template only needs one async pipe and every time the user picks something different in our list component our detail component will adjust accordingly and here we access each one of the properties page title product and product suppliers so what do we think is this something that we might want to try is it something we're already doing is anybody doing this technique now something like this Oh quite a few yay for those of you who didn't raise your hand this is something you might want to look at okay just a few cons to know about picking the right opera is not always easy and sometimes it is difficult to debug observables but look at all of the pros we've got lots of good things that we can be doing with that composable streams sharing observables relatively easily and I won't mention the second to the last one here out loud and uh sorry uh Brandon um so with that I want to give you links to the slides to the code and my Twitter thank you all very much thank you [Music] you
Info
Channel: ng-conf
Views: 47,872
Rating: undefined out of 5
Keywords: angular, angularjs, javascript, ngconf, ng-conf, programming, angular conference, ng conference, angular javascript, angular tutorial, Javascript Tutorial, Programming Tutorial, Computer Programming, Google Angular, Google Programming, ngconf 2019
Id: Z76QlSpYcck
Channel Id: undefined
Length: 20min 56sec (1256 seconds)
Published: Thu May 02 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.