Angular and RxJS by Stephen Fluin

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Birgit make it do it makes s my name is Steven fluid I am a developer advocate on the angular team at Google my role on the Google team really has two parts the first part is help developers and organizations be successful with their use of angular and the second is to really understand what it's like being a developer out in the real world building applications every day and then reflecting those needs within the team to help make sure that we're making the right sort of product decisions today we're here to learn a little bit about rxjs and how it works with angular's we're going to go through basically four parts we're first going to talk a little bit about how angular works make sure they're all on the same page then we'll switch over to talking a little bit about what rxjs is what the problems it's trying to solve are and then we'll talk about how they come together to solve a lot of kind of problems in a new interesting way and then we'll actually do some live coding so that we can see how some of these things come into play in the real world while building a angular application from scratch so before we get started with angular I want to get a little bit of a survey or poll from the audience here how many people have used angularjs so that is the 1x version all right almost everyone here now how many people here are using angular meaning versions 2 or later so if you're on the latest version you'd actually be on version 4.1.2 I believe and so what we're seeing is kind of a huge adoption across the community of both these frameworks and they both continue to grow but we're seeing a huge uptick in angular and that's a term I'm going to use very intentionally throughout this presentation so as we think about angular itself I use the words angular is a platform that makes it easy to build applications with the web and I want to call out several of the words here in particular so platform what I mean by platform is that we're really trying to move beyond just being a framework into solving all of the developer experience problems that you have to face and you have to overcome when you're building an application I also say building applications because these applications can be running kind of anywhere but it's a foundation we're still using web technologies right we're still using javascript we're still using browser rendering engines in some cases and so just understanding kind of how we look at things really should help you give a little bit of a background a better understanding as we proceed here so this actually picture from a dinner that we the last time the team was in London this was in November of last year for angular connect and I love this picture because mieszko the founder of angular sitting there in a chair and we Misha co-created angularjs for the first time back in 2009 we were really trying to solve a very unique problem the web was rising as a platform for building applications but it was a little bit tough right we had things like jQuery where you could make single manipulations to the Dom and so he asked the question if we could build applications any way we wanted to how would we want to build applications so that was some of the philosophy that went into angularjs the the first round around time around then the other half of that is really focusing at how do we solve problems at scale right we knew scale worked for Google and so when we try and solve problems we don't try and solve them for a few users we try and solve them for all of the users right we're trying to address millions or billions of users and so that was sort of the foundation of how angular was created and so when I flash forward to these days and we look at angular I really think about three kind of core values or things that we care about when we're thinking about the platform and how it involves our users and developers so the first thing is we want applications that users love to use second we want applications that developers love to build and lastly a community where everyone feels welcome and that last piece is very important to us because community is an essential part of what we do on a your team we would not be successful about the huge numbers of libraries toolsets seeds components all of these things that the community creates and offers up to each other makes angular what it is and makes it very powerful so one things that we look at is actually some data from the industry so back in 2016 github did a state of the octave urse so looking at and understanding the open source projects that existed on their platform and you see here that angular is actually one of the top projects by numbers of contributors even above the rest of Google which is a little bit funny from our perspective another study that we take a look at it was actually Stack Overflow 2017 survey and they looked at different frameworks and libraries that were being used out in the world and people were engaging from a standpoint of asking questions as well as developing and answering and solving issues and so the bucketed and your jsn angular together and according to their numbers and your jeff naylor together are the biggest framer of our most used framework according to everything that they're seeing and so this sort of momentum is kind of very important to us and important to you as developers because you really rely on that ecosystem as we look at kind of the more technical side of things why people like to use angular beyond just the community we see many features that we've built in but kind of some of them are baek's much more into the core of what we do the first is dependency injection which I'll talk a little bit a little bit then we've got single path change detection so how we actually operate change section which is now distinct from how we did in angularjs and then we'll look at declarative templates which have the same sort of philosophy that we've always had so the first one dependency injection dependency injection is a standard topic we didn't invent it we just leverage it extensively as part of building our platform but the way I think of it is really just access to the services layer where and when you need it in a very clean very stable way back in angularjs unfortunately we actually had to hang a lot of those things basically into global scope whereas when we look now towards how we architected angular there is nothing being polluted in the global scope in production everything is enclosed everything is relative to your imports relative to your files and so it's a much cleaner way of getting access to the services at any point in the application where you need it but because you're able to refer to things by types that are being imported from their files we know exactly what you're importing and we can be very intelligent about it another thing we did between a origin angular as we reworked how change detection works so in angularjs basically look at all of the expressions into your entire application and we would run them all and then at the end we didn't know something had changed because of change detection that happened in one place modifying something else and so we ran it again what we actually do is we would run this digest cycle over and over and over for developers until things stabilized this meant that you when you were building very large applications with maybe thousands of things on the screen runtime change section actually ended up getting very slow in angularjs and so this is one of the kind of main drivers behind our move over to angular which was a rewrite so in angular what we see is that our entire application is built as a graph a single graph that we can do a single pass of change detection so we start at the top the root component and then we can go down the tree based on the current state of the application and evaluate each component individually and say hey what has changed here and we're so confident that this is right and this is the right way to do it that when you're in development mode will actually run change detection exactly twice and if anything changed between the first pass in the second pass will actually tell you and will throw an error saying hey you had an unintentional side effect of your change detection you should go back and look at this because this is an error case the last piece that we really feel is fundamental to what we do in angular as inside you have declarative templates so we're all very used to as I neared estimating our developers writing in HTML and then adding this special syntax which is still valid HTML that makes it easier to interact and express what do I want to actually see from a view standpoint what do I want on the screen and if you compare angularjs and angular we've actually dropped something like 50 of the directives we're really trying to focus on making things much simpler and so in angular what you'll see is things like text interpolation where you can use the double braces here so person dot name is person is an object on our property of our component and we can get the name sub property of that but we can also call methods within text interpolation we can also use this within attributes as well but a little bit better than that a little bit cleaner in angularjs we had a number of different directives like ng cloak ng-hide ng show as I said we reduced and removed a lot of those and what we've replaced them with is this very simple bracket syntax where you can bind to any property on a component just by using the same syntax whether that's an image whether that's an input or whether that's a custom component that you have built yourself so there's many things that we're kind of more opinion on there some things were less opinionated on so from a freedom and from a choice standpoint we're a little bit less opinionated about data so it data is very core to what we do want angular but we were trying to expose a lot of different great ways to interact with data so on one end of the spectrum you've got things like HTTP which are going to do arbitrary fetches of endpoint data using xhr under the hood or fetch under the hood or whatever the technology you want to use there is on the other end of the spectrum we've got integration with real-time databases such as firebase we also have community members who've built things like Apollo which is a way of declaratively pulling in data from graph QL backends where you can in any of your components simply state here's the data this component needs and what I want it to look like and then Apollo will aggregate and combine all of those queries into a single query to the back-end and then all that data will come down at once and then get parsed back out into all the components that need event which is a very cool way of building applications at scale we're also a little bit less opinionated on bundlers although this is continuing to change so when we first released version 2-0 our CLI for example was using the system J s bundler but what we found was that there was still a ton of configuration work that developers had to do and so you can still build and run and bundle your application using whatever bundler you want but many of our developers and a lot of our tooling is moving towards webpack but what I say is that we're still going to continue to be less opinion of the bundler and that our CLI actually under the hood does not expose any of those capabilities that come with webpack and that's intentional Darcy lies a little bit of a black box and I said that this was intentional and we do that because the bundler systems that exist today are going to change over the next twelve months so finally we have es2015 modules landing with native support in the browsers but this native support works a little bit differently than how that all the bundlers have implemented it and so as the browser's continue to evolve and change and as search engines start to implement this same sort of features we're going to see all of our bundles are going to want to react so that we can maintain some level of compatibility between the code that we write for a bundler and the code that we write natively for the browser another thing that we're a little bit less opinionated about is how to ship great experiences for mobile we're less opinionated because there's lots of great ways to do this again on one end of the spectrum you've got things like progressive web applications where we're shipping to native browsers that have these enhanced support for things like service workers allowing you to basically in a very simple way add a service worker that proxies all of the HTP requests that you the user makes to your application and in doing so we can make your application work offline we can make it work instantly we can give you complete control of the balance of performance and freshness that you want for your application there's also installed mobile so if you're still looking for an experience that is I installed on to the App Store or into Google Play there's things like ionic which are frameworks built on top of angular that are really designed to make it easy to have that installed experience they use Cordova under the hood but there's also technologies like native script from a company called progress or formerly telluric a native script is the idea that because angular is no longer dependent on the Dom because we are no longer having to run all of our template compilation in the browser we can actually do all the template compilation and compile to a different target and so for example with native script their target is native mobile widgets so on iOS and Android you write native script instead of HTML and then you compile to these native widgets their performance and have that native look and feel out of the box so those are some of the things that were less opinionated about we're more opinionated about a few of things so template syntax so a very similar template syntax to what you saw in your dress is everywhere in angular we're also very opinionated about our rendering pipeline this idea that instead of doing all this rendering in the browser and making the users computer pay that cost we want to do all of the compilation on the build time on the developers machine so we save that time and we can make the bundle hopefully a little bit faster to run another thing we're a little bit more opinionated about is the use of typescript and so you can still use angular with es5 es2016 but there's a few places where typescript is going to get you huge advantages so for those of you who don't know typescript or haven't started using it typescript from our team's perspective is really just the latest and best from the ACMA script standard so well that's yes 2015 yes 2016 2017 and beyond typescript automatically takes all of those standards and includes them out of the box with their compiler and then on top of that it adds something that really makes it easier to work on large teams or on scale of application which is types and I'll come back to types a little bit because types make working with asynchronous data a lot easier so we're all used to having callbacks and promises and all this data that's going to come from somewhere else at some point in the future and if you can have types that follow that data that can make your world a lot easier and then the last thing that I want to talk on the real the topic that we're going to dive into today is rxjs and so we're relatively opinion about rx just because we actually use it in angular and we expose a number of ways for you to use rxjs within your own applications so let's first get into a little bit of a background in terms of the problems that rxjs is trying to solve so I say that rxjs is really about bringing functional programming principles to JavaScript you might say well why do we want functional programming principles and so I'm going to take us on a little bit of a journey and so all of this journey kind of starts with the rise of a synchronicity where we've got data that is flowing through our application coming from a number of different places it can come from api's backends income from different web sockets it can also come from user triggered events and also things like timers so all of these things are coming in and we don't control when they happen we don't fully control the order that they happen and so having a more functional paradigm can help us with that let's take a look at some of that a little bit further so you really want your applications to be more predictable but as soon as we start scaling these applications up and the client-side in an area that we can't control if you don't use a functional paradigm there become less predictable so here is a brief egregiously oversimplify totally incorrect history of JavaScript just a disclaimer all these concepts are older than me I'm just talking about the rough timeline that developers have started to adopt them when we build web technologies so in the beginning javascript was a weekend project from Netscape right it had a single thread it made a few things move on the screen and that was great but we live on the Internet right we want to be connecting to data we want to be connecting to other users and so we couldn't really just rely on this single threaded all running local set of JavaScript and so we really had the rise of the xhr and so this is hey I'm going to make a a synchronous request I'm going to go get some data I'm going to pull that back in and that works great right we're going to we've added xhr throughout our application and so I've taken something that maybe was simple like due process and now I've given it a callback right so now I'm saying hey when you get this asynchronous data back do something with that so take my success parameter but it's never actually that simple right we also need to handle the failure case and so these callbacks got more and more complicated and so what we kind of at first our beautiful structure of xhrs now it's starting to look a little bit wonky or it's a little bit harder to maintain a little bit uglier and so then we had the rise of problem so problem since we're going to solve all the problems that we had with xhrs right so instead of having callbacks we now have this beautiful painting right we have I'm going to say give me this single set of data so HP get from angularjs here and I get a result that I can then call then method I can call a catch method and I can do these asynchronous operations on in a way that feels more declarative it feels more natural but then what ends up happening is do you start looking a little bit more and more like callbacks right we have a van method we have where I'm handling the success I have a catch where I'm handling the failure and then these end up causing a few problems for us so the promise is to find where the data is created right not where I'm consuming it and so what if I wanted to retry a failed call then where I'm consuming the data I actually have to know about what's happening over in the creator of the data and I have to have a mechanism for passing information back and that mechanism ends up being all over the place within our applications and we don't really have this nice eight one-way data flow which really makes our beautiful paintings work a little bit like this where you've got paintings on every surface of your entire application and again it becomes a little bit hard to manage so from one perspective rxjs is all about unifying the ideas that came from promises callbacks and all these data flows and making them easier to work with so the fundamental principle that you need to know about an arc chef is called an observable it's just like an array but if you think of an array as being in space right and your memory observable is a sequence of events over time and that sequence events can be anything from nulls or undefined like you can contain no data all the way to having a complex object or a boolean or whatever you want to put into these sequences it's works just like an array so when I think about observables when I explain observables to developers that have never worked with them before there's really kind of two participants there's someone that creates an observable a data source and then a subscription and then observables the interactions with observables are all about how do we map the data from the source to the subscription to where I'm actually consuming that data and so in angular we have a hv library that's been relatively straightforward for developers so we have an HP diet method and so what this does instead of returning a promise we now return an observable and so I say data equals HP I get and I refer to my API so now data is going to be an observable of responses so that's the Creator and then on the subscription side I actually want to consume that data I can subscribe to that data and there's three things I can do with that data I can every time a new very values being emitted I can get that value by the next method there that I'm creating I can also see if there's any sort of errors and then I can see when the observable is done omitting values so when it is completed and then as I talked about we've got on one end you've got the creators and then on the other end you've got the subscriptions we also have a number of really useful operators and what these do is these define basically a function that happens on an operator when it's being consumed and so the simplest one that we use all the time is called map and so it does is it takes that you have the map operator on an observable it takes in an item from the sequence and then you can do whatever you want with that so if we have an observable is giving us a set of people or a list of people over time we can actually say hey turn this from a observable of people into an observable of their names and that becomes very useful because I can define that stream but that stream actually doesn't run unless someone is listening an observable is not activated until someone activates it another thing you can do is at the point of consumption of an observable right where you're subscribing you can actually say hey if this fails retry this and so you can compose these observables via various operators to make them much more interesting because I can now buy that HTP for example even if the HD was originally created in a service that's ten miles away I'm in my component I'm one actually you do something with this data I can say hey retry this if this doesn't work and that knows how to operate all the way back up the observable chain and re-emit those values or retry that those attempts as I mentioned there's this idea of hot and cold observable so cold observables are just defined right you're defining the functions you're defining the streams that are going to exist in your application but they're not actually activated until you subscribe to them and so let's take a look at how angular and just make things better when they're coming together so the first thing that we've done is we built a pipe called the async pipe so basically everyone that uses angular is going to end up using this pipe at some point so while you can do a standard subscription within your component right where you can say hey I manually want to start looking at this data you really don't want to as much as possible you want to be doing this in the declarative template style that we recommend and you do this with the async pipe and what the async pipe does is whether you give it a promise or an observable we're going to create a subscription we're going to unroll that asynchronous data when the component is loaded when that piece of the template is actually running we're going to automatically unload it as soon as that component is torn down and so this manages the whole lifecycle of subscriptions to observables so you don't have to be managing any of that yourself you're going to find observables pretty much everywhere as an angular developer so you're going to see this in many libraries so I'll look at angularfire too and also look at ng rx store which is a Redux tile pattern that we've got and then we also see these things within angular so let's start talking about angular fire too so how many people have used firebase before all right so firebase is it started as a real time database but these days is actually a number of different things so on one so firebase is now it still has the real time database capabilities but it also has things like file storage arrays has things like hosting authentication management as well as event management so it's kind of becoming a much broader developer platform but when you use firebase for authentication or databases within angular you're going to see that data come in as observables via the angularfire library that connects these two things now so here's an example where I'm defining on my component an item's property and that iris property isn't observable with a list of items and so that's a sequence of lists of items and so in my constructor I just pull in angular fire and I say hey go get this list of data from the firebase real time database and then I can say that as items here and once again this doesn't get executed this doesn't actually get run until I subscribe to that data and so I can create as many of these as I want without any runtime penalties or cost at all but then when I want to actually use that data it's very straightforward I can use it it'll by ng 4 and I can say let item of items from the async unrolled version of that and then I can access any of the properties such as the name of every item there I also mention that we have authentication integration with angularfire and so this is a very common use case where I want to for example get data about a user and so I'm going to be combining both the data coming from the authentication layer with the real-time database layer so I'm using a operator called switch map so what this basically means is every time data comes in every time authentication data comes in from firebase authentication that's events like logging out or logging in or having some sort of changed my permissions I am now switch mapping which means I'm getting a sub observable and returning that the items emitted by that sub observable we're here I'm getting the actual data for that user so my off stage is coming in because the user logged in or logged out and then if they did login so I've got a state then I can actually use something like their UID and then get fetch the data from the users table and so this gives me a single stream that is always going to be either a null or a full set of user data combining the best of the database lookup and the authentication layer another great library that exists with angular is called ng rx store and so if anyone's familiar at the redux pattern this is basically that same sort of capability built with an angular and so it's penny one summing up that pattern it really has three things it's got a store so it's a single immutable data store we're going to add data to on top of as we change or as we add information we've got something called actions so anything in the application can emit an action such as increased counter decrease counter etc then we've got reducers and these three things come together in a relatively simple way and so I can for example pull out of my store a counter so I'll do store that select counter which because of how ng RX is built on top of observables is going to give me the latest data from the store from that counter object and so we were looking at the combination of reducers that create new state from old state plus actions but I as a developer once I've created those actions once I've written those reducers all I have to do is point at the data I want and I can know that will always be have the latest and freshest data that I need but it's really beyond libraries we've actually baked rxjs into several play in the core of angular the first place I want to talk about is the router and so if we think about a sample application where we maybe have two routes so we have a default route that goes to our home component and then we have a route that goes if the user goes to post slash 42 that will pull up our view post component for rendering that item and so we use observables here to express those route parameters you can also get them synchronously but there's some problems with that so let's let's take a look what we're doing here so we're taking in this observable of parameters so any time the route changes we're going to see a new emission from the router with those parameters and then what I can do is I can return another observable for maybe a service or from firebase that fetches the data for the specific page that I'm on and then I can also use a operator or something like do if I want to do additional actions whenever this operator is being run and so the reason that we made our router use observables rather than synchronous data is because we wanted you to be able to reuse your components and so what that means is if you go from posts slash 42 to post slash 43 we don't actually Rhian Stan she ate the component at all all we do is we emit a new value from the route parameters and then you can decide how much of the state you need to tear down or build back up so it's really all about runtime performance there where we can reuse as much of the application reuse as much of the state without having to run extra cycles of change detection you can also do very fancy things so I know this is a very complex example here but I'll try and explain it a little bit so you all of the events that happen on the router are come as an observable as well and so this is a sequence of events over time what I can do is I can use something like this filter operator which gives me a subset of those events so we're checking every event and saying is this a navigation end event so did a user successfully navigate to a route that they were interested in and then I can subscribe to that and what I do is I know because of typing these are all navigation and events and what I can do is for example send an analytics request out if I want to save that a user at that state or maybe I want to look into the router configuration that exists within my application and render a page title that was set up declaratively so I can set up all of my routes ahead of time I can say right next to the URL that I want for it what the page title I want was and then this kind of few lines of code in my app component will automatically listen for all those events and then dispatch them as appropriately to the title service as well as to anything like analytics HTTP is also based on observables and so an HV by default is only going to return exactly one item and by default it returns a response and so most commonly what we're going to do is we're going to take that response we're going to get that body we're going to get that body as Jason out of it so you'll map from response to response jason a lot of people ask me why is HB an observable if you're only going to return one thing why not make it a promise but for us observables are really about how do I build more composable applications more extensible applications I already talked about the the retry method but there's another method that actually helps a ton with this which is start with so if you take an HTTP call an observable that comes back from HTTP and you say dot start with and then perhaps you have a local cache copy of the data that you want to be coming from the server now my observables going to MIT to things it's going to emit the local cached version instantly synchronously so that my UI can be up-to-date as soon as it renders for the first time and then as soon as that HTTP response comes back that day will transparent transparently be rewritten for me which is a really nice way of doing things that are would be a little bit harder to with promises if I had a promise of this then what I'd have to do is I'd have to maintain some additional state somewhere save that local copies store it there and then as soon as that promise resolves rewrite that data back and so this is something that you're going to see kind of over and over is the operators that are available to you and the way that you can combine different asynchronous functions with observables makes them far preferable to work and when I build and scale and architect large applications alright so I'm going to jump into some live coding here so what are we going to do we're going to do the traditional instant search or autocomplete so I'm going to build a basic application from scratch where I'm going to type something at the top of the screen and in this case we're going to do a search of github repositories using their github API I'm we're going to want our success criteria here is we don't want to be triggering another Network request every time the user hits a key because then we'll actually build it that way to start and we'll see why that's bad and we also want to avoid something called out of order processing where maybe one of my responses that I sent later comes back first now my data is stale and out-of-date so I'm going to jump over to the IDE here and so what I've done I've only done one step here all right where I scaffold it out a new project and I added a couple dependencies so I added angular material and the necessary animations library and so this is going to look exactly like any new project it's scaffolded by the CLI so I just ran ng new dev ox UK - rxjs what it gave me was all of the ESRI configuration all of the testing configuration all the typescript configuration that I need and then all the files that I really care about let me make this actually visible - you guys are going to be here in my source /ab folder and so you can see here we've got the module so this is the context that my application is running in so this determines what directives are available to me and then also what components belong to this module and then you've got here a component so this is just a relatively simple root component it has a single property called title and then you've got an HTML page that goes with that that actually renders out that title and so let's go ahead and make sure that this works so I'm going to go in my terminal and I'm going to run ng serve and if I'm still in the right folder we should see the start to do all the translation all the bundling of my application in this live dev mode and so what that will do is as soon as I hit save on the right side and I will forget to hit save at least one time in the demo pair of angular sunglasses - whoever points out a mistake as I'm live coding here and automatically recompile do the incremental rebuild and then refresh the browser so let's go ahead and see if that worked so I'm going to pull up local hosts 4200 all right we'll also pull the dev tools here all right app works so we have a working angular application woohoo would that was easy all right so let's say let's rename this application instant search save that and we should see this live reload so now we've got Instant Search so the first thing I always do with my angular applications is I add material design because when I build applications they look terrible material design helps me make less terrible applications so what I do is in my module here I'm going to go ahead and import two things so I'm going to import material module from angular material and I'm also going to import something called animations so in version 4 we actually split out animation so if you don't need them you don't pay the extra 37 KB platform browser animations browser animations module all right so we've got those two es2015 imports and now let's add them to our module so Rijn and material and we're going to add browser animations module all right so now we've installed material everything should work but in order for it to actually look okay I'm going to go ahead and add a very simple CSS reset style sheet as well as pull in a default theme here so I'm just going to go to my styles that's the FS file I'm going to paste these in so you just see I'm resetting the margins and I'm adding some margins back to some specific elements so that means if we go to our component HTML here we should actually be able to swap out this h1 with an empty toolbar for example and I'm going to set the color equals primary and you can see I actually have something called the angular language services which I highly recommend installed so what this will do is this will give me type completion based on a component aware model so it knows that this component owns this HTML file and this component belongs to this module and because this module has material design I'm going to get all of the material design components automatically for me here based on all of the setups and all the configuration I did in the module and you can also for example get all the properties that exist within your component so if I say title it knows that that's the property of my component and can-do type of completion and it's also type aware so if I have some complex object that I'm trying to get into I can actually see all the properties of that object all right so if we save this and we take a look alright instant search it looks a little bit better here let's make it figure all right perfect alright so in order for us to have an instant search let's make a section here and I'm going to put at the top of the section I'm going to put a input box let me use material design here again and then I'm going to in there I'm going to say input of type MD input and let's give it a place holder of search type of search and then let's give it model so I'm going to use the banana in a boxing text to do both property binding and event Bond binding for our ng model I'm going to say search term and then I'm also going to add an event called ng model change and I'm going to say new search and I'm gonna give it the search term and then I'm going to finish out my HTML here for the section for the MD input container and we're seeing errors here that's because we actually didn't write those methods of that property doesn't exist on my component yet so let's go ahead and add that back here so we should see I believe it with search term what I called it a search term and new search so search term it's just going to be a string that we're going to store locally on our property you almost got me there and we're going to create a method called new search we're going to pass in the term and so the first time I do this what I'm going to want to do is I'm going to want to use HDPE and I'm actually going to make a request and get back a set of responses so let's go ahead and import HTTP from that angular slash HTTP and then what I can do is I can get access to that H to be handled that's singleton that exists within my application that was provided by the module here you can see we've got HTTP module I can get access to the singleton using constructor and then what I'll say is I'll say public HTTP of type HTTP and so as I talked about in the beginning we're using the type that you use there in the constructor to actually know what to go fetch what to the injector should use to go provide that because we said it's public scoped it's going to automatically add that to the scope of this object and so in new search I should be able to create a new variable here called results for example and we'll say this dot results equals HTTP GET and we need a URL from github so we'll just copy this one and I'm going to swap out angular here for our search term so I'm just using the the es2015 template literal syntax alright and so as I said before this should be actually giving us a observable of responses so HTTP responses and so we don't want an HTTP observable response we actually want something a little bit more interesting so what I'm going to do is I'm going to use both a rxjs map as well as an array map in order to get exactly the data we want very quickly so I'm going to take this observable responses I'm going to say dot map response to response JSON and then from within there I want to get the items property because that's I know that github returns back and items property that has an array because I know items an array I can actually map each item and maybe I just want to get the name of that item so in this one very quick command here I'm actually diving really deep into the Jason's coming back from the server into getting items and then I'm turning every items name property into the results of the observable here and so if we go ahead indoor HTML and we actually take a look for results here let result of results pipe async so that angular does all the subscribing for us and unsubscribing I should build us the results and this should just be the name if I've done things right here so let's go ahead and take a look back at all that code that we just wrote and see what I did wrong all right so we've got let me show you'll design search box it looks kind of nice here and then what I'll say is I will just copy the word angular and so the second I pasted that in I'm getting back a full response and if we swap over the network tab we're going to see it we should see one response here it's a little bit too small let me know if you guys can't see that all right so we made a single request here at the bottom for repositories with angular as the search term and if I every time I hit a key so if I just hit backspace here every time I hit a key it's instantly doing another search and so because we're doing this all kind of in real time every time we're replacing the results instead of using an observable it's swapping out and getting rid of all the data and then as soon as the new data comes in it gets rendered so we see this flickering which is relatively undesirable and I also don't want to be searching every time the user hits a key because both of these things will trigger me to actually exceed my github limits which hopefully won't happen during this demo all right so what we want to do is we actually want to refactor this in base it off of an observable of strings so every time we get a string from the user we want to do something with that we want to process that as a stream of data so what I'm going to do is I'm going to import something new called a subject so I'm going to import subject from rxjs slash subject and so subjects are a subclass of observables they give you a couple methods that allow you to emit data when you want to and so I will create latest search of type observable actually now I'm just going to latest search equals new subject of type string and then we'll construct that all right so we have this latest search what I want to do is I'm going to refactor my new search to just say latest or this that latest search dot next we're going to omit that term so now we've turned what was a imperative set of results so every time I something changed we would imperil e throw away all the old results and now we've got an observable of those terms and so we can actually move this up into our component because very into our constructor because we only want to define this mapping once so now instead of going and getting from the term what I can do is I can say this dot results is going to be this latest search which is an observable terms and then I can save switch map and then I can say term and then I want to return that same object we had before so the same HTTP request with the same map here and then we just need a closing parenthesis so what do we do here we took our observable of terms and then we're switch mapping so every time the term changes we're returning a new observable so a new HTTP response that gives us new data and so what this does is because this data is coming in as a single observable we still can consume it in exactly the same way but we can actually now make much finer grained control of what we want to do with this and so I'm going to add three new operators so I'm going to import rxjs add operator and we're going to pull in something called we probably need a switch map here as well we're going to add something called a filter which allows us to say only give us a subset of these emissions from the observable we're going to pull in something called add operator debounce time which allows us to say hey only emit a new value if a certain amount of time has passed since the last new value so this will allow us to to batch up our key changes and we'll also pull in something called distinct and so currently rxjs is built so that you can get this very small object for so of you can get observable you can get subjects and then not ship the rest of rxjs into your bundle but then I can add as I want to declaratively all of these additional operators onto that prototype of that object and so if I do this for example in another component as well I can do the same imports on the bundle are smart enough to know hey we're only going to modify that prototype once so let's just go get all the things I need one of the things that happened recently is the author of rxjs 5 Ben Lesh actually joined Google and so we're working with him to look for ways of making this syntax more intuitive as well as to support things like tree shaking so that you can just import all of rxjs not have to worry about which subparts you're using at a given time and still produce small fast bundles for your user all right so we have this latest search with an observable of terms so the first thing I'm going to do is I'm going to D bounce it so I'm going to say every fight I want at least 500 milliseconds since the last change so if we just look at our experience now the application will refresh here and so as I type angular we're not going to see a network query until after 500 milliseconds passed and that allows me to make a bunch of changes and I can just get all the typing rights and then we make a single request out to the server server as soon as the users done another thing we can do is say dot distinct so what this does is this will only emit a new value if the underlying term has changed and so if we look back here and I said angular if I delete three characters and retype them nothing has changed so we don't actually need to do another web request and the last one's really easy to add here is stop filter what dot filter does is it looks at the item emitted by the observable and then as we saw with the router example only emits values that match so we're going to say item and we're going to say not not item or maybe term and so what this does is we're just checking the term to see if it's true the-- so if it's not an empty string because we don't really want to be doing searches for the empty string and so we're collecting all the user inputs for about five milliseconds we're making sure they're distinct and new and then we're filtering them out to get rid of anything we don't actually want to search for and so very quickly here this is going to refresh and now we've got kind of the the right instant search box that is good on my go for my users and good for my API so I type angular here and back space across everything the data is still there while the user is thinking about their next search so that was the simple app pulling in live coding I've got a couple more slides left and then we'll get into questions here all right do we succeed yay all right thank you all right so another really cool thing that I love using observables for is role based access control management because what ends up happening is we build these fantastic applications we've got lots of different types of users and we want the application to look different to different types of users a very common use case of that is for example on I want my admin user to see an edit button on every piece of context right but it's not always just an admin user maybe I have 19 different roles and different permissions that are going to be expressed different ways in my templates and so what I do is I always use observables to map this data and so for this example I may use firebase so just like we saw before firebase has an authentication flow so it's kind of service could be any authentication flow you have within your application as well and then we've got a database to actually fetch data about our user and so we're going to combine these two things using observables so what I can do is I typically create an offset service CSV file and I define the exact thing that I want so when I'm when I think about observables I always want to define what do I actually want to consume in my template and so in this case I want to say ng-if is admin ng-if is user and i want to be able to do these checks to see if they are either a visitor if all these things are false their visitor they don't have any permissions they might be just a user in my system or they might be an administrator and so by starting with the end in mind if I want this observable of boolean switch is going to change whenever the user logs in logs out or even if they change permissions in real time that's the data that I want for the user and then I can define these things relatively straightforward combining that auth flow and combining that database by saying this dot user equals off state map so we're taking an existing off state that comes from the authentication service and saying did I get something back and if I got something back I know they're a valid user so once again I'm just doing that double exclamation point to get the truthiness value on so that I get out a boolean the other thing I can do is I can combine as we saw before the off state just like we did with the router where every time the off state is updated so if the user logs and logs out we get a new observable that omits values from that users permissions so here we're actually checking within firebase to see is this user is their ID exist in the admins object because if their ID exists in the admins object we know their admin if it doesn't we know they're not an admin what's really nice when you combine these things is that all these things happen in real time so if you have two users and you you add some of those permissions there their entire UI is going to react it's going to respond instantly because this real-time data is going to update it's going to say hey I suddenly have a new set of data for that object and now I can actually see that I'm an atom in that edit button will show up kind of instantly so just to kind of leave you here including rxjs is a really important part of developing your own personal toolbox right this is something that doesn't solve every problem from a developer experience but it can be very helpful especially the amount of data we were but that's asynchronous continues to grow and continues to expand thank you so much all right I think we've got about five minutes left for questions so if anyone has questions I think there might be a microphone around otherwise I can just repeat your question is it is it correct to say that we could systematically or we should systematically use switch map when whatever whatever function we're going to be passing it to passing to it would return unobservable as well instead of returning just normal data and that's what you don't yes so somebody does that it creates it flattens out this nested call right so you've got this calls when this first dates to the data changes we need to go to the second piece of data that second piece I did just also asynchronous it flattens it out and gives you just one observable that has the resulting data of both of those calls and then why wouldn't we just then you slap map flatmap I believe there's a screen flat map since which map is that flat map does not unsubscribe from past data so if my UID switches I want to unsubscribe from the endpoint that had all that data for that user yeah there there's something like 60 or 70 operators so you can get the first item of an observable you can merge them you can merge streams things like that is combined latest you'll kind of as you develop and as you learn more rx you'll just add one or two every few weeks and then you'll get to a critical mass of I don't know ten that are your kind of go-to observable operators and that'll probably solve most of your problems all right any other questions all right well thank you guys again [Applause]
Info
Channel: Devoxx
Views: 57,332
Rating: undefined out of 5
Keywords: DVUK17
Id: aYurQaN3RoE
Channel Id: undefined
Length: 47min 21sec (2841 seconds)
Published: Wed May 17 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.