Video details

JavaScript Marathon | Design Patterns in JavaScript (And How They Can Clean Up Your Code)


"Design Patterns in JavaScript (And How They Can Clean Up Your Code)" with
Tim Winfred
Design patterns are a bit of a controversial topic in the dev community. While some developers believe they are overly complicated, others are dogmatic about using them. As a JavaScript engineer, there's a good chance you'll need to know them at some point in your career whether you subscribe to design patterns or not. Let's unpack a few commonly-used JavaScript design patterns together, and discuss how they can make your code cleaner and easier to maintain.


Hello and welcome to JavaScript Marathon a week full of free online courses and some of the leading web development technologies and concepts. I'm excited to introduce Tim Winfried. Tim will be presenting on design patterns in JavaScript and how they can clean up your code. Welcome to JavaScript Marathon. Tim. Thanks for having me. I'm excited to be here. Yeah, you can find him on Twitter at contemporary Mugger. I like that. Yeah, I got to get those dad jokes in. A special thanks to this week sponsor, the Stat Labs, offering personalized training programs to suit your organizational needs, ensuring you and your company stay on the leading edge. If you find keeping up with constantly evolving technologies a struggle, and want to bring your team up to speed on one of the latest technologies. You can contact us today at High at this Co to set up your complimentary needs assessment, and the lab is hiring. If you are a senior software engineer or an engineering manager, we would love to hear from you. Send us your resume at jobs at this Co, and we have a ton of events happening next month. As you can see here on the screen, we have State of Graph QL View contributor days, State of Angular or Women in Tech monthly mentoring session in modern Web state of micro services and next week or actually later tomorrow, actually. Wow, it's coming up quick. Angular World Tour is continuing in Seattle next week. We will be in Athens and back in October in Memphis. You can find out if we're coming to your town at Angular World tour. Com and we are excited to announce the kick off of React World Tour at the start of August in Austin. Check it out at React World Tour dot. Com to see if we're coming to you or to request us to come to your city. We'd love to connect with your local meetups. You can keep track of all of our events on Twitter at this medium, and we'll be back in November with another week of JavaScript Marathon. It'll actually be our final one for the year. Right now, we have Mike Ryan with NGR Training, David course with X State and Anthony So with Bite Training with more still in the works to get lined up for that week. So you're not going to want to miss it. Follow along and check it out at the JavaScript marathon. Com. All right, that said I'm ready to hand the mic over to you. Tim, how are you feeling about it? Let's do it. All right, go. It's early. I never up this early coding, so hopefully I don't fumble too much. But if I do feel free to correct me in the comments, let me know I did something wrong anyway. The first day of fall. Happy fall. Happy fall. Thank you. All right, everybody. Thank you for joining me today. As Tara mentioned, I'm going to be presenting six awesome design patterns in JavaScript and how they can clean up your code. There's more than six, but I am choosing to present some of my favorite. I will discuss some more of them beyond that. But before I get into that, I wanted to throw out this little JavaScript and food joke just for Tracy Lee. If you're watching this one for you, I'll let it sit on the screen, sink in for a minute. So is non or is not a number in JavaScript. It eleven even Bake bread. If you can flag that, it would be true. I found that. And Tracy love code and food. So that one's for you. I was asked to do this today after I had a slight viral post on a blog post on Dev Two on the same topic. Feel free to check out the full blog post at Dev Two Twin Fred, and that's sort of what I'm going to be presenting today as well. So if you want to follow along, you can check that out. So let's jump right into it without further Ado. So the first question, if you're unfamiliar with it, is what is the design pattern? So this is a block of text. So I'm going to kind of just read the bolded out parts to you. But a design pattern in software development is a general reusable solution to a commonly occurring problem. It's a description or a template for how to solve a problem that can be used in many different situations. So it's not quite a copy and paste where, as you know, as a developer, if you go to stack overflow, for example, a lot of times, just copy and paste solutions. And that's what we get paid for. Right? In this case, it's a template that allows you to reuse it and repurpose it in a way that make sense for whatever project you're working on. And it is also sort of a formalized best practice. It is a little controversial because some developers tend to think they make your code a little bit more complex or complicated. But it's a great way of actually you might have going to recognize several design patterns in your code if you worked in code bases that companies before. And I actually that's part of the whole reason for this. I was asked by a developer a while back if I like what design patterns I used in my job, and I actually couldn't answer him. I was unaware of the things that I was working on are actually design patterns. So whenever I started writing that blog post, it took me about a week. I dug into all of them individually, really studied them, and I recognize like, wow, a lot of these are actually things that I've used or I've worked in in code bases and just didn't know that that name or that template for my code was a design pattern. So in JavaScript, there are three types of design patterns. There's actually a fourth one called the concurrency design pattern that's for multi threaded languages, which if you know JavaScript is not. That's why it's not available. Those design patterns aren't used in JavaScript for the three in JavaScript or creational design patterns, which some of these are a little convoluted definitions or wordy. So I'll try to simplify them and feel free to drop any questions in the comment section as I'm going, if the explanations don't make sense, hopefully as we get into the code, they will anyway. Creational design patterns are as the name suggests, situation specific patterns that reduce complexity by controlling the object creation. I'm going to be going over to awesome my favorite creational design patterns in a bit. We also have structural design patterns, which is where you realize the relationship among entities to simplify the design of your code. And then lastly is behavioral design patterns where you identify common communication patterns to increase flexibility in that communication. All right, to kick things off. These are the four creational design patterns, the one with the single star, the factory one is the one I'm going to be going over first and then the Singleton strict is the one that I will be going over later. I have six set aside. I'm going to try to keep this presentation to an hour to be respectful of everyone's time. So I'll try to get through as many as possible. And structural design these are the six. Now there are more in these design patterns as well beyond the ones that I'm sharing with you today, but not all of them are necessary on JavaScript. Some of them have JavaScript has native features, for example, that don't require some of the design patterns. Alright, before I kick things off, if you have any questions about anything I presented so far about what a design pattern is. Feel free. Drop it in the comments section, but I'm going to go ahead and jump on over into code sandbox to discuss the factory design pattern. I've got my code Sandbox set up for react at the moment. It comes into play for one of these a bit later because I will be using the axis library. But if you have any questions about that again, feel free to let me know. Okay. So for the factory pattern creational design pattern, we are going to be building an employee factory, so it's sort of separated into a couple different parts. So the first is we're going to create the employee factory first and then in addition to that, we're going to be creating the employee types. These will be objects. I'm going to be doing functional based objects, so you can also do class based objects if that is your preference. And then at the end we're going to go ahead and create create the employees using the factory. So as the name suggests, a factory, if you think about like a garment factory, a garment factory might create certain types of clothes and they're limited to what they can create, because maybe they only have those patterns available. So maybe the factory creates shirts and pants and socks. So those are the three. And if you try to request leggings or a hat, that garment factory can't create that without setting up a new method for that. So that's what we're going to do. Let's go ahead. And first, as I said, set up the employee factory. Sorry, you might see some console logs console errors as I go, because it's refreshing in real time. Alright. So the first thing we're going to do is set up a method called Create employee type, and then we're going to pass in that type into it. So this is where we just say like, okay, we create a switch statement and then we pass in what we can create. So we pass that type into there of the switch, and then we're going to say we're going to go ahead and give that three different cases. Let's say it's for this labs and they need would she say senior designers for developers? Excuse me in your developer. So we're going to go ahead and return a new senior developer and then break. Otherwise she said that they need developer managers, I believe. Okay. And that will return a new developer manager. So we haven't created those objects yet, but we will in just a second. Right down here. I got to break that as well. I'm going to make the developer manager the default as well, just in case he yells at me, what is going on to create employee time? I forgot to turn that into a function. Okay, there we go. So there we go. That's literally all that our factory is, as you can see, it controls all of the different types that we can create. Let me just check. Is it possible to receive or download the presentation? Yes, I will make sure that's possible. I'll also post it on my Twitter afterwards. You can also check on YouTube as well. Sorry. Okay. So back to here. So if we wanted at a later point, we can go in and again going back to the example of the garment factory. If we wanted to add those leggings or hats, we could also add on an architect. For example, here a junior developer and then allow the employee factory to create that as well. Alright. So then next we're going to go ahead and create our senior developer object. Here we go. So this is going to be a function and then the senior developer, they're going to have a name. So let's go ahead and pass in that name here and then. So name will equal name and then just to separate it from the developer manager a bit. Let's give it a method. Let's say this dot write code is equal to a function and we're just going to console log writing code. It's probably not going to like this. Okay. There we go. And then that's just so you can distinguish the difference between the two. Next we're going to create a developer manager, and that again is a functional object. We're going to give them a name as well and they're going to manage devs. Is there a function and then that will just console log managing actually to this dot name plus is just so you can see the difference between multiple Deps plus. There we go. Okay. Got to throw in those how to keep my code as clean as possible. Awesome. So that's actually all there is to the factory. You have. What a name? It's a protected type. I'm just going to say a name then their first name. Pass that in there. That's what it is. And pass it. Okay. Awesome. So that was the employee types. Put that above my object. And then now we're going to go ahead and create the employees using the factory. Let me check for questions. Okay. Create the employees using the factory. So we're going to go ahead and set up our factory first. Cons factory is equal to new employee factory like that. I am. Hold on something's up because I'm passing in the name. Right. The name doesn't go into the employee factory. It just goes into here, not the employee factory. I need to set something up with that. Okay. So Const employee factory. That doesn't take any parameters. And then we're going to go ahead and set up another Con and call it employees. And that will be an array. So then what we're going to do is we're going to push new objects into that employees array. So employees do push and then we're going to create a new object. So using the factory. So factory dot create employee type and we're going to create a what did we have senior developer and we pass in a name as well. Right. So we have type and name on the create employee method. So senior developer and this developers name will be Tracy. And then let me widen this a bit. And then we're going to do that again and we're going to use that factory to create it. And we're going to do a create employee type. And you can see right there we have a developer manager type. And then we're going to make that Tara. Alright. So we have that. And then let's just go ahead and do two more going to copy it for speed. And we're going to have I like this T alliteration. What's another T name? Tanya. Alright. So Tracy, Terra, Tim and Tania, and then let's just check make sure everything is working out. Right. And console logger employees. So here we go. In the console here you can see we have an array of four different objects in order that we created. It is a senior developer, a developer manager, a senior developer again, another developer manager. And if we pop that open, you can see the information there. And then if I just come to this console or actually let's say employees at zero and that's a developer. So they are going to write code. So let's just make sure that is working and that should console log. Tracy is writing code a little bit off with the spacing, but there we go. Tracy is writing code. Awesome. So there you go. We have a factory that is creating employees by their type. I might even put that keyword by in there just to make it a little more obvious. And if I was going to clean this up, I might move this into a separate object. And just so we don't have to manually type that out and update it in a variety of locations. Awesome. So that's the factory design pattern. Feel free to drop comments. I'm checking those outline. Next up I'm going to go ahead and go into the structural design pattern. So this is where it sorry. The decorator design pattern, which is a structural design pattern and that just like it sounds, is where you're just decorating objects. The definition here attach additional responsibilities to an object dynamically, keeping the interface the same. So that super class is the same and then you're just decorating each of the individual objects that come out of it and it allows you to extend the functionality. Alright. So I'm going to come here. I'll provide all of this code as well on my GitHub afterwards. It's the same as my let me log. So we don't see that over and over. Alright. So for this one, we're going to create some superheroes. It's pretty simple. There's a couple of different the parts of the decorator pattern. The first is the object or the general generic whatever you want to call it superhero object class that creates the superheroes. And then so that's the first thing I'm going to set up. Then I'm going to create individual superheroes using that object. And then lastly, is we're going to decorate the individual. I superheroes over it and then we'll test it at the end, per usual. Alright. So creating the superhero objects again, I'm going to be using functional based objects. You can use class based objects if you'd like. So superhero is going to be the name of my object and we're going to path in a name so that we can if each superhero their individual name. So then this dot name is equal to name. That's literally all you have to do to set up that superhero object. Checking comments. Sorry. Okay. Create some. Alright. Okay. So then let's see we're going to create Wonder Woman, do a new superhero and her name is going to be Wonder Woman. And then we're going to create another one which will be Captain Marvel new superhero. Marvel. And then last, let's just create three Superman. Of course, new superhero. And the name will be Super Summer Man Superman. Alright. And then now we're going to decorate those. So each as you might expect, the superheroes, each of them are going to have their own individual superpowers. Right. So we could use this. This object, the general superhero object, the super class interface. There's a bunch of different words for it to give them mutual things. Like let's say this dot is super. Is true. So they're all going to be super. Right? And they have individual names. But then we can add their own methods and it's super easy. All you have to do is say like, wait, those are objects I'm just gonna facing on that real quick. So Wonder Woman and we're going to say Wonder Woman has a whip attack and that is going to equal a function. And whenever she does her whip attack, we're going to console log. This dot name plus is doing a with attack. You can see all I'm doing right here is I'm just decorating this Wonder Woman object. So we know she'll have this attribute of name and we know she'll have the attribute of this is super. Well, also decorate her with a whip attack because that's her individual attack. So we can do the same thing with Captain Marvel and Superman. So Captain Marvel does I don't even know, travel through time function. I can log this dot name is traveling through time. And then lastly, Superman fly and console log name plus is traveling through time. It's that simple. There we go. We've decorated each of those individual objects and then so now let's go ahead and test them. So let's go ahead and console log or wait. We can just do call bar method. So Wonder Woman with attack. Captain Marvel. There you go. You see it in the console already. Captain Marvel travel through time and Superman fly. Alright. There it is. Wonder Woman is doing lip attack. Captain Marvel is traveling through time. And I wrote traveling through time here as well. It's early, like I said, is flying. There we go. Alright. So right here. There you go. There is our structural design pattern of the decorator pattern. And next up checking comments. No questions on that. If you have any questions, feel free to let me know. Alright. Next up is the behavioral command design pattern. So this design pattern is actually one of my personal favorites, because if you I mean, we're all developers, I'd assume so if you've ever tried to create something like a calculator, which is what we're going to do, you know, it can get a little messy creating all of these functions. So I love this one because it encapsulate the object and allows each of those methods to be parameterized using different requests and then use the logging of those requests. That's super wordy. Feel free to reread that. And soak that in on your own time. Let me show you what it does. That's the best way to explain this definition. So going to come over here. Let me comment out those. We're not getting these on logging over and over again. So there's pretty much two parts to this. The first is we're going to create our methods object. Excuse me. Sorry about that. We're going to create our method object, and then we're going to create our calculator at calls methods by passing in. So this is a calculator object just to clarify passing in the parameters. All right. And then per usual, we will test it at the end. Alright. So the first thing we're going to do is we're going to create our calculator methods. So we're going to create the four basics. We're going to do the add method, which will be a function and it's going to take in two numbers an X and a y, and then we'll return X plus y. So like me doing this on the same line. So. Is there. Subtract? It should be pretty obvious. Just run through this really fast turn X minus y. Multiply. Return times by and to find to be a function as well. Turn X divided by y. So that's all that we need for calculator methods object. And then next we're going to create our calculator object, which actually executes each of those methods by passing in the necessary parameters. So how later? Actually, I'm not going to call these new because I'm not using this method for this feature. So those are just going to be lower case. So this is going to have an execute cute. And it's going to take in three different parameters. So later what we're going to be doing is we're just going to be calling our calculator with the execute method and the three parameters. So the first one is going to be the method. Add, subtract, multiply and divide, and then number one, which will be that X and y and number two, X and y. So the first thing we're going to do is we're going to check to see if that method actually exists in our available methods, or if it doesn't, and then we'll return. No, if it doesn't, if the method does not not method and calculator methods return. So if the method doesn't exist in our calculator methods, otherwise we will go ahead and return the calculator methods calculator methods at the method that we passed in and we're going to pass that number one and number two. So there you go. So if you look, we will be grabbing if we pass an ad. This will result in this method. Here the add method. And then we're also passing a number one and number two, which up here become X and y. Check for questions. No questions yet. Okay, now let's test it. That's it. That's all we have to do. So this is we just use this execute command and it sets it up super simple. So we just call our console. Let's do a console log on each of these commands. And say calculator dot execute and we're going to add two and we're going to add five, so that should be seven and we're getting seven immediately there. Let's go ahead. And I'm just going to copy this and we're going to do that four times. Wait, did I call it minus? No subtract attracts multiply and fine. Alright. So let me clear this out real quick just to make sure it looks like there's some sort of error in there. No multiply. I forgot the multiply. There you go. So you can see seven is the addition method. Minus three is the subtract. Ten is the multiply, and 0.4 is the divide. Awesome. So that is the command behavioral design pattern. Again. Like I said, it makes it super easy. You can just set whatever the return value is to however you're going to use it. And all of that is managed in a completely separated out calculator methods object that is then called in the calculator object. All right. So next up, let me go over to my slides. This is such a fun one. It's simple. It's easy. It's the Singleton design pattern. It's now the creational design pattern. And as the name suggests, it ensures that the class has only one instance and we provide a global point of access to it. So this one is fairly easy to grasp the concept of. Let me comment. Okay. So today for this, I'm going to be building a single database instance, and it's fairly simple. We have literally just one part of this. So that is our Singleton object database. We're going to create that first and then we're going to test it and make sure that we're only getting the single object. Okay, let me scroll. So we're going to set up our database. And unlike the other thing, other ones that I've set up before, this is actually going to be a self invoking function. And we're going to do that in order to wait. Did I do that right now? Okay. Outside of that, a self invoking function. And what that's going to allow us to do is have some private methods as well as return the public methods. Let me show you what I mean. So the first, as I said, this is only a single instance of an object. So once this database instance has been set up, we want to make sure it doesn't create another one. So in order to do that, we need to set up this initial instance variable, and it's a let because we're going to reset it once. As you can see, we're going to check that it exists or not based off of this being an empty variable or an undefined variable. And then we're going to have two private methods. So the first method is going to be the create instance method, which will handle the creation of it. And then the next method will be the get instance. And so that get instance is what we're actually going to return. So we're going to return and then a method called get and that is going to return the method get instance so that this publicly can be called as database get. So we're going to set up this get instance first and you'll see why in just a second. So if there is not an instance, right, what we're going to do is we're going to set instance to create instance goals. Create instance. Otherwise we're going to return the instance. So center setting this as setting this create instance function. That means we're going to need to return return an object. I want to set up that object outside of here just so we have. So database object is equal to a function. We're going to say this name is equal to my database. And just to show you that whenever I try to create more than one instance, I'm going to go ahead and create an ID and that will be a random number. So I'm going to go ahead and do math, floor math, dot random. I think it's like that. And 1000. Yeah. Okay. Times 1000. There we go. So hopefully whenever we return a new database space object, if everything went well and my Singleton instance right here. Right. If the instance doesn't exist, we create one. Otherwise we return in the instance that we've already created. So if everything went well whenever I test this right now, it should work out. So let's go ahead and set up on TV one is equal to database dot get and then the B two is equal to database get as well. So this will ensure that these whenever I console log B one and B two. Let's see what we get over here. You can see that the ID is the same. So if I save this just so you can see that randomly generated number is the same, change the load that randomly generated number here on my database object is the same and we can even double verify that by saying console log DB one triple equals DB two. And that should Consolo true. There you go. So this is great. Like if you have settings and you're using like a cash key on those settings to make sure that the cash key is getting updated or that the cache is clearing whenever that ID changes. Awesome. Let me check, see if we have any questions. What was the previous pattern called? The previous pattern that I worked on was the command design pattern. That's the one I built the calculator out of. Alright, so that one the Singleton design pattern. Where are we at on time. We have 15 minutes, about 15 minutes left. So if you have any questions about where I'm at, I want to pause real quick before I get into the facade design pattern and allow some time for questions. I'm going to keep going, but I'll keep an eye on the questions down there. So the facade design pattern is actually one that is probably the one that I personally have seen the most in the professional code that I worked on because it separates it out. Separate your code out into like, if you ever use a utility tool where you move methods into a utility file and call that and import it into others, or maybe you have a utility package that's internally managed by your company. That is an example of the facade design pattern. So the definition here is you attach additional responsibilities to an object dynamically, keeping the interface the same decorators provide flexibility, flexible alternative to subclassing for extending functionality. This like I copied and pasted from my decorator pattern. It is that is the wrong definition. I apologize. Let me I've got two. Let me pull up my design patterns, and I want to get you the definition. So it provides a unified interface to a set of interfaces in the subsystem facade finds a higher level interface that makes the subsystem easier to use. So as I said, it's something like the utilities. So let's go ahead and create that. We're going to create just the get method just to show you. But this is where I'm going to be using that Axios library. If you're not familiar with Axios, it's just another way of fetching API data. So let's go ahead and then we're going to have a couple of different method. So I'm actually going to create just a solo, an entirely new file here. Okay. That's going to be too complicated. Take too much time. So I'm just going to keep it all in one file. But generally you would have all of the methods in the facade separated out into a separate file. Like I mentioned, like a utilities file or separated into a node, an NPM package. So I'm just going to put a little wrapper around my facade here. Just so you know what I would end up having in a separate file. Okay. So the first thing is going to be we're going to create the a couple of functions that we want managed here. So function get users, and that is just going to call that's. Okay. This is not in the facade facade is an object, and that is going to have just a method called get a function, and we're going to pass in the U, the URL and the params. And this is where I'm going to use Axios, which have already imported way at the top up here. Let me go ahead. Where am I database object. Let me comment out that. So we don't keep seeing that in the console. Okay. So this is where I'm going to use Axios. And just if you're not too familiar with Axios, this is a quick overview, but we're going to go ahead and return Axios with the URL, the params and the method will be to get method. And then after we do that, then we're going to do a conversion of the response. Rest data, which is what Axios returns. Okay. So externally we are going to this is our facade right here. So in our file where we want to call the facade, for example, we could say function get users and that's just going to call the general facade get and I've set up this little URL from JSON placeholder to just get the users. So JSON plate you can check that out. We'll see in just a second. What that is what's going on with Prams and then function get users by ID and we're going to pass it or get user by ID. And then we're going to also use that facade. Let me copy that URL again. And then this time we're actually going to pass in an ID object. Return is not a method. Okay, there you go. So now you can see we're using the facade to create this get method. And the great thing about that is later. If we ever decided to switch up our get method, all we have to do is update it here instead of calling this axis in each one of these individually, this is just one time you set up the Axios get facade and you could do post patch, put delete all of the other methods as well. And you could even create a utility if you wanted like, a general one is something like adding the dollar sign, converting a number to a currency floating out two digits and adding the dollar sign. A currency string would be another example of like a utility that would be in the facade file or library. And then let's test this. So because we are actually making an API request, we want to make sure we're waiting for the response. So I'm going to go ahead and create an async test function. And. Let'S go ahead and grab those users. So Const users equals get users. But I want this to be in wait. So we don't run the stuff below it. And then console log users. Let's make sure we're working over here. I have to call that test function. Lastly. There we go. I can see who is it? Console Logging choice. We have nine users that are getting returned here in that console log. Then let's go ahead. And I mean, we know that we have ten users, but generally we wouldn't do it this way is equal to wait. We loop through all of the users, right. But I'm just going to go ahead and do get users get user by ID and number one and console log user one. And there it is at the bottom. I'm not sure why this is running twice, but confusing me, but that's okay. So here's user one. There you go. We have only about five minutes. The strategy design pattern. I will just show you my code for that instead of building it from scratch. So here if you look on my GitHub. So this is where you define a family of algorithms. Just pretty wordy. So I apologize encapsulate each one and then make them interchangeable strategy lets the algorithm very independently from clients that use it. So whenever I originally created this, I decided because I work at Fandango to create a movie ticketing strategy. So right here we set up the Regal object that has the get ticket price and that takes in a quantity and then it returns the quantity times 1199. Same thing with AMC just 1099 and Cinemark, which is 999. And then what we do is we create this ticket price object. I might actually rename this if I was rewriting it right here to theater. So function ticket price. And that has a theater chain which we don't set immediately and we don't even pass in a parameter. We actually set it with the set theater chain method. And then this ticket price also has a calculate so that takes the theater chain and then it returns the get ticket price. So depending on whatever we set as the theater chain like right here cons Regal, AMC Cinemark. We've set up there and then we created our ticket price object as well. And then we set the theater as legal. And then we calculate that times two same thing with AMC and calculate that. And what that's going to do is that's going to attach you see, I'm updating without creating a new ticket price, I'm updating the theater chain and then just calculating that. Alright, so that is the strategy design pattern. So I sort of ran out of time on that one. But those are the six awesome JavaScript design patterns that I wanted to show you today. If you have any questions or any of this does not make sense, feel free to hit me up on Twitter at Contemporary, and you can even check out all of these on my GitHub. In my JavaScript design patterns. Repo, I will be saving all of the code that I wrote today in one big block on to my GitHub as well into this. And I will save it in a folder that's probably called something like JavaScript Marathon and the date. So check that out. If it's not there in a couple of hours, check back tomorrow. I'm going to pause for the next two minutes or not two minutes, but a couple of seconds and see if there's any questions. If not, that is time for me. We're at an hour again. Want to be respectful of your time. Thank you so, so much for joining me. Thank you this lab for having me, Tara for hosting and Tracy for inviting me. Follow me on Twitter and I hope to see you guys soon. Thanks so much.