 Hi there. Thank you for all coming out today. It's awesome seeing you all. Yeah, this is me, Rob Dodson. This is my contact info. If you want to send me questions or comments after the talk or just help me build a massive Twitter army to take over the universe, I'm going to do so there. This talk is called End to End with Polymer. And my goal with this talk was to basically build an application starting from just an idea and taking it all the way to production and kind of thinking about all the steps along the way. This is the app that I built. It is a pretty simple to-do list app, but it's got a few cool features built in there. So it's got real-time data syncing. It's got user authentication. It's all hosted on HTTPS. So there's enough sort of cool factors there to make it feel like a nice sort of production-ready thing. And what I want to do is go through the problems that I faced while I was building this app and present to you the solutions that I came up with, little strategies and tips to make your process a lot easier. So the first problem when you're building any app is one that I'm sure basically all of you are familiar with. You want to build something awesome and you're just kind of looking at a blank page, right? And that can be incredibly intimidating because web development is just a super complicated trade. You know, any time you're starting off a project, there's a million decisions that you need to make. And there's all these different sort of tools and libraries. And each one of these is kind of like a rabbit hole that you could just disappear down, spending a ton of time researching and not actually writing any code. I've got a lot of side projects that I've started, where I just ended up, I was just reading blog posts about, you know, tools and libraries and things like that. And so for that reason, we created this project called Polymer Starter Kit. And the idea behind Polymer Starter Kit is we want to give you all of the best practices that we've come up with. We want to give you all the best tools that we've found out there so that you don't have to spend a ton of time doing that research. You can just get up and running and start building your app. So out of the box, a few of the features that Starter Kit includes is layout for any sort of application. You get these nice responsive app layouts as well as a router for building single-page apps. You're going to get components, basically, from our paper set, our iron set, even our platinum set, sort of just built in there, already wired together for you. So maybe if you're not super familiar how to use some of these components, you can actually see them in action and sort of grok how they work. You're also going to get unit test support for Web Component Tester. I know you're all testing your code, right? It's very, it's very, I don't know. Getting a little uneasy here, guys. And lastly, there's going to be support for Gulp. And you get this entire build chain right out of the box. And the reason why I think this is crucially important is because from the moment you start working on your app, you can just type Gulp and get a distribution, right? So you could just deploy that thing. And it's very important to have that early on versus when it's actually time to launch the thing and you're like, wow, I wish we'd structured this differently so it was easier to build. So with Starter Kit, you're just going to be set up on the fast path from go, which is awesome. Now, to get the Starter Kit, you would go to developers.google.com, slash web, slash tools, slash Polymer Starter Kits, the longest URL ever, or you can just Google it if you're like me and you're like super, duper lazy. And when you do that, it's going to take you to this page. We can go and you can click the download button there. And that's actually going to take you to GitHub. And then there's two flavors. There's a beginner and an intermediate slash advanced flavor. You probably want the intermediate advanced flavor because that is the one that contains Gulp. And you might be watching this right now thinking, yeah, but I'm super lazy and I don't feel like doing any of that stuff. Like can I just get all the good parts? So yeah, you actually can. We built a Yeoman generator as well. I did because I'm wicked lazy. That just takes Starter Kit and we'll just stamp it out for you. So with two little commands from your command line, Yeopolymer and Gulp serve and the magic of time lapse video. You can just get started with your very first Polymer app. You'll get something on screen in just a few seconds. And you can see we've got our single page router working there. So you can flip through the different routes and see what you get. Got that layout already set up for you. So problem number one, the blank page, solved by Polymer Starter Kit. Awesome. But that brings us to our next problem. We need to take our app now and sort of break it down into smaller and smaller pieces. Kevin said we need to eat giant lollipops or something. I wasn't listening to him in his talk. So yeah, but the idea is you want to break it down into smaller, smaller components that just have one single responsibility. You don't want to try and just build this one monolithic thing that's wicked confusing. So what I'm going to do with my app is I'll start off with kind of what seems like a large component called to-do view. But really, its job is just to kind of lay everybody out. It's not really going to be doing, hopefully, too much. And then it's going to be composed of smaller elements. So it's going to have to-do list element inside of it, which will have to-do items inside of that. There's one element that I'm not showing, which is to-do data. So I'm actually going to have an element for that as well. And so the flow that we're going to do here is we'll start with to-do data. That'll have all of our collection of to-dos. And it's just going to go along the way and it's going to pass our to-dos down the line until they end up as an individual to-do item. So let's start by building to-do data just so we can see what that looks like. So this is the markup for that element. It's pretty simple. It doesn't even contain a template. Its sort of main distinguishing feature is this to-dos property right here. And we're returning an array by default. And every to-do is going to be represented in that array with an object. So each to-do is going to be an object with two flags, an is-complete flag, and a label for the actual text of the to-do. And we've also set the notified true flag here so it'll be two-way bindable. Now, I'm sure some of you are looking at this and you're like, yeah, dude, an element for data is super weird. It's non-visual and it gives me the creeps. But this is actually a really, really useful pattern. And we use it in a lot of things like IronAgeX and IronLocalStorage. And basically what you're doing here is you're creating this nice representation of your data. And by itself, just this tag, you'd be like, yeah, I don't get why that's important. When you combine it with data bindings, now you've got this nice declarative data provider. And it removes the need for a lot of the JavaScript that you would have to write in your app. Most of the code that I would write in a to-do list app would be just like listening to data changes and then updating the DOM in various places. And by using a binding here, I can basically remove the need for all that code. And I can also sort of hide what's happening in to-do data. To-do data becomes kind of like a facade. And behind the scenes, how data is fetched from the back end. I don't really need to know how that works. And that's cool because we're actually going to change how that works later on when we connect to a real database. So I'm going to set up an auto binding template here in my index file. And this lets me use data bindings without creating an entirely new element. And I'll just drop to-do data in there. And I will say I have this to-dos binding that I would like the outside world to go on to. And that's just representing my collection of to-dos. And because I know that I'm going to want to pipe that data into that to-do view element, I'll just go ahead and stub that out as well. So now we've created this little linkage between the two of them with those bindings. So let's look at the implementation for to-do view. Now this element kind of has two things that it wants to do. The first thing is it wants to bind that to-dos data array to our to-do list, which we'll write in a second. And that's going to cut down on our boilerplate JavaScript. We don't have to write a bunch of code to handle these things off. But this element has also kind of got a bunch of smaller elements inside of it. So it's got a clear button. It's got every to-do item that's inside of it. It's going to have this little delete button. It's also got this field down here at the bottom where you can add new to-dos. So all these elements are going to need to communicate in some way. And we're going to use to-do view to do that. So to-do view is going to listen for events coming from all these different elements and act as a mediator on their behalf. And so if it hears an event, like, hey, add a new to-do, OK, I'll step in with a handler in this situation and I will modify the data that I've got. And that's going to go off to to-do data and update it. So I kind of think of to-do view as like a traffic cop. Like he's there, he's letting things kind of flow and move around the app so that they make sense. Let's data flow in. When it hears a bunch of noise, it hears a bunch of events, it decides what's going to happen as the mediator. So that's to-do view. Next, let's talk about to-do list. And I'm sure some of you are watching this at this point, and you're like, yeah, I don't know, man. It's starting to turn into a lot of code. I'm getting kind of tired. I don't know if I feel like, if I was following along, I don't know if I'd be typing any of this anymore. Might be getting bored. So you could go and you could be typing all this code yourself right at your keyboard, trying to follow along, making DOM nodes and templates and stuff. Or you could be awesome, and you could be lazy, and you could use Yeoman to just write all your code for you. So along with scaffolding out your application, Yeoman comes with a subgenerator that we've written, which will actually generate elements inside of your starter kit app for you. And for the truly lazy I added this feature, you can leave off the last five letters. Yes. So yeah, that's what we're going to do for a to-do list. We're going to go over to our terminal, and we're going to type, yo, Polymer L, to-do list. And it's going to ask us, hey, do you want me to import it for you? It'll ask, do you want me to write your unit test for you? Do you want me to stub out your unit test and be cool if it wrote it for you? But do you want me to stub out your unit test and add it to the application for you? So you could do TDD or BDD style. And if you want, just start doing test driven development. So you get all that just by using that subgenerator, which is really rad. So the actual implementation for to-do list, it's going to look like this. And this element's main job is to take our to-do's data and iterate over it using a DOM repeat template and generate to-do items. And lastly, the to-do item there is sort of interesting because it's a component that, again, contains more smaller components. And so it's going to work very similar to to-do view, that parent component. So it's going to bind its data to the children inside of it. We've got a checkbox inside of there to indicate the state of the to-do. We've got a label to show the text of the to-do. So we're just going to bind that. And we've got a delete button that fires an event. So we're going to listen for those events and act as a mediator. So it's kind of interesting. We're just reusing this pattern, but we're getting smaller and smaller. So now we've got our app, and it works. And we can go. We can like, whoa, whoa, whoa. I'm freaking out on my slide deck right now. Here we go. So we've got our app, and it works. Yes. We can go. We can add to-dos. Things are looking good. Buy some pizza rolls. It's crucial. And check to-dos that are complete. Delete the ones that we don't want. Click that button. Clear them all out, right? Awesome. So problem number two, we solved it. Kind of. Kind of. We kind of solved it. I mean, it's cool. It's great. We're doing good, but kind of got this problem still. Check out what's going to happen here. I got that one last to-do. Watch what happens when I refresh the page. Oh. All those hard-coded to-dos in that array and to-do data are coming back, right? So my app is like, it's working. It's doing all the things that I want, but it's not really hooked up to real data. It's not persisting. It's state, right? We don't have a way for users to have their own to-do lists. So we solved our second problem, but now we're presented with our third problem, which is figuring out how to actually productionize this thing, right? And that means, you know, we got to get a real database involved. We got to get user authentication involved. We got to get hosting going. And any one of those could be kind of a big, annoying challenge. But thankfully, there is this service called Firebase. And really quick, how many of you have heard of or worked with Firebase before? OK, most of you, for the sake of the live stream, I will just say everyone raised their hand. It was awesome. The whole audience was 100% on it. So yeah, Firebase is an amazing service. It offers three really cool features. The first is a real-time database. Next is user authentication. And lastly, you get hosting. So most people know Firebase as a database platform. They don't know that it can do hosting as well, which is pretty cool. So let's break, let's go through these and talk about each one individually, starting with the real-time database. Now, Firebase has kind of like a NoSQL data store. So if you've worked with Mongo before or I think Couch is also very similar, it's just like a big JSON document that you're putting stuff into. And so at any point, you could just like fetch some path out of Firebase and you'll just get a big JSON object back, which is rad. So to work with the real-time database, we're going to use the JavaScript SDK. And we're going to create a reference to our Firebase instance by calling the Firebase constructor. And we'll pass in the path to our Firebase instance. And then to write data to Firebase, we just call this really easy set method. We pass in an object for the data that we want to write. And if we want to work with array-like data, which our to-dos kind of are, then we would call this push method. And that lets us push array-like data so we can keep pushing the same thing over and over. So I'll show you an example of this. On the right, I've got Firebase dashboard. On the left, I've got the Chrome Dev Tools. And I'm going to go through and I'm just going to set up a reference to my instance there. You can all go to the Firebase website and do this, by the way. It's really cool because they have the SDK. I'm going to call set, write some data, call push, push some data. You'll notice, instead of an array, it creates this unique ID, which is kind of interesting. So that's actually what Firebase does so it can do its bookkeeping. If you've got multiple people pushing array-like things to the same instance, it gives them all unique IDs and sorts things out for you, which is really rad. For our purposes, it's not a huge deal. We'll just fetch the data later and work with it as if it's an array. But it's kind of an interesting feature of Firebase that they do that. Now, to get our data out of Firebase once we've written it, we're going to use the value event that Firebase fires. We're going to use their on method to listen for it. And that'll send us a snapshot of our data, which we can then iterate over. Now, this is a really cool feature of Firebase. Most databases, when you're working with them, you have to pull them for data. So you've got to request a big blob of data on demand. With Firebase, since it's evented, you can have multiple clients connected to the same instance. And whenever the data updates, it's just going to push to all those clients at the exact same time, which is really cool. So you could have 1,000 people concurrently getting instant updates. So let me show you an example of the value event. Again, in the DevTools here, I'm already connected to my Firebase instance. I'm going to drop in a handler for that value event. And then I can go and just manually start adding data over there. And you'll see that as I'm adding stuff, it's just going to start showing up in my console, because it's just sending me these snapshots. Like, hey, the data changed. This is the new state of the world. So Firebase seems pretty rad. And looking at this and looking at my to-do data element, I'm thinking, well, that to-dos property is really just an array. And how about I replace that array with Firebase? And I could go and write all that JavaScript that I just showed you in my to-do data element. I could call set and push and listen for changes and everything. But thankfully, there's an element that will just do this for me. So as part of our Google Web Component product line, we've built a Firebase element set. And so what I'm going to do here is, instead of writing any JavaScript, I will just remove that value's object. So we're no longer hard coding to-dos in there. And I'll replace it with a Firebase collection element. And there's two main properties to this element that we want to check out. The first is the data property. So we're creating a little binding here. So we're saying, hey, the data that comes to Firebase, we're going to just call this our to-dos property. And the rest of the app can bind to that. So secretly, when the app is binding to to-dos, it's binding to Firebase. And then we've also got the location that we need to give the element, just to tell it where our Firebase instance is. And we can actually clean this up a little bit more. We can turn this into a binding as well. And then from the outside, we can make this element configurable. And we can say, hey, to-do data. Your location is this particular instance. And that means I could reuse to-do data in other applications, or other people could take it and use it in their own app if they wanted to. So now when somebody is using my application, what's going to happen is they're going to go, they're going to enter some to-dos. You'll see here on the right, I've got my Firebase dashboard. And it's just immediately passing that data over there to Firebase. I didn't write any JavaScript to make this happen. I just wired it all up with data bindings, which is cool. So I'm going to go crush this talk. That is in progress to do, hopefully. But now check this out. I'm going to open another window down here. And as I'm changing, my Firebase up there is changing over there. And it's changing in that second window. So I've got basically real-time collaboration going on. And I'm getting those features for free just by the nature of how Firebase works, which is really, really cool. I mean, I'm sure some of you have seen Google Docs, right? You can collaborate in there. But that's a lot of infrastructure to try to write yourself. And Firebase just gives it to you for free, which is really rad. Now, I'm sure some of you are looking at this and you're thinking, well, this is really cool, so long as the user is walking around and they have really good connectivity on their phone. But what happens when the Wi-Fi cuts out? Well, this is actually where I think Firebase really shines, because they have built-in support for what they call intermittent offline. So let's say someone is using our app here, and they're going. And right now, this is actually pulled right from the Android Developer Tools. So this is my actual phone. I'm going, I'm creating some to-dos. It's right over there to Firebase. You can verify that the data is there. I'm just going to go kill my connection, like as if I went in a subway tunnel or something like that. And now I can keep adding to-dos to this application. So it hasn't just fallen over and died. I'm actually still writing to Firebase. But what's happening is Firebase has a local cache of my data. And so as I'm writing to it, it's just caching it locally. It's caching the events and what changed and everything. And I go back and I turn my connectivity back on, and now it's sitting there hitting Firebase, trying to be like, hey, are we connected? Are we connected? And when it figures out that we're connected again, I'm just going to write my data back to Firebase. So it handles that syncing for me. And again, this is like code that I don't have to write myself. I just sort of get this for free from working with Firebase, which is really cool. All right, so we're persisting our state writes. We're saving user data now, which is cool. We can refresh the page if we need to. But right now, everyone's writing to the same location in Firebase, and that's kind of a bummer. I don't really want that to happen. So the next thing I'm going to do is figure out how to differentiate my users. We've got to add some authentication. And this is another area where Firebase can really help us out. So if you go to your dashboard, you'll see that there's a little thing called security and rules. And this specifies who can read and write to different locations in your Firebase instance. And by default, it's just set so anyone can read and write basically to any other place in Firebase. But they have this really nice JavaScript-like syntax which you can use to modify these rules. And so what I'm going to do is create a user's object. And inside of that user's object, for every user's unique ID, I'm going to try to authenticate right there. So I've got this little, you can see where it says rules user, and then I've got this dollar sign UID thing here. So that is a path to a unique ID, but it's a dynamic path. So anytime someone's trying to write to user 1, 2, 3, or whatever, it's going to fill in that value. And then I've also got this auth variable that I can work with, which basically a representation of the currently signed in user. And so I can use Firebase's read and write rules to basically say, hey, the person who is going to try to, or the person who's allowed to write to this node has to be the person who's authenticated with that UID. Now, there's also a method for going through the whole auth pop-up flow. And Firebase supports multiple different OAuth providers. So if I want to pop up a Google sign-in window and I want to pop up a Facebook or a GitHub sign-in window, I can do that. And I can write all this myself. But again, there's an element for that as well. So inside of to-do data, next to Firebase Collection, I can just drop in a Firebase auth element. I can figure it as well. So I'm going to give it the same location. I'm going to specify the provider is Google, because I've got to represent. And then I'm going to give it this user-binding thing. And we haven't really talked about that before, but basically it's a representation of our user, whether or not the user exists in the app. And that information comes from Firebase Auth. And we can do really cool things with this user binding. For instance, if there's no user, we could say, hey, well, let's open a sign-in window and ask the user to sign in. Now, this is kind of an important pattern to pick up on here. Instead of writing a bunch of imperative code to say, if user query selector the dialog, open it, instead of running that, we're taking state changes in our app and we're binding to that. And that's how we're triggering updates in our UI, which is a really nice pattern. Now, once we've heard, hey, there is a user, we can use Polymer's observers to have a user change method say, hey, we've got a user now. Awesome. Let's create a new variable called user location. That's going to be a reference to their specific node in Firebase. And then we can go back to our Firebase collection element and we can tell it to bind to that user location. So now it's just going to write right to that user's spot in our Firebase instance. So this is the same app in an incognito window. And we refresh the page. There's no user. So it opens that dialog window. We ask them to sign in. Don't steal my password. Say, go, they sign in. And now it's off and it fetches all their to-dos from the Firebase instance. Cool. Awesome. So we've handled authentication. The last thing we need to do is host the thing. And this is probably the easiest part of the whole talk, which is great because I don't know. I don't like dealing with pushing the servers and setting all that stuff up. And Firebase makes this really easy for you. They have a NPM module which you can install called Firebase Tools. So install that from your command line. Then you can just go. You can run Gulp because you're using Polymer Starter Kit. And that's going to build a little distribution for us, a little disk folder. Then we can run Firebase init. And that will ask us some questions, like, hey, which Firebase instance do you want to push to? I'm going to say I want to push to my Polymer to do one. Which directory do you want to push? The disk directory I just built with Polymer Starter Kit. Sweet. Let's call Firebase deploy. And through the Power of Timelapse video, we're done. That's it. You can call Firebase open. Open the page for us, and there's our app. Easy. Now, one of the things that I think is super cool about this, and just because we're sort of nerding out for a second, when you're calling Firebase deploy, you can actually go and sort of open up the Firebase dashboard after you've called this, and watch your app deploy in real time. And if you're not stoked with what happened, maybe there's a bug or something, you can just click this button, and it'll just roll back to the previous version. So you get that nice version management set up for free. So problem number three, productionizing the app. Solved by Firebase. Awesome. All right, to wrap up, you want to get rolling fast. You can use Polymer Starter Kit to get you past that blank page problem. Once you're building, keep in mind, you need to be breaking your app into smaller pieces and always eating larger lollipops, I guess. And finally, you can use Firebase to get everything into production. Now, some shameless self-promotion. I do this show on YouTube every two weeks called Polycast. And we talk about things like building your first element or working with Firebase for your first time, stuff like that. So if you're interested in some of the content that you're seeing today at the event, please go check out that link right there. Check out our channel, subscribe to our playlist, whatever. And I just want to say thank you all for having me here today. Thank you all for coming out to Amsterdam. It's been amazing. I look forward to an awesome rest of the day with all of you. So yeah, thanks.