RxJS Patterns in Angular | Deborah Kurata | EnterpriseNG 2020 #ngconf

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] let us as angular developers we often work with rxjs and observables over time we see common patterns emerging in this session we'll look at a few of these patterns and along the way i'll share some tips for working with rxjs my name is deborah karata i'm a software developer and pluralsight author let's start off with a general tip for how to think about rxjs and observable pipelines consider what do you have what do you want and when do you want it here's our sample application we want to display a list of products here on the left so what do we have well starting off we don't have anything what do we want we want that list of products when do we want it we want it when the page is loaded here's our classic pattern for retrieving data here's our service code we have a get products method that issues an http get request it returns an observable of product array what's our next step then that comes to our next tip we need to ensure each observable is subscribed and ensure each subscription is unsubscribed so our classic pattern in our component we wanted to retrieve the data when the page is loaded so in the ng on init is where we do our subscribe we store that subscription so that when the page is unloaded in our ng on destroy we can unsubscribe but what if we thought about this differently what if instead of using a procedure our get products we instead declared a variable so here we've got products dollar in our service instead but it's set to the exact same uh http get request that we had in our method the products dollar that dollar sign is indicating that what we have here is an observable and not the actual data itself so it's an observable of product array not the product array so in our component instead of our ng on init and our ng on destroy and all of the extra code for managing our subscription we could just have this so we define another local variable products dollar and just assign it to our product service uh products dollar and you could add some exception handling there but what about our prior tip how are we subscribing and unsubscribing then if we aren't technically subscribing and unsubscribing how do we deal with that well that brings up our next tip which is to use the async pipe the async pipe automatically subscribes and automatically unsubscribes for us so in our template we have some code like this so we have our products dollar that we're binding to from our component we use the async pipe to uh subscribe and unsubscribe to that for us the as products clause defines the variable that the value is emitted into and we can then use that value throughout our template so here's our first declarative pattern our declarative data access pattern starting at the bottom we have our products dollar and our service in the middle we have our products dollar and our component and then in our template we're using our async pipe i tend to do my marble diagrams more simplistically to sort of make a point a little bit more artistically so here is the data stream it is then returning and emitting that set of data our array of products that vertical line is identifying that it's done whenever we issue an http request it is one and done it returns the response and then it's finished all right so let's look at another one we frequently end up having to pass data so here in this example we have way too many products to show the user so we want them to pick some criteria maybe we want to do paging maybe we want them to pick a category in this example we're having them pick a category so that we're only showing products from a particular category but this code as we have it written isn't going to work because where is that category id going to come from so what do we do we start with our questions what do we have what do we want and when do we want it so what do we have well the user is going to pick a category so we have the category that they picked what do we want we want the set of products for that category and when do we want it every time the user picks a different category we want to go out and get those products so we have an action of the user picking that category how do we work with an action in rxjs well to respond to an action use a subject or behavior subject that's our next tip so a subject the common pattern for doing a subject or behavior subject is this when we issue an http request the http service automatically creates an observable for us and it automatically emits the response from that request into that observable when we're dealing with our own actions we need to define our own observables and we do that using subject and behavior subject so that first line is defining a private variable for our new subject and the generic argument there is defining the type of item that's going to be emitted into that stream notice that we have the private keyword on there we do that because we don't want any other part of the application any other component or service to be able to emit values or potentially complete are observable but we still want to have the ability to access the read only or observable part and that's the purpose of the second line so here we're dividing an observable notice the dollar at the end there and we're setting it equal to our subjects observable using as observable so what's the difference between a subject and a behavior subject well with a subject when you first subscribe you don't get any initial value you won't get a value until another value is emitted into the stream for a behavior subject if a value has already been emitted into the stream you will get the last one if no values yet been emitted you get the default value which is what you specify in the constructor of the behavior subject okay so once we have our action stream how do we get a value into it well we emit it we emit a value using next so we use this.categorysubject.next and define whatever we want to be emitted into that stream in this case a category id so here's our pattern our retrieve on action pattern what we have we have a subject that is going to be notified every time the user picks a category what do we want we want our products dollar and that's what we're going to bind to our products dollar what is that code going to look like there as it's written here there are two issues with this code first of all we have this inner observable and we're not subscribing to it remember that tip we have to subscribe and we should unsubscribe and second of all maybe we don't quite know what kind of map to use here so how do we solve these two problems that brings us to our next tip leverage your ide what do i mean by that well without even running you can hover over your values in your ide so here we're hovering over products dollar and you can see what their types are so if we just used a map instead of a different kind of operator here we would see that it would return us an observable of observable of product array and that's not what we want we need to flatten that we just want the observable of product array to be um emitted from our products dollar observable stream so how do we deal with that well you guessed it we have another tip um to subscribe to an inner observable and flatten the result use a higher order mapping operator these are sometimes called flattening operators what is a higher order mapping operator well a higher order mapping operator is an operator that will automatically subscribe to your inner observable it also flattens the resulting observable so it will instead return observable of your type not observable of observable of your type it also automatically unsubscribes from that inner observable cool all right we're going to look at three of the common higher order mapping operators first there's switch map switch map stops the current operation and performs the new operation concat map performs each operation one at a time in order and merge map performs each operation concurrently okay so going back to our retrieve on action pattern we have our action and this is what our pattern is going to look like here so we have our category selected action when it emits we're going to use the switch map to take the category id emitted from the action stream and issue our http get we can now then use our category id in the url why switch map and not one of the others well switch map is good to use anytime that the user could be changing their mind so i'm gonna pick category one oh no i wanted category seven what the switch map will do is even though it might start getting the data for category one as soon as it sees the next item emitted hey i really wanted category seven it will stop that first one cancel it and go ahead and execute then the retrieve for category seven okay if we then hovered over products dollar we'd see that it did correctly flatten our observable so we now have an observable of product array so using our ide we can frequently check our types which can be very helpful to ensure especially as our pipelines get more complex that each one is returning what we expect it to be returning all right here's my fabulous marble diagram for this the user picks category with 42 the result stream has the products for 42 if they later pick 15 they get the new products for that and you'll notice that there are no vertical bars on there it will keep emitting values as long as that page is displayed it won't terminate the stream until the user leaves the page because of our async pipe the next pattern is the shape on action pattern so let's again ask our questions what do we have well in this case now we have our list of products on the left what do we want we want to display the detail for the one product that the user picked when do we want it anytime the user picks one on the left we want to display that product on the right okay so how do we do it so here is our products we already talked about this this is the code that we just finished talking about and we want to change the shape of this based on an action all right so we already know the pattern for an action is to define a subject or behavior subject here now if the user hasn't picked a product yet we don't want to display anything so we don't need any kind of default value so that means we'll use a subject and not a behavior subject so here is our product selected action so now we have two streams we've got our products and we've got our selected product how are we going to work with the two of them together that brings us to our next step to work with multiple streams use a combination operator combination operators combine multiple streams just as as the name sounds we're going to talk about three of the most common one combine latest emits a combined value when any of the observables emit and it won't emit until all observables have admitted at least once so the nice thing is there if you're doing multiple retrieves it will not continue and try to work with all that data until it's actually received all of it so that's great when you have to hit multiple endpoints to retrieve the data you need for an operation merge emits one value when any of the observables that are merged emits merge is best used when you're merging things of like types for typing purposes you really don't want to emit into the same stream a customer and then an order and then odd things what you would instead use it for is if you need to get customers from one end point and potential customers from another endpoint and you want to merge them into one list you could use merge and then there's fork join the important thing to note about fork join is it only finishes it only starts its pipeline when all observables complete so you don't want to fork join action observables because they're set up to not complete until you're leaving um so when the all observables that you're joining complete you emit the last value from each observable into an array all right so we've got our products we've got our action and we're going to combine them with combine latest so there's our products our product selection and then we can use the find to find the one particular one that we want here is the marble diagram for that so our data stream user says i want product one we're going to get saw the later later go if the user later picks product 3 they'll get the x all right so let's dive right into our last pattern retrieve related data pattern so let's talk through again our questions what do we have well we have a product what do we want we want that products supplier when do we want it anytime the product changes we want to get the supplier now here we have two kind of sub patterns one case when there's a one to one relationship meaning every product has one and only one supplier and one when there are multiple when each product could have one or more suppliers so let's look at the first one first so this is our retrieve related data pattern when there is a one-to-one relationship so we have our selected product we've seen that one before and what we're going to do is pipe that one through another pipeline and here we're going to use switch map again because the user could say oh i want product one now i want product seven and it'll switch to the right one and then we're issuing an http get request and since we're using a higher order mapping operator it will automatically subscribe to that inner observable for us and unsubscribe from it and flatten the result but what about the case of having multiple so here in this example you can see that i'm returning multiple suppliers for a particular product how do we do that well this is not the best implementation but i wanted to show this one first because it's a little bit easier to talk through so here i have my selected product i'm switch mapping again on the product but this time now i'm taking the array of ids that are stored with that product i'm using from to define that as an observable so i can pipe it through some more operators i'm using merge map here then to take each of those ids and retrieve the data why merge map and not switch map well let's talk through an example if i had three supplier ids let's say for simplicity one two and three if i used a switch map what it would do is go to get one and then see the second one and go oh no let's not get the one let's get two and then c3 and then say oh no not two three and you'd only end up with the last one if you used concat map it would get one wait for one to get back get two wait for two to get back get three wait for three to get back using merge map it says okay i need one two three and then it starts collecting them one two three now the last one last line here is two array without two array what this will do and if we hovered over product suppliers dollar we'd see what it would do which is return an observable of supplier singular it's going to give us one at a time but we don't want one at a time we want the set of them so that we can bind to that set so that's why we're using two arrays so that it stops and waits for them to get collected a better implementation of this is this here so again we're starting with the selected products again we're switch mapping as the user could change the product but now we're going to use fork join and what fork join will do is we're going to take each of the ids using the map so we're using the array map taking each of the supplier ids and issuing all those get requests and fork join will automatically subscribe to each one of them and wait for all of them to finish and then return the result as an array again if we hovered over product suppliers dollar we'd see that we were returning the right thing all right so on a picture when the user picks a product it's going to get the associated suppliers the fork join will wait till it gets all of them and then return the value all right so we looked at quite a few patterns here in this session i hope that they were useful for you and here are some links for more information thank you very much
Info
Channel: ng-conf
Views: 15,254
Rating: 4.9170656 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
Id: uv_sblwIJag
Channel Id: undefined
Length: 19min 23sec (1163 seconds)
Published: Mon Jun 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.