Choosing a JavaScript Framework


  1. Internal Mechanics Let's examine the internal mechanics a little bit. They work fundamentally different, right? They're achieving similar goals, and also, you typically would not want to use multiple of these. You'd want to use just one, because they're scratching the same itch, more or less. So we're going to talk a little bit about what's happening under the hood, right? Just a little bit. Just enough so you can make an informed decision about which one makes the most sense to you and what tradeoffs you're willing to make. So, Angular. Angular achieves two-way data binding, which, for those of you that aren't familiar, is you update something in your code and that value is instantly perpetuated to the UI, and then if you change something in the UI, it is instantly perpetuated to the backend or to your JavaScript's variables, right? So Angular achieves this two-way data binding by what's called dirty checking. Basically, you establish your value, and then Angular's going to perpetually check it over and over and over and over again in this, what's called the digest cycle. Now, if that sounds a little inefficient to you, it is. It's pretty inefficient, right? It's a lot of computational power, but at the same time, we're running on modern machines, right? These machines have a lot of computational power, and as long as you're aware of that and you are aware of what you're sticking to be checked, then it works okay. And the code behind the dirty checking is just totally bananas. It's just crazy. This is actually a real snippet from the Angular code. It says insanity warning: scope depth traversal. This is totally crazy and don't modify it, and we have tests to prove that it does work, so we're sorry. So essentially, some subset of actions in Angular, like changing a variable, for example, will trigger one of these digest cycles, which then checks to see if anything has changed. Yeah, and it's inefficient, but as long as you're keeping up, tracking at least, or at the most, two thousand variables, and none of those comparisons are taking more than 25 microseconds, you're golden. You're never, ever going to see any churn, so I would say for, things essentially short of doing things at Gmail scale, you're typically okay, right? Most times, you're not tracking two thousand variables. Most times, you're just doing simple comparisons. You're not really worried about 25 microseconds, right? Because 25 microseconds comparisons is pretty long, so if you're taking longer than that, you're probably doing something wrong. Questions about Angular so far? All right, let's talk about Ember. Ember achieves two-way data binding via accessor methods. If any of you, and we'll talk about Backbone, obviously, in a sec, but if you've ever done Backbone, it's a similar concept. This is essentially meaning that every time you want to set a variable, you have to call the .set method, and by the same token, if you want to get a variable, you're going to have to call a .get method, and you have to work with these Ember objects, as opposed to Angular. Angular, you're just working with the POJO, right? The plain old JavaScript object. So this allows for very efficient data checking, right? There's no crazy digest cycle. It's really just, you call a .set, it then fires off a bunch of other stuff under the hood, and everything gets updated everywhere. And this also allows for some other cool things, like computer properties. Computer properties, to give you just the dumb example, if you have a square, or, let's just say a rectangle object, and you have a length, and you have a width, right? Any times that the length gets changed, it automatically is going to update your area, as well, right? So it has those bindings to other properties, and it's seamless, right? You can't actually tell that that area is a computer property. You can only see that it's essentially treated like a variable. Naga is wondering if there's any tools for around these projects, like debugging, testing, that kind of stuff, and if you're doing to give in to that throughout the day. There are tools. I'm not familiar with the Backbone one, but I'm positive it exists, but there's Angular Batarang, there's the Ember tools, and there's the React tools. I'm not going to get into them, but they're definitely worth checking out if you're going to do any sort of in-depth coding in these, because it's going to save you a ton of time. It's a great question. Cool. Going back to Ember a little bit. The tradeoff here is that this syntax is slightly less appealing than Angular's. It doesn't allow you to use the cool built-in functions to Angular, right? If you have a collection, there's an Ember collection object, and anything that you want to do, like mapping across it, if you wanted to do MapReduce across it, you have to write that yourself. So it's a tradeoff. Actually, I think Map is built into Ember, but those other native JavaScript functions are not immediately available to you in Ember. Questions about that? Cool. Backbone. Backbone achieves two-way data binding like Ember. The big tradeoff here is nothing is free. Ember, it's free. All that stuff is just totally built into it. With Backbone, you're going to call a remove method and then it fires off a remove event, and then nothing happens. (laughs) So what you have to do is, you actually have to go code up your own methods, right? So it basically gives you here's all the wiring, here's all the events that you need to handle, now go forth and write a lot of code. This is frustrating to set up a new project, because you can just jump into Ember. All that stuff is there. A lot of it's just baked-in. But the advantage here is that you're not going to do anything that you don't want to do, right? Ember is going to do a bunch of things for you, and in case you might want to do things, Backbone, it's really bare bones. It's going to do just what you tell it to do, and so it has the potential to be much more efficient. Please. I heard that in Backbone there's two developers. The way of doing it will be way too different, because there is no framework. Can you comment on that a little bit? Definitely. Just saying that the, there's many different ways to approach Backbone. I mean, I would even just say it's like approaching JavaScript, right? There's umpteen million ways to write JavaScript, right? It's the same thing with Backbone. They give you enough rope to hang yourself, essentially. And we'll find that with Angular, as well. Definitely not with Ember, but Angular is pretty unopinionated, as well. They said, "You're the developer. "You go be efficient about doing things." Whereas one of Ember's core philosophies is you don't know how to do it yet, so we're going to make you do it our way, which, it sounds bad when I put it that way, but I actually think it's a great thing. I've written lots and lots of Angular code, and my early Angular stuff is just awful. It's terrible, because I wrote it in an awful way. All of the Ember code I've wrote has never been too bad, because it's really hard to write bad Ember code, so in team settings, in particular, Ember will shine on that because it's hard. They force you to go out of your way to be stupid, which is cool. As opposed to Backbone, super easy to be stupid, real easy, so just be careful about that one. And someone mentioned that in Backbone, there's tons of plugins that knock back and deal with some of these problems on top of Backbone. Definitely. Marionette. Marionette's probably the biggest one. There's a vibrant community around Backbone, and, I will say, most use cases are going to involve another plugin to Backbone, unless you're a huge company. I know Yammer uses Backbone, and I'm pretty sure they just use vanilla Backbone. But most new projects, you're going to start with something like Thorax or Chaplin or Marionette, or something like that, yeah. Does that answer your question? Yes. Cool. Great question. So yeah, Backbone is easily extensible going along those lines, to the point that you can rip out the view layer entirely and throw in React. It's actually fun. We had planned to go over that today. We're actually going to just do a complete React portion by itself. So we'll talk a little bit, at a high level, how to rip out Backbone views and put in React, but there's tons of great blog posts on it, so I just recommend going through some of those. Cool. More questions on that? Cool. React. So, React is special. It's different from all these because it is not actually MVC. React is just the V in MVC. However, that's most of what we're concerned with in doing frontend code, so it's, the M and the C can be rolled by yourself pretty successfully, which is why we're going to treat it completely separately. So, like Backbone, the data binding isn't free in React, either, but it's pretty easy. It's easier than Backbone, in my opinion. And there actually is a way to do two-way data binding that's actually really simple, which we'll go over later. So the coolest part about React is this idea of the virtual DOM. You have your actual DOM and you have your virtual DOM, and what React does is it takes your actual DOM and then it reconstructs that into this virtual DOM, because the most inefficient part of the browser is definitely the DOM, right? Updates to the DOMs, repaints, reflows, all those kind of stuff really, really inefficient, and you can have just the best JavaScript that's just super-performant, but if you're interacting with the DOM in a bad way, doesn't matter. Your computer's going to go super slow, or rather, your site's going to churn, it's going to jank, it's going to do all those terrible things. So React, in a rather smart way, in my opinion, has minimized your interaction with the DOM so you can just make that as efficient as possible. Yeah. How's that work with screen readers or that type of stuff, accessibility? Are there issues? I think you run into the same issues that you do without it, because that virtual DOM, what it does is it does a diff between the actual DOM and the virtual DOM and then it takes that stuff that's on the virtual DOM, just the most minimal part it can, and puts it on the actual DOM. So if you have alt text and some stuff like that, it just looks seamless to the actual browser. Okay, so it's actually transparent to it? Yes, definitely. Perfect. I guess it does not introduce any new issues, I don't believe. Not that I'm aware of, anyway. Great question. Other questions? Cool. So yeah, this diffing is really efficient, so updates in React are much cheaper than perhaps in these other frameworks because it's very smart about what it updates and it minimizes repaint.

  2. Project Setup So we're going to start off writing some Angular. And let's see here. Let me actually get my... Okay. This is the app we're going to be creating, and we're just, we're actually going to create the same app in all four frameworks. Exact same app so you can get a really good look and feel of how you would approach the same problem with different hammers, I guess. So this is actually completed and working. You can add a new to-do, so you can just click that, adds it. Check it off, it'll apply a different style, right? Move something, clear completed. These can be updated, as well. So, pretty simple, right? The only caveat before I give these is, I believe, this is a really Angular-optimized problem, and this is probably not the most optimized problem for Ember, so I would say take this with a slight grain of salt. Cool. So let's go ahead and start, so it... If you have not yet, go to github.com/btholt/jsmvc-pres. That's where all of this code is going to be and live, so if you haven't already grabbed that, just make sure you grab it. Can I ask you if you're using Sublime or Atom? I am using Sublime. I don't think Atom's quite there yet. I don't think so, either. And I'm just lazy, mostly. Let's be totally honest here. This is just a product for being lazy. Okay, so this particular project is, there's completed projects. That's going to have all the completed code, so if you ever fall behind or you actually want to see how it looks altogether, it's all there. Empty projects has essentially the seed projects, because there's a lot of writing fixtures and writing CSS and stuff like that that I didn't want you to have to do, because I'm lazy and I wouldn't want to do it, so that's all there in the empty projects. I have a bunch of notes up here, and all of my notes are here in the presenter's notes, so if you fall behind, all these code snippets and all that kind of stuff and the order I'm going in, it's all there in the presenter's notes. And then the slides that you saw up there, that's just here in slides.

  3. AngularJS Bootstrapping Let's get started. We're going to go here into the ngTodo. You'll see that ng- a lot in Angular, if you're not familiar with it. That's just pretty much how you're going to know it's an Angular thing. I think they did it just because it looks like Angular, the ng. I don't know. It's kind of dumb. (laughs) Why not stick an A on there? I don't know. Pretty legible here? Yeah, it looks good. I also have some comments in here, so just where you know to stick things because, again, it's easy to get lost. Cool. Well, let's go ahead and start by going to, in here into the JS. We're going to go to app.js. Right now, we're just going to Bootstrap a basic Angular project. We're going to say var ngTodo = angular.module. Here, you can call your app whatever you want. In this case, we're just calling it ngTodo. It does not have to be prefixed with ng. You can call it my awesome, super cool app if you like reaffirming how cool at programming you are. Then we're going to say .config. Function just takes a callback. That's actually just kind of my convention. You actually could even leave out the .config part. This is where you would do app-level configurations. A good example is that I have to play nice with Django templating at my work, so the typical mustache syntax. Typically, you would say. That's weird. I don't know why it does that. That's weird. This variable. That's how you would display it in your template. If you don't want that mustache syntax, you can actually change it to be two square brackets, which is what we do. All that app-level configuration is happening at this level. We're actually not going to do any app-level configuration. It's just good to have for when you do actually need to do it. Save it. We have now Bootstrapped an Angular project. Workshop over. Just kidding. Cool. Let's go to the ngTodoCtrl. As you may have guessed, this is the controller portion. Here, we're just going to create our controller. You're going to do it off of your app. If you remember here, we called it the ngTodo. Here we're going to actually give it its name, ngTodoController, which, by the way, it's actually usually called Ctrl. function Ng. We'll go over this here in just a second. Let me just finish typing it out. Yes. Cool. This is just setting up your controller. You have an entire app on a page, but typically you would have multiple controllers. If you had multiple components going on or something like that, you would have one app and three controllers or whatever. Or if you have different routes, each route is going to have its own controller. In this particular case, we're only going to have one controller. It's going to be this NgTodoCtrl. Bears mentioning that Angular does have a router. The actual official one is actually not my favorite. The Angular UI one is really cool. I'd recommend sticking with that one. Here we're passing it a named function. I actually believe that this bug has been solved, but in the past, you actually had to name it, so I just continue to do so out of habit. Then we're passing here at this $scope. Angular has dependency injection. If you're not familiar with that, essentially what it does, it's going to go in and analyze the name of your parameters. Then it's going to inject the right Angular objects in there. There's another one called HTTP. It's actually going to say, oh, you want the HTTP object? I'm just going to inject it in there. You don't actually have to go call it with those functions. It just does it for you. It's just like totally black magic, so it's really cool, but kind of scary. As long as you know what the proper name of it is. The other thing is we're not going to create our own services today, but you could do MyComm or something like that, your own services, and you can dependency inject them in there, as well. Pretty fun. This is a cool thing because this makes it really testable. (clears throat) In fact, you don't need the HTTP, either, because we're just going to be doing it locally. If you want to test this controller, and you had an HTTP object that was out there making Ajax calls, when you're doing testing, you don't want to actually make real HTTP calls. What you can do is you can pass in a mock. Then it's going to call functions on this mock, and then you can test it that way. It's not actually making real requests out to your database or some crazy stuff like that. David's asking what is your personal preference when it comes to project folder organization. By MVC structure or by functional area? That's a good question and one that I change my opinion on constantly. (laughs) Right now, at this very moment, I'm into the MVC separation. I'll have one of just controllers, one of just directives, one of just services. That seems to be working okay for me. I separate them by app, as well. Don't ever mix apps. That just leads to bad code, which I have also done. Learn from my mistakes. Don't do it. Cool, good question. Other questions so far? Here? The scope object, let's talk about that. Scope is kind of what you would expect of it. You have parents, and they have scope. The children can see the parents' scope, but the parents cannot see the children's scope. You can have a parent controller that then passes that scope down into a directive, so on and so forth. You'll kind of get a better feel for why scope is useful as we're going on. It's kind of a global state, or not a global state, but it's a state within whatever you're working in. Cool. Make sure I covered everything. On our scope object here, let's create our todos. Notice that we're just working in plain old JavaScript objects here, in this case, an array. I go ahead in here. We're just going to put a bunch of objects with val. "A new cool thing", and completed: false. Go ahead and create five objects of whatever you feel like. In this case, I'm just going to copy this a bunch of times. A newer cool thing, this'll be true. A new cooler thing, false. Newer cooler, maybe. You can leave that one false. Make that one, how about that one true? I'll give you a sec to put out your newer, cooler things. We're just going to stick this on the scope object. The scope object is then going to be available in the templates for us to loop over and display. That's one of the key components of why you're going to use this scope object, is if you want it to be available on the templating side, it needs to be on the scope object. Whereas, if I had just done var todos = this array, it would have been available inside of my JavaScript, but it wouldn't have been available on the templates. Make sense? Have you looked at the newer controller as stuff at all? I haven't. Okay, it's pretty sweet. I'll have to take a look. We have our fixtures in place. Cool.

  4. Adding HTML Let's jump back into our HTML. Make sure that you've saved, you've saved your app. Let's jump back into our index here. Let's do a little bit of more Bootstrapping here. On the body here, notice I've marked app right there. You're just going to say ng-app =. Then it doesn't matter what you call it as long as it's the same as the name of your app. I called mine ngTodo. I imagine most of you did, as well. You're just going to stick that there. You're just telling Angular this is where I'm sticking my app. This is where I have scope. It will not have any power outside of your scope. Say I stuck it on this div right here, this ng-app directive. It would not have power outside of it. In this case, our app covers the entire page. That's why we're sticking it there. I've always wondered how they were using that Angular ng-app to grab that element because I thought that, it was my understanding that in HTML, you could only use custom tags that have data pre-appended to them. If you want to have valid XHTML, that's true. However, in HTML5, they got a little bit more loosey goosey with it. It works in modern browsers, essentially. That being said, I believe you can append x-ng, and that would actually make it valid even in the older specs, as well. In fact, I even think data- works, as well. I would need to check that. Data, I've seen data before. All three of those work. Because we're just concerned right now with modern browsers, it's good enough just to do this, but that's a great point to bring up, for sure. Other questions? Cool. Tony's wondering if you can use single or double codes. I don't know if that matters. Doesn't matter. Cool. That's where we're going to have our app. Now let's actually give our power to our controller. Got the ctrl right there. We're going to do ng-controller. ngTodoCtrl. Pablo is asking why, how does Angular know how to look for ngTodoController.js file? Oh, it's because it's already included down here in the bottom. I already include all of your files for you so we don't have to deal with that. Then it knows to look for it because that's what we called it right there. Does that make sense to people? Let's go back and just reaffirm that point. Oh, yeah, no. This should be capital N, sorry. So we have NgTodoCtrl. That's what we called it here. Then here, we told it when I ask for the NgTodoCtrl, this is the controller I'm asking for. That's how that gets magically wired up. Does that make sense to people? I take that as silent compliance. Actually, I have a question. Can you flip back to your controller? Is the lookup based on your quoted name that you're passing as the first argument or the name of the function there? That's a great question. It used to be a problem that if you just did this, and did not do this, it wouldn't find it. I believe they actually have solved that issue, but I just always call it the same thing. I think you could actually just do this, and I think it still works. The whole answer to that is I'm not sure. Yeah? Francisco's asking your opinion about creating controllers using constructor functions, separating the code by creating methods on the prototype so you can easily extend the controller. Not a fan, personally. The reason being there is that if you have functions or things like that that you want to share across multiple controllers, those are best separated out into a service, which we'll get into later, either as a service or a directive. There are other constructs in Angular that make sharing code easier and more intuitive and easier to follow than doing prototypal inheritance. Definitely. Good question, though. You don't need to define the function name. I just checked that. You don't? Thank you for doing that. My other question is how do you include all these scripts in production, personally? How do I include it in production? Use require or something? We're moving to Browserify. It's a little interesting with Angular, but it works. Require works, as well. You're also welcome to just do that, as well. All of the above work, but personally, we're moving to Browserify. Good question. Other questions? Cool. Let's keep going. We're putting the ng-controller on this section right here. As I was explaining with the ng app, it now only has scope inside that section. Outside of it, it has no power. You cannot call its functions, you can't access its variables. If you want to share it, you have to find other ways. Cool. Let's go to. Let's look a little bit at the power of the two-way data binding here. Here on, where we have New Todo. Model, right there. Line 25, at least in my code, you have this new New Todo. It's an input, should be. We're going to put here an ng-model = "newTask." Doesn't matter the order. Doesn't have to be the first attribute. It could be the last attribute. Whatever works for you. Now we have two-way bound this input right here to a property called newTask. The fact that it doesn't exist already doesn't matter. It's automatically bound to that newTask variable. Anywhere now inside of our JavaScript, we can refer to newTask, and it's always going to refer directly to that newTask input. In fact, just to demonstrate to you, we're just going to do this mustache syntax right here. I'm going to put {{ newTask }} just immediately afterwards or wherever. We're going to take it out here in a sec, so it doesn't matter. Let's just save that and move over to our browser. I need to change this to be empty. Now we're actually into. Cool. If we start typing in here, it's just going to start immediately putting it out right after it. Or we can delete it, add more things. Super cool, right? It's just instantly bound. Anytime you change it, it's instantly going to perpetuate. Pretty sweet, right? Even to take that, again, just a little bit step further. Save that. So take out that newTask because it makes it super ugly. (clears throat) Let's go back to our ng Ctrl for just a sec. Just to prove a point, we're going to say scope.newTask = "An initial." If I can spell. This is not a spelling workshop, by the way. Whatever you want. I just put initial value. Now when we refresh the page, it actually now has an initial value. It's bound both ways. Is that pretty cool? This is the power of Angular. This kind of stuff is just deadly simple in Angular. Let's get rid of that. We don't need it. Cool. Cool. Someone's saying it printed I'm assuming there's some sort of JavaScript error. Could be a JavaScript error. Could be that they didn't initialize their app or they didn't initialize their controller. It's essentially saying that Angular is not running over that piece of code, for whatever reason. Is everyone in here having a good time with it? If you're having issues, please stop because I'm sure that means other people are having issues.

  5. Looping with ng-repeat Let's go over the ng-repeat. Line 33 here, it's got a nice little repeat thing right there for you. Admittedly, this is the part of Angular that just made me fall in love with it. This is like, okay, this is kind of weird, but I'm going to learn how to do it because this really makes my life a lot easier. ng-repeat. todo in todos. I will take this opportunity to say this is one of the reasons that Angular feels a little weird to a lot of people. It has a lot of domain-specific language. In this particular case, what this todo in todos mean. It just looks like nonsense. It's a for loop, essentially. You're looping over a data structure, anyway. So you have todos here. Todos is actually the name of the variable that's on your scope. In this case, we have the todos, those fixtures that we created. Here we're going to loop over it as many times as there are elements in there. We're going to call each one a todo. This could be anything. We could call it X or whatever we want to call it. I call it todo for, I would say clarity's sake, but it looks really (laughs) close to todos. I call it todo out of habit. Let's even just save it and run it again. Now we have a bunch of them. Not very useful because there's nothing. I don't know why there's X's. That's weird. They're marked true. Are they? ng-show. I don't know. In your controller. Does everyone else have on line 40 an ng-show? Yes. Take that out. (laughter) I think I was probably demonstrating to another workshop, and whatever. Anyway, we'll go over ng-show later because that's kind of fun. Cool. We're here on ng-repeat. Does that make sense, what's happening here? This is, in my opinion, one of the most awesome features because how many times in jQuery have you looped over a status structure and appended a child? It's just stupid, hate it. Love it, love this. This is great. Cool. Let's go ahead and just make it actually show all the right values and such. Here we're just going to do the ng-model again. This is going to be todo, referring to this todo right here, .completed because that's what we called it in the title of our little data structure. This is line 35, by the way. I guess I can get rid of. Oh, it's okay, we'll leave it. We're going to put an ng-model here, as well, and call it todo.val because that's, again, what we called it already. Now we're going to do another new one for you. It's called ng-class. This is going to be an object. I always get the order mixed up, so bear with me for a second. I believe it is what. We're going to give it a finished class. If it is todo.completed. I might have to go back and flip that, but I'm pretty sure that's the order. Again, it'll have the finished class if the todo is completed. It just takes some truthy or falsey statement as that second statement to evaluate that to see if it's true. Yeah, let's just go ahead and try that. Pretty cool, right? Someone just commented that, also, from an efficiency perspective, in the ng-repeat, if you add new things, it doesn't re-append everything. It only appends the new thing. Yeah, definitely bears mentioning. If you're operating on that todo or that todos array, so you add three more, it's smart enough not to go back and re-add everything all over again. What it's going to do is it's just going to append those last three. It does aim for efficiency. You can probably even do it here. Whatever. But we'll see it here in a sec, that if you change that todos, it's going to update on the fly just for you. You don't have to say, "Hey, I changed stuff. "Re-render yourself." It just does it for you with its Angular magics. Again, you can click these check boxes and it's going to apply and unapply that style because of that ng-class directive. Let's go over, in my opinion, one of the dumb parts of Angular, that they could have figured out. They use all these fancy, stupid words like directive or transclusion. It just sounds like a bunch of Ph.Ds. That's probably what they are. When I say directive, this ng-model business right here, that is a directive in Angular terms. It's an attribute that you are applying to something on the dom. In this case, it's an ng-model directive. These attributes, I don't understand why they couldn't call them custom attributes or something else like that, these directives just look like that. As you can see, they can be combined. This is one of the powers of Angular, is these mix-ins. That's a good one. HTML mix-ins. I should write a framework. (laughs) ng-model, ng-class, those are directives. They can be combined, lots of other cool stuff like that. Questions? Pretty clear so far? All right, let's keep going. Let's go actually add some functionality in. Right now, we're just checking and checking off, and it's kind of cool. Something else that does bear mentioning, you can delete these things. We're not really doing anything with them right now, but they actually, the data is changing behind it, as well. That's pretty cool.

  6. Adding Interactivity Let's go back to our NgTodoCtrl. Let's go ahead and throw some functions on here. Let's just do an addNewTask. That's a pretty easy one. addNewTask. Function. We're sticking it on the scope. This is for the same reason. We actually want to be able to call this function from the template. scope.todos.unshift, or you can put push, as well. That's totally fine. completed: false. When you add a new todo, you're not going to be adding a completed task. That seems rather silly to me. val:, and then you're going to say scope.newTask. Then after we do that, we're just going to say scope.newTask = blank because you're going to click add new todo, it makes sense that you don't want to re-add the same todos, so you want to just blank it out. Let's go back here, check it out. Get this new task business going on. Say New task business. It still doesn't work, right? The reason why is that we actually haven't bound it to the button yet. Let's go back here. Oh, sorry. Is someone talking? Sorry. All of my tasks disappeared when I reloaded that. That's problematic. I probably just didn't type it right. Let's see. We'll leave that there for just a sec. Now we have to actually bind to add a new task. Let's go back here to the, let's remove. We want to add task. That's at the top. It's right here. This button right here, we're just going to add ng-click =. What did we call it? addNewTask. That ng-click directive just accepts a JavaScript expression, and it's going to evaluate what's ever in there. In this case, the expression we want to evaluate is on that scope object. We want to call the addNewTask function. Let's save that. Come back here, refresh it. A newer task. Pretty cool, right? Just adds a new task. Does that code make sense that's going on here? This unshift is just an array function. Again, you could say push. The reason why I chose unshift is it adds it to the top, as opposed to adding it to the bottom. Whereas, if you did push, if you just saved that and went back here, as you might expect, this is a new task, it's just going to append here to the bottom. It's going to maintain that order for you, as well. It's pretty nice. Let's see who has unshift because that's fun. Other questions? Did you sort your stuff out? Yes. Cool. Let's go ahead and do a clear completed because that's another easy one to knock off down here at the bottom. Clear completed. Just going to add another ng-click here for a clear completed function that we're about to write. Let's go back in here. scope.clearCompleted = function. This is pretty easy, as well. We're just going to use some more built-in JavaScript functionality. This is, again, what I was talking about with Angular. Just super cool because you can use all this built-in JavaScript functionality. You can use other libraries. If you wanted to use underscore or low dash or whatever you want to call it these days, or anything else like that, it's all available to you because it's all just operating on normal JavaScript objects. scope.todos.filter. Again, this is an ES5 built-in JavaScript function. I think here it takes element and index. I guess you don't even need index, but we'll put it in there for clarity's sake. I'm going to return el.completed. Think. Make sure I get that right. Yep. Again, what's happening here, we're just running a filter over the todos. If the todo is completed, then it's going to return false, so then it doesn't get re-added back to that new array. They're just assigning that back to todos. That make sense? We following? Let's save that and give it a shot. Make sure I saved my index, I did. So I click clear completed, I should expect this one, this new cool listing and a newer cool thing to disappear. Voila. Is that working for most people? All right, awesome. Let's go back to our code. I got the opposite effect. You got the opposite effect? You have bang el completed? Oh, nevermind, syntax error. Okay. That's kind of fun syntax error, though. Take everything that you should do away. That's what I want my todo list to do. We still have one more button here. There's a couple ways we can do this for this button right here, on the remove individual one. No matter what, we're going to do ng-click. I'm going to lead you down a potentially dangerous path, and I will let you decide how dangerous it is. You're going to say todos.splice($index, 1). I think that's it. This just takes a JavaScript expression, these ng-click directives. You can stick anything you want in there. This is dangerous because this actually works, but you're putting a lot of functionality into your template, and you're taking it out of your controller. I would personally recommend against doing this, but this is just to demonstrate to you that if you want to do this and you want to make yourself cry in the future, then you're welcome to. I believe that should work. Oh, $index, that's worth explaining, as well. There is some hidden variables that are exposed to you. In this particular case, we're just going to be slicing out that index of it. Excuse me. That $index is just the counter of where you are. In this particular case, we're going to be removing from todos that particular index. Does that make sense? Is that $index, is that only work in the context of todos? Or if you have lists of lists, how do you get? That's a good question because you can have that. I believe the answer is there's a dollar sign parent that you can use. $index would refer to the specific one most local to you. The $parent would just keep going out. Now, let's see if I've made a fool of myself. Hopefully that works. Let's make sure. I should remove a newer cooler thing. Yeah. Questions about that? Does that just seem like black magic and really dumb? Let's just refactor this to how I think actually you really should do it. First of all, how we doing on time? Pretty good. We're just going to run that off and we're just going to say removeTodo. Then we're just going to pass in the function. You can either pass in index. That's really easy. Let's just do that. removeTodo. Then we're going to come in here to this. We're going to add another function here. Say scope. Let's roll up a little bit. scope. There we go. removeTodo. It's going to take in an index. Then we're just going to do that. Just do that todos.splice(index, 1). Save that. Make sure I called it the same thing. removeTodo($index). Oops. Let's go back over here. So, a bug. I don't remember what I did, so let's take a look at the JavaScript, or the error. Unexpected token. One of the neat functions of Angular is they actually have error pages. It gives you this URL right here that you can click on and say this is why I'm crapping out. You can go check it out and see what they have to say about. In this particular case, this error's actually more useful, that I have a bad syntax. Error syntax, line 22 in my controller. I don't know, that was dumb. That = function(index). Sorry. Let's close that, refresh it. Still getting errors. You have to add scope to your function. Scope to that todos. Thank you. The dangers of live coding. It's all right. We got your back. (laughter) Yeah, you do. All this is going to be edited out. I'm going to look like a genius. Just kidding. Cool.

  7. Angular Extras We have now written an entire Angular app in an hour. Super cool, right? Pretty easy. How do you feel about it? Good, bad? It was pretty cool. I see some head nodding. That's good enough for me. (laughter) I like how you can just kind of build straight from that HTML with a couple of JavaScript files, whereas maybe other frameworks might make the process a little more cumbersome to get started. For sure. Here, you can just put a tag. It's just like using jQuery or something. Definitely. I'm going to go out on a limb and say that working in Angular and Ember, particularly, if you want to build a rapid prototype, you just want to get it out the door right now, you really can't beat those two. They're super fast at writing up new code. I would say Angular goes even faster, but I would say Ember is probably better long play. Depends. That's personal, off-the-cuff opinion. Take that with a couple bags of salt. Definitely. They're both really, really fast and productive to work in. We might come back to this. If we have a little bit more time, we'll go over some custom Angular directives. I'll show you, there's a bunch of directives, as well. I've just scratched the surface of even the ones that Angular exposes to you. That one that you removed earlier, let's just go ahead and put it back. ng-show= todo.completed. As you might expect. Now if you add these in, the X will show. At least I am. I'm constantly showing and hiding divs. This make it just trivial to do it. If you wanted to do the negation of it, as well, like ng-hide works, as well. There's umpteen billion. Another cool thing is you can make your own directives, which is really cool. If you wanted to say, I don't know. If you wanted to change the color of the X based on the thing was completed or not, it's trivial to do with an Angular directive. Cool. I was going to show you just what a filter is really quick. Let's go back up here to the add newTask. Just underneath it, like we did before. Let see, where were we? Whatever. Wherever you want to, really. We have this newTask. Then if you can put a bar. Then you can put a filter afterwards. In this case, I think it's upper case, if I remember correctly. Let's just give that a shot. No matter what, this is a new thing. Notice that it's getting printed out with all upper case. That upper case one just happens to be built into Angular, so that was an easy one to do. If you want to do format for currencies, there's one for that. If you want to do i18n, that's the internationalization thing, you can build a filter for that. You can write everything and say just run this through my translator. It works. Lots of cool things you can do with filters. You can define your own filters. You can use them programmatically, as well. Those are the fun parts of Angular. Cool. Any questions about Angular before we move on? We can always revisit them. All right. Let's just get rid of these. We're going to move onto Ember. If anybody need a break, (mumbles). Please do. Let's keep rolling. All right. I have one question real quick. In most of these languages, or these constructs, is commenting out, is it just the same as HTML, nothing special? If you want to comment out your mustache code, you just use regular HTML comments? Yeah, in fact, let's give that a shot. Just whatever. Just change one of these. This would be newTask. Now, the question is does it get compiled? I'm not actually sure. It still works. It's not there, but I'm not sure if Angular will actually run it through the compiler. My guess is not because my guess is that they exclude comments. That's a gut feel. One way to find out. Yeah, totally. (clears throat) Cool. Good question. Concerns about throwing logic in the HTML? Do I have concerns about that? Someone. Someone does. Just check. No. Totally valid concern, and it's probably, in my opinion, the most valid one you can lever against Angular is it's very tempting to put a lot of logic in the template. It's tempting to do a lot of tightly coupling of your template to your controllers. Really, the idea of Angular is to separate that out. Angular is not going to make you code one way or the other. I think we went over this a little bit already. They give you enough rope to hang yourself, definitely. It's up to you to observe best practices. In my experience in practice, it seems like with all the frameworks, that it's always a problem, coupling things to the view. It is, for sure. It's a perpetual JavaScript problem. Backbone apps. There's so much stuff in the view a lot of times. Same thing with Angular, same thing with a lot of different code bases I've seen and production. Poorly written Backbone might be the worst thing in the entire world, possibly. War is right up here, and then poorly written Backbone. No, I'm just kidding. That's awful. But yes, it's really hard to separate those out, and it's really up to you as a programmer to observe those best practices. We're going to see here with Ember here in a second, it's actually really hard to break out of best practices, which is nice. What's your opinion of Angular's dom templating language versus string-based templating languages like mustache? When coupled with Angular, they're very pleasant to work with. It's very fast and easy to work with. I don't have any problem with it. It's worked pretty well for me, anyway. We're about to get into Handlebar, so you guys will get the chance to make your own decision about that.

  8. Angular Directives Let's talk about some more Angular stuff. We're going to jump back to the Angular project. Let's talk about directives first. I've just put some more code in here during the break, but we'll talk a little bit about it. Here at the top, we're declaring that we're creating yet another Angular module. This one is separate from our app. Reason being is that if, say, I create 10 apps and I have this directive that's just kind of general purpose, in this case, I can stick them, the multiple directives on this StupidDirectives module. This one, I've created one that's called completedColor. This right here, this empty bracket, it just says that it has no external dependencies. You'd put external dependencies in here. Say you were creating some cool date picker, and it depended on moment. You could declare that dependency in there. This is the name of it. I've called it StupidDirectives. If we had multiple directives, we could kind of package them together in the StupidDirectives package. Then a lot of times, actually, we'll just do this for clarity's sake. Let me just indent that a little bit more. You have this directive called completeColor. What it's going to do is it's going to change the color of that little X, depending if it's completed or not. We're doing the restrict here. This is another event. Just a dumb thing about Angular is that what does restrict A mean? It's not intuitively obvious. What it means is this can only be an attribute, which is what A. There's also E for element and there's one more I'm not thinking of right now. N for comment, I think. That sounds right. I believe you. No one uses it, though. A and E. A and E are the ones you're going to use most of the time. If you actually want to have a whole component, then you would make it an element. You can also have it be A, E. It can do both. We're defining this link function right here, which is just saying any time that that's being rendered, this is how you render it, or this is what it does, rather. We're doing a scope.watch. Yeah, it gets scope element in attributes. Scope is when we're talking about scope. Element is the element itself. The attributes are the attributes being passed in. In this particular case, we're actually not going to do anything with the attributes, but you could tell what color it should be or something like that. Is that element, is that a jQuery element or is that a JavaScript dom element? I think it's going to be a dom node, yeah. That brings up a good point. Many of us come from jQuery backgrounds. This is just on a tangent. It's really tempting. I know how to do this in jQuery, so I'm just going to do it in jQuery inside of Angular. It's a really bad anti-pattern. It's going to make your code really bad, unreadable, unmaintainable, untestable, every bad word I can think of right now. (clears throat) You can do it without jQuery, so do it without jQuery. It's going to take you longer. You're going to bang your head against the wall, and it's going to be worth it. Just don't use jQuery at all. Say if there's a cool jQuery plugin that you want to use with your app, you can wrap it in a directive like this and then use all the functionality around it. Then that becomes testable, reusable, all those good things. Ben commented on chat that he thinks that element is wrapped in jQuery Lite. Okay. That might be true, or that probably is true. Cool. Quick question. The in your wrapping up jQuery within Angular, is that true for the other libraries, as well, other frameworks? (mumbles) Do jQuery? They have their own patterns for plugging in jQuery because that's what everyone wants to do. There's a thousand jQuery plugins out there that are all still useful. They all have their own patterns for wrapping it. I've never done it in Ember, so I'm not entirely sure what the process is for that. Probably has something to do with components or with doing it in the view layer or something like that. Cool. Inside this scope function, we're defining a watch, or, I'm sorry, rather inside this link function, we're defining a watch. This is kind of like that object observe paradigm that you're seeing. Anytime this attribute of completeColor changes, it's going to be either true or false because we're going to make it contingent on our completed. Anytime it changes, run this function. That's all that watch does. It's expensive, so be careful with it. That seems like a really cool paradigm. Anytime this changes, run this function. That's really exciting, but it's also a little scary because it can be quite expensive to do. In this particular case, our completed doesn't change that often, so we're okay with it, throwing that around. Here, we're just going to change the element css. It's either going to be yellow or green, based on if it's true or false. Let's just save that. We're going to come over here, and we're going to need to, in our app right here, we're going to put in StupidDirectives here because now that's a dependency. StupidDirectives. You didn't have the I in it. (speaks too low to hear) What did I do? StupidDirectives. In in the other file, you didn't put stupid. Good call. StupidDirectives. Also, I think you don't want that semicolon after the link function. This one? No, no. One more. It's fine. Yeah, that's for this watch right here. I see. Cool. So now we have that StupidDirective. That's now available in our app. Now we can come into our index.html down here. We're just going to throw it on that X icon right here. Not the plus, we want the X. This one right here. I can't even remember what I called it. What did I call it? completeColor. complete-color. Angular assumes that in your JavaScript, you want to do camelCase. As an attribute, you want to do dashes. Then you're just going to put an expression in there. I believe that you're just going to do todo.completed. I think that's right. Let me make sure that's right. Let's give that a shot. Now when you change it, it's going to change the color of the X. Now, why is this cool? It's actually really annoying right now. Who wants to change the color of the X's? Let's say that we also wanted to change the color of our text, as well. That StupidDirective can be re-used in multiple places. It's kind of an interesting mix-in for the rest of the app. Questions about that? Directive are really powerful. It's probably one of the most compelling reasons to continue using Angular.

  9. Angular Filters Let's go ahead and do filters now. During the break, I just threw together this Angular module right here for stupid filters. Remember when you used to do MRC or old (mumbles) school IRC or Telnet or stuff like that, and you used to type in alternating caps because that was awesome? Well, I brought it back. That's what this business is right here. It does alt caps for you. Filters are a little bit more simple. There's none of that linking business or anything like that. Again, I'm just packaging it up into StupidFilters module. We could actually put these in the same module if you wanted to, and StupidThings or something like that, but didn't. Here it's going to be a function that we're going to return that takes an input. Then all it's going to do is just go through, alternate, and make things caps and not caps. The JavaScript there, it's a little clever, but it's all just raw JavaScript. It just breaks it up into pieces. Then every other one, it turns into caps or lower case, and then just returned the joined array. Let's grab StupidFilters here. Sounds like I hear some more keystrokes. I'll let you guys finish. It's kind of an off comment. When listening to Misko and podcasts, and also when he was here, he started building Angular for the directives piece to actually extend HTML. Then all the architecture-type stuff came in after. Those are just normal (mumbles) services and all those kind of thing. Definitely. It started as-- For the directives. Yeah, directives thing to extend HTML, for designers to extend HTML. Then sort of everything else extended from that. We built those layers on top of it. They're a little intimidating. I said it has the restrict A. There's a little bit of intimidating elements about them, but they're worth banging your head against to grasp, if you're going to be an Angular developer, for sure. Let's just go ahead and apply this now. Again, we need to have, we need to make a dependency here for the StupidFilters. Let's go ahead and save that. Now that's available to us on our index.html. That was in the app.js, by the way. Let's just go back to what we were doing before with addNewTask. We'll just put it here underneath. It's like newTodo. That's what I called it. No, I called it newTask. Sorry, newTask. Then I'm going to do alt caps. You remember, that's the syntax for applying a filter. It's just going to know that alt caps is the thing that you've done because it's already been included through that dependency that we showed. Let's go ahead and give that a shot. It was undefined because we didn't initially define it, whatever. This is super cool and I'm a hacker because I can type like this. That's essentially the most useful thing you can ever do with programming. This is the achievement of mankind. (laughter) Just kidding. But while this in particular is really, really stupid and only serves to annoy people, you can see the power of why this could be useful. Currency is a really useful one. We find ourselves displaying currency all the time. That's actually baked straight into Angular. You don't have to write it yourself, which is really nice. This doesn't even have to apply just to strings. It can apply to numbers, it can apply to arrays, it can apply to objects, anything that you want to feed into it and get something out of it. Anything that could be filtered or sorted. There's a lot of them that you can do sorting. Say I wanted to sort these. I'm not sure if I'm familiar with it off the top of my head, but let's just try. There's the ng-repeat right there. You can do sort: todo.completed. I think that'll work. Nope, screwed it up. Yeah, it really didn't like that. Maybe just sort. No. I don't remember off the top of my head, so we'll just pass on it. Say you wanted to sort all of them by alphabetical order or date added or some other thing like that. Those filters can also be applied for sorting purposes, as well. I think if you actually go do the TodoMVC.com version of Angular, they're actually not hiding. In this case, we're just throwing away completed todos. What they actually do is they just hide from you that, so that's another thing you can do with filters. It just won't display anything that it's not completed. Cool. Do you have any questions about directives, filters, services?

  10. Angular Services What's great about services is that. Let's see, so we're in controllers. ngTodoController. This scope right up here, that's dependency injected. You can write your own services. Say, for example, you're doing a lot of things with currency or something like that. You could create a service that does all these translations and other fancy things with it. You could create your own service that then comes in. For our Black Friday sale last year, I created a local storage memcache imitator because we wanted to pre-cache everyone's data for all the flash sales so that when they hit our servers, they wouldn't just die. They just wouldn't even reach out. They just grabbed out of memcache, their local memcache. So I went and wrote a service that then was injected in here, that it would go out and check their local memcache first to see if they had data. If they did have data, it wouldn't even reach out to the server. It would just grab it out of their local memcache. That's a powerful reason to use services. We saved ourselves a ton of server traffic just by that one little tweak. It's reusable, as well. It was generalized so that if it didn't. We've used it in multiple places, not just our flash sales. Questions about that? Cool. Sorry. Yeah, go ahead. For this service sort of thing, what would that actually look like when you're doing that? (mumbles) Let's see. It's going to look really similar because you're going to package it in a module. The other thing is you actually don't even have to, you could actually do ng-Todo. You can do directives straight off this. You can do directives just like that. I think it looks like this. Function. It looks really similar to how you instantiate. I'm really hesitant to show you because I don't remember off the top of my head. Can you just put a name, service name, and then function? Oh, yeah. It's going to be like memcache or something like that. I think this is what it looks like, typically. Then you return an object. Double and triple check this, but this is just from memory. (speaks too low to hear) (clears throat) You return an object. The object is just. What's the fancy word? Singleton that you can then just operate on. What you'd do is you would have a function that would say get. Then it would return thing. Then you would have set, and be function (index) or something like that. The most common reason to use one of these is reaching out to your API. It's a really compelling use case for one of these. Looks something to that effect, like that. I don't know why I put an extra dot in there. In chat, people said that it's order by, and not sort. Order by, damn it. When you were trying to do. (laughter) While I was trying to sort the array, it's the order by. This was asked in the (mumbles). I was watching the videos, but service versus factory. That's kind of a new argument that I've seen emerge. There's another concept in Angular that I'm not going to talk about because I actually don't know hardly anything about them. They're called factories. It's something that you would use instead of using a service. They kind of achieve the same goal. I think they even look and act really similarly. Maybe some homework for you. I think there might be actually. I think this was discussed by Lukas Ruebbelke when he was here. People asked services versus factories. Then we also have a PDF you can download with that same question with his answer. Look at the AngularJS In Depth workshop with the PDF. Download it. Definitely. If you guys want to go deep dive into Angular, there's just. I showed you the code. There's just crazy corners and crazy cool stuff you can do with it, but it gets pretty, it can get pretty hairy. (laughs) Something cool about directives. Probably the most in depth I'll talk about is transclusion, which is kind of a fun thing you can do. You know how I was complaining they call it directives and services? Transclusion. What is transclusion? All it is, is it's essentially allowing a child to display its parents' scope. A really good example for this is modals. You have a popup modal. You don't want to actually do all this fancy passing around of data. You just want the directive to be able to see into its parent and display what the parent has. What you're doing is you're transcluding scope. If you create this modal, you just do a little bit of your text in there. Then you put your variables just directly into your text that you're feeding into your modal. Then it can transclude its scope. It can see into the parents' scope and grab all the necessary data and text that it needs to display. That's all transclusion is, but it's really cool. You can create general purpose widgets, like modals and anything else that you would have to see into your parent for. This obviously won't make any sense, but all you have to do is say return. Right here. You'd say transclude: true. Then it would just start doing it. That's all you have to do to make transclusion a thing. This wouldn't do anything because we're not really transcluding to look into our parent, but we could.

  11. Ember Bootstrapping and Controllers Let's close all these files out. Move my browser over here to... You can just change this N G to emb, E M B. Got a nice little Ember up there. Same sort of thing. So, let's get this going. Don't know why this printed out so small; it's annoying. All right. So, we have the index here. Let's just go ahead and open our app.js. Let's go ahead and talk just a second about dependencies. Yeah, I think we're okay. Yeah, we're good. Ember has dependencies on Handlebars, on jQuery... That might be it. Yeah, so those two have to always be present and declared before Ember starts. Angular has no dependencies. Angular actually will use jQuery if they have that on the page, but they have their own jQ lite that they'll use if it's not there. Backbone depends on Underscore, jQuery... That might be it-- and, yeah. I know that in Backbone, you can use what, something like zep-tan? Which is lighter than jQuery. And there's a lot like-- Does Ember work with that as well? My guess is probably not, but I'm not sure. I haven't-- I don't know. Maybe. a complete displacement of jQuery; it's just a small-- That's what I'm saying. Yeah, I don't think that Ember supports that. It's worth looking it up. Yeah. But I would speculate not. Okay, let's go ahead and jump into app.js right here. It's going to be pretty simple. Going to throw on the window.Todos = Ember .Application.create, lower case. Okay, you're going to see this pattern a lot of Ember .something .extend, or .create. It's very, very common to see that. Ember's pretty verbose with their names. I think it's good, because at least the clarity makes it more maintainable. I know, as programmers, we're like "saving keystrokes saves lives," right? But, in this particular case, I think it's a good thing. Okay, that's it. Congratulations. You've now written your first Ember app. All right, let's go to the router. As you noticed with Angular, we did not write any sort of routing whatsoever. Ember, it is baked in, it is core, it is absolutely essential. If you do not write a router, you do not have an app. So, let's go ahead and write a router real quick. So we have this Todos, which is what our app is called, .Router.map(function) Okay, this.resource('todos'.) And just, this is like a customization options object. So, here we've designed-- Just created one route throughout, is the Todos route; and the path of that ('todos', {path '/')}; One thing-- another thing you're going to see throughout Ember is it's always going to try and take its best guess at what you want. This is definitely a convention over configuration idea here, so if we did not define that path, it would assume that our path would be slash to do's. So, both good, scary sometimes when you don't actually know it's being done for you, because it is doing a lot of work under the hood; but once you get the hang of it, it's very productive to work in. Is there no config flap here, like with the app? No. You would do it probably just on this to do's object. That's the first place you inject anything? Mm-hmm. Good question. Okay, so we're going to do Todos.TodosRoute = Ember.Route.extend We're not actually going to put anything in here right now, but this is where all of our route controller objects are going to be going, just right in here. Um, yeah. The Ember router is awesome. Like, I'm a huge fan, and I know the guys at Angular for Angular two-oh have taken a long, hard look at what's cool about the Ember router, so. They have some good stuff going on here. Uh, yup. Did that. So, yeah, this convention over configuration stuff, it's great for advanced programmers. It's kind of (blank)y for people just starting out, because you look at it like, "Where did all these objects come from?" Right? Like "Well, who created that to do's route object? "I didn't do that." I guess you can have it right there, but you'll see the to do's controller. It already exists; you already instantiated it, and you don't even know it, and it's crazy, but it's cool, because it cuts down that boiler-plating a lot of code, so. So there is a route provider in Angular? Mm-hmm. Is this through-- I mean, how do you just compare it to this thing? You just have it right away? There is a route provider. It's actually a separate module completely than that used to dependency inject the-- N G route, yeah. Yeah. And you just mess around with that. This is just like, baked straight into the core, right? You have to define it, or else it's just not going to work. Cool. Yeah. So, let me just go ahead and say that even if you didn't do this Ember.Route.extend that Todos route would actually still exist, because Ember instantiates it for you with that name. Because it's assuming that "You call this to do's, "so I assume that you want to call it to do's route;" because a normal, sane person wants to do that, and if you're coding in Ember, we assume that you're a normal, sane person. So they just follow this naming convention, and they expect you to just follow along with it. I'm not even sure if you can overwrite it. If-- it would be difficult to overwrite, and that's kind of what I'm going back to. Like, it's hard to write bad Ember, because they make it really hard to override their good thinking, right? It can feel a bit heavy-handed, which is-- To some, you know, that's a valid thing that you can say about Ember; but at the same time, I think it's good. I personally find it appealing, so, for whatever that's worth. All right, so we have saved it. You can go check the page. The page wouldn't have done anything yet, so, let's just keep going. Let's go to the model, modelset.js Ember has schema, so, I believe it's the only one that has schema. Yeah, so it's the only one that's going to enforce schema. You can actually make Backbone enforce schema. It would be a pain to do it in Angular, wouldn't recommend it; but Ember, it's just baked right in. Also bears mentioning, we are using Ember Data as well. It's an optional part of Ember. Can't see why you wouldn't use it though, so. I like it. So Todos.Todo = DS Any time you see this D S, that's referring to-- I believe it's data store, is what it stands for. But that's the Ember Data part of it. DS.Model.extend() Okay, and then we're just going to give it-- It's going to have a val, right? Just call things the same, to keep it easy. It's going to mean a string. Completed. I believe they just call it a Boolean, right? Yup. There it is. Okay. That's it. That's how you define your schema for your model. And, pretty simple, right? Just to-- a quick detour here. Rather than have you type up your fixtures again, I made them for you. This is just not-- this is just something I wrote to speed up the thing, but if you look into your fixtures.js that's what this is. Like, it's just-- oh, you need an ID as well. Ember requires an ID so you can have something to key off of. So. Cool. So Angular provides that for you, on an array. The ID? The index, or whatever. Yes. If you-- just a sec. If you loop over... If you try and do an N G repeat on something that has duplicates, it's going to yell at you. It's going to say, "I have duplicates; "I can't tell what's unique," so then you have to say like, "Key off of index," or "Key off this other value," or "Key off this value pair," right? So Ember, it just says like, "Screw you. "Use our ID system, or don't use it." So. Thank you. Yeah. Yeah, go ahead. other models with attributes?" I'm assuming he's talking about mex-tin-- Models and stuff. Yeah. Totally. That's a good question. Anything I tell you, I would just be guessing. I'm not entirely sure, but I know it's possible, so I'll just say look it up. I'm not sure what the uppercase fixtures is in this. Is that some kind of magic constant or something? This Todos.todo.FIXTURES? It's something that I invented. It's a Brian Holt invention. It's not a part of Ember. I did it just as something easy, so that we can loop over it.

  12. Controller So let's go back to our-- Or let's go to our controllers. All right, so. Todos.Todo = DS Oh, sorry. I got the wrong one. Todos.todoController = Ember.ObjectController.extend Okay, we're going to put an actions thing in here right now. Or actions, sorry. S. Not going to put anything in there yet. That's the place where you're going to essentially define the actions that can happen to the object. And, yeah. Oh, the other thing I was going to say about the-- The schema here, is like, when you're defining like, it's a string, it's a Boolean. As many of you are familiar with, static typing helps you catch bugs. This is super helpful when you're trying to shove a Boolean into a string, or something like that. It helps you catch bugs super early, so it's a really strong point. Okay, back into our controllers. Notice that we have a to do right here, right? And now we have a to do controller. Again, just all following the same convention. It just assumes that if you have a to do, it's going to be called a to do controller. It's just going to automatically append that controller. All right. So, we have that. Because this is a short program, I'm going to put both the controllers in the same file. If this was a bigger project, I would separate them out, but let's just go ahead and do it in the same one. So we're going to have a to do's item, right? So we're going to have a to do's controller. Notice how we have a to do controller, and we have a Todos.todoscontroller, with an S. And it's going to be = Ember.ArrayController.extend Again, actions: Be utilizing that later, but just going to get it in there now. So yeah, this is just going to be a collection of to do's. A to do's, the to do's array is a collection of the to do objects. Pretty straightforward, right? If any of you have ever worked on Backbone, this paradigm should feel very familiar to you. Cool. So, let's go back to our app, right here. Save that. So something you might have noticed by now is, at this point, when we were coding up the Angular app, we'd already jumped into the index o-da-shun a little bit. The boot-strapping of an Ember app is a little bit longer, but once you get it up and running, it's pretty similar, that you can just go back and forth really quickly, rapidly iterate. All right, so. This is one of my favorite parts of... Application adapter. This is one of my favorite parts of Ember that we're about to look at right here. DS.FixtureAdapter.extend. So, what's going on here? Ember has this concept of an adapter, which is essentially saying, "This is the place "that I'm going to get my data from." Typically, this is going to be like an adapter to reach out to a server, right? Like, this is going to be where you define all of your AJAX calls, like "When I create an object, "do this; when I delete an object, do this." In this particular case, we're just working locally. Like, we're just prototyping right now. So we're going to use the fixture adapter, which is where we're going to pull in our fixtures. But, let's say you coded this super-cool fancy app, right? And you go in and you create this ability to save objects, and delete objects. They make it absolutely trivial to switch from your fixture adapter to your AJAX adapter. You have to go code up like, three or four more methods; and lo and behold, you went from just working on local data to working on Chat data, just like that. Pretty cool, right? Like, I think it's super cool, because it helps you take your prototype and turn it into an actual, real working app very quickly. And there's other sorts of adapters as well. There's like, the local storage adapter, there's just about anything. I'm sure there's like, a cookie one or something like that. Whatever you want to do, wherever you want to stick data. contrast that with Angular in terms of getting to the persistent data? Yeah, definitely. Angular has an HTTP service, and it also has something called a resource, N G resource. And they're essentially just little services, libraries, whatever you want to call them, that allow you to reach out to the server. It doesn't actually give you any structure to do that. It's just really up to you to define how to do that. An anti-pattern in Angular would be just to throw it into a controller, and just use your AJAX service in there. A better pattern would be to create a custom service, and then have that service injected into your controller; and then when you do that, it makes your service testable, and it also makes your controller not-- Dependent on having a back-end to talk to, which makes your controller more testable. It just separates concerns as well. Like for example, we have a Reddit gifs project, and we have an Angular service that talks to all of our back ends, so we have several Angular apps throughout the entire site, and we just inject that same service into every one of them. So it's really nice because we're all using the same end points throughout the entire site, right? That's probably a really verbose way to answer your question. (laughs) Cool. Other questions? All right, let's keep going. Here we go, actions, actions. Takes that... Adapters. All right. So let's give to do's route, let's save that. Let's go back to the router. We're going to give this route a model. This is going to tell it where to pull its data from when it is on that model. It's like, "You switched this model. "I need you to get some data; go get it." So in this particular case, we're going to say model: function And it's going to say return this .store.find('todo') It's going to go out and find all the Todos that you've defined. Oh, okay. So... Yes. So going back to these fixtures real quick. This is telling it "When you're looking for fixtures, "look for these fixtures." Like that, that's another auto-magically-- I feel like I wasn't clear on that before. So, that .FIXTRUES is saying "Whenever I'm looking for fixtures, "here's some mock data to throw at it." So, that's what this Todos.Todo.FIXTURES = Businesses. And in this case, this.store.find('todo') because we're on the fixture adapter, it's going to go find those fixtures that we were talking about. Is that clear? All right. Cool. So, we have that. Now we're going to talk a little bit about Ember components. So, we have a components.js; let's just go ahead and bring that up here. And this is going to look just painfully familiar to you already. Todos.TodoEntryComponent TodoEntry is my own name; that's not an Ember thing. I called it something different just to differentiate it from what was out there. So, Ember.Component.extend So, Ember components are kind of like web components. That's the idea that they're kind of chasing here. Kind of like, I would say they're at least similar in concept to Angular directives, because you can create Angular directives that are actually entire elements; and in that sense, Ember components are similar. They don't have the ability to do mix-ins kind of stuff like Angular does, but... yeah. So, here again, actions. Which we'll define here in a sec. All right. We finally have, we can jump into our index now and start putting some stuff in there, so. Um, is this like where, if you had actions that you want to get handled across multiple controllers, you stick them up here, and you just include them in your controller? So you're going to-- An action's going to happen, and you're going to use that to call out to other things, right? Right. But isn't that where you were building components so that we can sort of inject that into our controller or--? Right. So essentially, that the components can send actions back to the controller, says like "Hi, I'm a web component. "Like, I'm really dumb, I don't know about "anything around me; but I just got deleted, "so you should go delete me." Oh. Yeah. Right. Stuff like that. I think it'll be a little bit more clear as we go forward. And that's kind of like, that's what I feel like teaching this Ember portion always, is that you have to get a lot of foundation laid, and then you can start building on top of it; whereas Angular, it's so haphazard sometimes, that you can just like, "All right, let's build "a little castle right here, and a little bit right here," and you can just kind of stack them next to each other, and it works. Whereas Ember, everything has to be laid out before it can start going up.

  13. Templating Go back to the index.HTML. Okay, so you see scripts right there. On line 18. We're actually going to surround our mark up in a script tag. That's really weird, but that's the way that Ember currently works. So we're going to say script type equals... Text slash X dash handlebars. And then you have to give it an ID. The ID is significant. Uh... there it is. Or-- sorry, it's not an ID. It's a data template, that's what you have to call it. Data dash template equals to do's. Sorry-- template dash name. Okay? And then we have a-- just from this top section to the bottom part of this section, we'll just indent it a little bit. Okay, close the script tag. So, that's just the way that Handlebars and Ember works right now, if you want to in-line it. They're working on another project that's called HTMLbars that will make this less clunky that way, but that's still a ways off. Okay, so we've just sent this data - template - name, we've told it like, "This connects to the to do's part, "so go ahead and throw it at that." Uh, yeah. Let's go ahead and start putting some cook-- I skipped a page here. All right; well, let's just go ahead and we'll kind of do like the N G repeat kind of stuff that's going on. So we have this each, and then we have this slash each right here, so you can just replace each one of these with... Hash each. Then you can tell which item controller is in control of this particular one. In our case, it's going to be the to do one. And here, we wanted to put... Each, like that; just letting you know where it ends. I guess that's supposed to sit there. Anyway. That hash means that like, if this is actually like, creating a new scope, like, there's actually going to be stuff inside of it like, this is something you're going to be looping over, in our case. Whereas if it doesn't have that hash, it doesn't have, like, doesn't create that new trial scope and a bunch of other stuff like that. Okay, what we're going to do here now is, we're actually creating a component here as, so we're going to rip all of this out, right here. Okay, so just like, copy that or-- I'm going to cut it, actually. I'm going to then go down here and say, make another script tag. Say type equals whatever it is. Text slash X dash handlebars. And then you're going to give it an ID of components slash something. To do dash entry. Okay, close your script tag, and then just paste all that business in there. Okay, good so far? We just ripped up all of this code, put it in down here. We've designed-- defined like, this is the template of our component. So going back up here into the each, obviously something needs to be in here. So what we're going to create is a to do entry. Val equals val, and completed... Equals completed. Now, what's happening here is, we're just taking the parent values of val and completed from that individual to do in each iteration of that loop; and we're passing it down to the to do entry component, so it can display it correctly. Yeah, let's make sure I caught everything. All right, so let's go and actually make this like a-- Sure. How much of the logic do you think should be in the dump-letting regarding the handlebars versus putting inside the view code? I would minimize whatever you can put into the template. The template really should just be like, how you display your data, and how you interact back with the dumped update data, and then let-- Oh, sorry; interact back with your app, and then your app updates all your data and handles, and marshals that data about. You don't want to have-- You want to minimize the data in the template, because that's going to make it easier, one, to maintain, because you're going to-- You're going to have a bug. The bug is going to change something when you don't anticipate it. And if it's happening in the template, you now have to look both in the template and various places in your apps to figure out what's modifying it in a weird way. Typically, when data's being modified in an unanticipated way, your first thought is not to check the template, right? Your first thought is to go check the app. So it's just-- you're putting data operations in unanticipated places, which makes it less maintainable and also less testable. Did that answer your question? Cool. Wouldn't you put this in a separate file? It's a component file. The template stuff? Yeah. Definitely, yeah. This is for simplicity purposes. That's a great point. Okay, cool. So, let's go ahead and start making this more like, Ember-esque. So, in our script tag here, we're going to make this-- We're going to make this an Ember input, so delete your angle brackets, and put in mustache, Okay? This-- the input, it's actually like a function, it's a helper function. It's something just for inputs, because there's a lot of inputs, right? When you're creating a new template, and so they just give you this little helper thing to help you out with it. So, we're going to give you a type of check box, and we're going to give it a checked equals completed. Kind of what you would expect, right? If it's completed, then it would be checked. If it's not completed, then it's not; and then it's automatically data-bound. Pretty cool. It's analogous to the N G model, I think. Pretty close. So let's go down here to this input, down here. Okay, same thing. Take the angle brackets off there. I have form control on there twice. Go ahead and delete one of those. It's not very helpful anyway, so. So, there's this idea called class name bindings. So we talked a little bit about N G class in Angular. This is the analogy in Ember, and we're going to call this class name bindings. And then here, we're going to prefix this form control with a colon. Now the reason is that it accepts key value pairs, like, the key being like, "If it's true or false, apply this style." But we always want to apply that form control, so we're going to prefix it with a colon. That just means like, "Always apply this. "There's no contingency here. "Let's just always apply it." And the other thing is that, class name bindings and class don't play nicely together. So if you have class, it just means like "We're not going to do any guessing on your class names," but if you do want to have some conditionals in there, you have to put everything in the class name bindings. Does that make sense? on (stammering) seems like there's sort of a wavering between CamelCase and DASH case in naming stuff in Ember. Like, I think you can-- I'm not sure, but I think you can also say class dash name dash bindings. Like, if you use bind attribute, you can use bind dash A T T R. I'm just like, wondering. Do you know why that's going on? I'm not too privy. I used to be a little bit deeper into the Ember community. I'm not as much anymore. A lot of their guys went down to Austin, so I don't talk to them as much anymore. And Portland. Whatever. Anyway, so I think the DASH is the old nomenclature, and I think the CamelCasing is the newer nomenclature, and I think people are still arguing about it, but that's just my feeling. I've always done the CamelCasing. That feels more correct to me, because it's more of a scripting kind of access to it. I heard a lot of complaints about Ember changing a lot of breaking changes in their release. Is there-- Yeah. Can you comment on that? Definitely. Up until one-oh, that was a huge thing. And then with one-oh, they said "Okay guys, the dust has settled. "This is the way it's going to be." So, it was for sure. It is better now. I don't think they've had any massive breaking changes for a while, since they went one-oh. Totally like a-- If Ember feels good to you, I have no reservations about recommending it wholeheartedly, so. In fact, I wouldn't present any of these to you-- Any one of these is a good framework. There's not a bad one here, right? Some of these just make more sense to other people. Or, to different people, rather. Okay so, now we're going to put a conditional one in there, which is going to be completed, finished. Finished is the name of the class; completed is the name of the... The actual value, the Boolean value that's determining it. So if it's completed, then it will apply finished; if not... And that's what gives it the italics, the greyed-out, the strike-through; that's what that class does. Did I do value equals val? I haven't done that. So, value equals val. This is the N G model part of it, right? D. This is the actual value I want to have on here. Fingers crossed, I think everything we can actually look at it now. Something will be happening. Hurray! Didn't screw it up. So let's see; checking should work, as it does. You should-- and you can, again, delete these. You're not actually seeing anything, but it is actually updating in the back end, so. When I say back end, you realize that's in the JavaScript as opposed to on the template, right? Questions about this? Not getting my Todos printed out. Okay, is there anyone getting it printed out?

  14. Code Review All right, so let's just have a quick rerun through the code. So, the app should have Ember application, D S fixtures extend. about using quotes for the value, like checked equals completed, or checked equals completed, inside quotes. As long as they're inside this helper right here, you're totally welcome to say value equals val, right? This is actually being patched into the JavaScript, and then compiled, so you're totally cool to not use quotes. Did you figure it out? Um, yeah. I omitted the value equals val. Okay, cool. Everyone else? It's a lot of code to get up and running all at once. Are you guys getting Ember-- or, errors in your consoles? No errors. That's a bummer. I'm getting a 404 error that it couldn't find to do's. So did I name something improperly? A 404 on to do's? I don't have anything called to do's, so. I must. (chuckling) But I mean, that's the kind of weird thing that Ember would do; it's like, "I assume you wanted to do's," so. Cool. The best thing I can say is that I have my presenter's notes in the repo. You can just go kind of line by line, and-- Cool. Let's see. Well, we have about-- we have a little bit left. Now that we have kind of like the base level laid down, the rest goes pretty fast, so. Yeah, we'll just-- let's just run through real quick. So we have the app.js Ember.application create, fixtures, right. Go to the router. Make sure you're getting the store find, the resources, like, has a good router. Who-- is it working for some people here? Okay. Okay, components. Not a whole lot in components. Just the fact that it exists, right? Models: again, just a couple things there. Controllers: again, they just have to be extant, that's it. And then-- yeah, all this stuff here. All right. Well, if you're still having issues that say-- either ask your neighbor, ask in the chat room, or go through my presenter's notes. I mean, it's-- all the code is in the presenter's notes.

  15. Actions Let's go ahead and add some actions, no? So let's go back to the components. So, we're going to actually be operating now on this actions object. So we're going to define one called click function... And then what we're going to do is, we're going to send an action up to the parent to remove. So we're going to say this.sendAction(' remove'). The component itself is not able to operate on itself. Like, it really is, it's just a dumb container that you throw data into, and it displays it, and then it just throws like, "Hey, someone touched my button. "You should do something about that." Like, it doesn't do any operation in and of itself. So,this.sendAction('remove'); Okay, and let's go up to the... Yeah, the router, or rather the... Right. We also have to give that into the index as well. So in the index, we have the to do entry, right here. And we're going to have the remove... Equals remove to do. This one actually is in quotes. So now we've defined when something-- When I get called, or rather, here we have the send action, right? It's going to call remove. That's going to pass it through here, and this means "Hey, my parent called remove Todo," Let's go... Into our little web component right here. We have the button. We actually have to put the action on it. Like, we have to say where the action's actually happening. So you're going to do action. Let's see. I lost my place. Yeah, action click. There it is. Okay. Yes, action click. So, no colon, no equals. It's just saying "When this button is clicked, "call the click function," right? I believe that's also an arbitrary name. I think you can call it whatever you want. So, let's save that. Now we actually have to define what remove to do actually means, right? Because here, we're saying when the remove is sent, when the remove action is sent, that means call the remove to do. So now we actually have to go into the controllers. Which is on the Todos.Todos.Controller. So you're going to do a remove to do function right here. So you're going to say var todo = this.get('model') Okay, todo.deleterecord, and todo.save. Let's talk a little bit about that. So what's actually happening here? So first, we're just going to go grab the model that is being operated on, right? So, I click on one of the buttons, like, the red X buttons, right? I click on it, it's going to generate an event that then Ember's going to listen to for itself, and then it's going to pass into this controller. The this.get( 'model') it knows which model it's operating on,'model') does because it's the one that you clicked on, so that context already exists. You don't have to worry about that. That's what that this .get( does. It just gets you the model that's underlying what's happening right there, And then we're calling the todo.deleterecord. That's a built in function to the adapter. It already knows what it means; you don't have to define it. It's just Ember magic going on, right? And, then you call todo.save. It actually won't be perpetuated until you actually call the save function, because you could do a bunch of operations in a row, and then save it, so it only does one save, right? Like, if you're doing like, an AJAX request, right? You don't want to call like, the endpoint multiple times. You want to call it once with all of your entire data payload. So, that's what that paradigm's all about. I think the delete one's kind of silly, because if you want to delete something, you don't really care what else happens to it, right? Like, you just want to delete it, so. Questions about that? No injection to the scene-- You can't inject the model? It's going to go and get it? It's in contrast to Angular, because you've got the scope. Yeah, no. It depends on context. Uh, yeah. So save that. Now our removing should work. So let's go ahead and give that a shot. Cool. So you can remove horse-sized duck, duck-sized horse, banana for scale. (chuckles) Anyone get my Reddit jokes? No? Okay, good. Okay. I wanted to make sure I wasn't the only one. Cool. All this make sense so far? I mean, like, once you get Ember up and running, it's cool. Getting Ember up and running is a pain in the (blank), especially the first time. It's a lot to take in all at once. So if this is not immediately obvious to you, just get in line. (laughs) This isn't immediately obvious to anybody. In fact, all these frameworks are somewhat difficult, so this is pretty advanced stuff. So if you're following along, you can feel pretty good about yourself. And if you're not, then you can still feel pretty good about yourself. (class snickering) It's cool. I give you permission. (chuckles) I'm glad you came-- this is like, a self-reaffirmation class, so. All right, let's go ahead and do some other fun stuff. Let's go ahead and do like the-- New to do kind of stuff. Go back to our code. Let's go back to index. Okay, where am I going? Right there. Let's go ahead and do our magic Mustache syntax right here. Class can stay. We know to say value equals, let's see. What do I call it here? Value equals new to do. Okay, and action... Yeah. Oh, might as well. There's an-- We'll just, we'll do it later. Anyway, okay. So, value equals new to do, and then on the button here, we're going to do action. Uh, what do I call that? Create new to do, something like that. Create new to do. Okay, so I just added two things: the action right here, and the value, as well as these, like, Mustache stuff going on. Okay? Pretty simple. Go ahead and save that. So now, it's bound to the new to do value, or the new to do, rather. So, those two are kind of, they're two-way data bound; and when we have, or we click the button here, it's going to try and call the create new to do, which, right now, would error because it doesn't exist. So let's go ahead and go and create that new to do. So let's go to... The controllers.js Okay, and in the TdosController down here, let's go ahead and create new to do. Okay, so, just going to go ahead and grab the new val, which is going to say... This .get('newTodo') Okay, and then I'm going to create a new record which is going to be todo = this.store.createRecord That's going to be a new Todo record, right? And then we're just going to pass it on the values that we have; so we're going to have... Val is new val, and completed is always going to be false, when you create a new one, this.set('newTodo'.), to be blank, and then we're just going to call that save function again. Let's see, I can probably make that go a bit higher so you can see it better. So, just to recap what's going on here. First slot, that new val line is just calling out to get that new to do value. I think that's a pretty common paradigm in Ember just to, you call out once to get it, and then you can just operate it on the local scope. Then you're creating a record. It's a new to do record, that's what that first value is. It's like, going out and saying like, "This is a to do-type record, "and give it the new val, give it a false completed, "and then set that new to do to be blank, "and then save out the information I have." Again, that save would usually go out to the server and say, "Here's my new to do," but in this case, we're just staying local with fixtures. Questions on that? Does that make sense? Cool. Extremely stupid question. On line 16, do you need a comma? Yes. Yes you do. Yep, you do. It's cool. If you want to be trendy, and have functioning JavaScript. Yeah, thank you. Cool. Other questions, or gross errors? (laughs) Cool. Let's give it a shot. Okay, refresh. This is a thing. And that business, ta-dah. Most people getting that working for them? Cool. (flute and electronic music)

  16. Actions, Continued So, let's go out and add that. Let's go back to our index .html Go find that clear completed button down here. Add the action, clear completed. And then, we're going to go back to our controller.js. And, that is going to be on this to do's controller. Just comma right there, clear completed function. So, var completed equals this filter by. This is an Ember construct. So while you can use native JavaScript function straight on Ember, they've done pretty well in giving it, most of it, to you. Like, so they've just recreated it inside their little ecosystem, which is what this filter by is going to do for us. So we're going to filter by completed true, so this means we're going to go out and find everything that has been completed, and then we're going to call deletes on all those. "briefly review how Ember does data binding?" Yeah, let me just finish this part, and we'll go over data binding real quick. But that's a good thing to talk about. So completed.invoke. So, this is a super cool feature, in my opinion, about Ember, because you can call this invoke function. That's going to go call some functions on every one of these, right? So, in this case, we're going to call-- We're going to invoke the delete record, and then we're going to do completed.invoke ('save'). So, three lines. We go out and we grab everything that is completed, right? So everything that has completed true, then on all those, we're going to invoke delete record, and then we're going to invoke save. Could you pop back to the index, please? Yeah, definitely. So what we did in the index is, we just set clear completed, right here. That's the only thing that changed in there. Is that good? Cool. Any questions about what's happening here with clear completed? All right, should we give it a shot? Refresh that, clear completed. So duck-sized horse and learn Ember should go away. Lo and behold, go away. Puppies, banana for scale. Very cool. Okay, so Laura asked, "How do we achieve "two-way data binding in Ember?" It's based on getters and setters? I guess-- is the question like, a high level, conceptually? How does the data binding work in Ember versus where we stopped in Angular? So if you've-- We actually haven't done much like... Let's just actually go back here to our index real quick and look at the check boxes. So right here, we have the check completed and the, uh, right there. The value equals val. So, Ember is based on getters and setters, so any time you want to like, get something, or you want to set something, you're actually recalling a function rather than saying like, object.property = value, right? The difference that that makes is that you have control over what's happening in your setter, meaning-- so I can call .setvalue, and then in my value, I can set that; but I also know that it has dependencies out in a bunch of different places, and so that setter can call out and set all those different places that it's dependent on, right? So in a real-world example, let's just go back and look at how it works here. I have this one right here, and I have a dependency that every time that this completed changes, the class name has to change; and so I change, using a getter-- or using a setter, rather, and I know that every time that that changes, I immediately have to go and update that class. So it builds this almost like, dependency web that it knows where it has to go out and change everything. Does that make sense? I see no faces. Okay, I assume so. Whereas, Angular's doing dirty checking. It's assu-- like, it's just doing this digest cycle, it's always constantly checking, saying "Did it change? Did it change? "Did it change? Did it change?" And if it did change, then it goes out and updates everything. Because it does not have an ability to tap in to that, that setting process. Because that's, any time something changes is when you have to go out and update everything else. That'll get better with ES7. ES7 is landing object.observe, and they don't have to do any sort of dirty checking. They can just say, "Object.observe this value, "and then when that value changes, it'll fire an event. "You can listen for the event, "and then you can go out and do whatever you want." So, Angular is poised to get a lot of performance advantage with that, because dirty checking is expensive, as you might imagine. Object.observe is already in Canary, which is kind of fun. If you want to go toy around with it, it's pretty cool. But yeah, that's Ember. As you can see, tons of setup time, and very little actually coding up after we got that setup time done. Did we do the remove item? Yeah, that was the first one we did. Okay. That's cool. Just go through the notes; they're all there. In the inspector, is there a point for the Chrome plug-in? Sorry? In the inspector, is there, for the Chrome plug in? Yeah, I have it here installed. I'm not actually too familiar with it. Bad rang versus? So it's just like, right here. They have like, a bunch of cool stuff for it. Render performance, this is new. This is updated. Cool. Whereas like, there's the Angular one over here. Lots of inspector in kind of stuff. Do I have the React one here as well? I do have React; it's not up right now. Anyway, there are really cool tools for all these, so definitely worth checking out. Battering is the name of the Angular one, really really cool. So. Is there any kind of inspector for the Firefox side of things, if you're targeting that? Battering for Firefox, I think just landed, but last week or something like that. So that one's, yes. I think Ember's on there as well. I don't know about React. I'm so used to using Chrome tools, so. But there are definitely options. I know Safari has some of them as well.

  17. Ember Questions What questions do you have about Ember? There is a thing called Neats. I saw that in like a par- inject, like another controller or something. What's it called? Neats? Neats, you have like an attribute. I can't comment on that. I don't know anything about it. Sorry. Property. It's very different than... Yeah. I imagine the generators help with that. Like, yeoman-type stuff for Ember. Definitely. Like boilerplate. There's the Ember CLI. You install it through M P M. It runs like, its own little Ember server for you, like, there's a lot of really cool things around the Ember CLI. I would definitely recommend-- Last night, I was like this close to just re-fracturing everything to use the Ember CLI, but wanted to keep it simple and equal. So. But I would definitely check it out. It's one of the better parts of Ember, for sure. "Is object.observe in ES6 or 7?" I thought it was in 7. But that being said, I think it landed in Canary already, so. I think it was supposed to be in 6, and they pushed it out to 7. is that it is coming, regardless of what (chuckles). Yeah, it is coming. Just, it's not in any modern browser. It's just in like, one of the nightlies, so. "How does testing work in Ember?" That's kind of a moving target right now. At EmberConf-- no, RailsConf. Anyway, one of the confs that I'm not thinking of right now, either Yehuda Katz or Tom Dale, one of the guys that does Ember, said that "We're standardizing on QUnit." Which was like, sent waves throughout the community. People were mad, other people were super happy. But the Ember community is standardizing on QUnit. Yeah, so that's the jQuery one. Which is great, it's a cool testing framework. Like, ultimately, it would probably prove to be a pretty good thing for them to rally around one, but I think a lot of people just aren't familiar with QUnit as much, so that'll be an interesting transition for them. But that's recent, like, that was like two weeks ago, or something like that. So I'd say just kind of keep an eye on it. Ember's very testable; unfortunately, I don't have a ton of experience specifically testing Ember apps. And that's probably a big part of it, is it has been such a moving target of like, how one does it. Angular was definitely built from the ground up for testing to be like, the most testable possible, so it's just like baked into their culture. And it has always been. Ember kind of missed the target up front, and they've caught up, and it seems like they've caught up pretty well, and they're still finishing that catch-up, I think. when Misko was here giving a workshop, he was, prefaced everything with like, he was a testability coach, like you will for was it like, eight years before creating Angular. Yeah, I mean it's, you can tell. Like everything, like with dependency injection, like all this different stuff that just makes it trivial. If you're not testing Angular, it's just-- It's only like, one further step. It's so easy. Let's jump back and do it. Sounds like we have a couple questions to kick it off. Javier says, "If you're using Ember with some "external API, how does it internally work "when watching for changes?" It keeps making AJAX requests, or asking for changes on point, and how do you do that with Ember compared to like, Angular? Ember kind of observes more of the Backbone paradigm, which we'll talk about when we get to Backbone. And what that is, is it's kind of like when models change, it's going to perpetuate that data out to the API. And so, it can-- There's several ways you can wire it up. It's kind of up to you, to the way that you want to do it. You can have it so that every time that something changes, that it's instantly perpetuated the back end, kind of like you know those fields that you type in, and they're instantly like, saved on the back end. Like, I think Airbnb is definitely one that does it that way. You can also have it like, batch your changes. It's kind of up to you. As opposed to Angular, Angular's kind of the same thing. You just kind of define like, "When they press this button, "I want them to go out and," you know, "reach out to the server and change that." It's kind of up to the programmer, however the programmer wants to do it. Do you have more questions, Mark? Uh, yeah. In the clear completed function, you said that you couldn't use native JavaScript function in Ember. Can you expand on that, or clarify? Yeah, definitely. So, if you remember-- in fact, I'll just even bring up that code right now. Let's look at Angular, the thing that we wrote in Angular. Angular, some of the empty projects, N G. N G Todo. C T R L. This ToDos.filter, this filter, is just like a native JavaScript array function, right? Like, this is just built straight into JavaScript. You can call it anywhere; it's not part of Angular. And then we're just filtering out something. That ability, because you're not operating on native JavaScript objects, you're operating on Ember objects, that ability is not exposed or available to you. Now, if you remember, we had that filter by. I can probably even bring that up. Believe it's in the controllers, here in clear completed. So we have this filter by. The Ember guys have actually done a pretty sweet job of like, back-filling you for those abilities. So in this particular case, we're doing a filter by completed, and that's returning everything that's like, that has been completed, so. That ability is there; it's just not native JavaScript. It's just whatever the Ember guys decided was best for you. Cool. Anyone else think of any other questions that they want to address, before I move on? We got just like, a couple minutes, so, before lunch. We're going to talk a little bit more about Angular. We're going to talk about directives and filters. Could you talk about Ember's computer-- That's kind of interesting, actually, when I saw that, you know-- Yeah. Computer properties? Yeah. Just, kind of the dumb example I gave a little bit earlier, about like, you have an area thread, and an area's always just computed from length and width, right? So you can have a computer property of area, but you can have other properties of length and width. And many times, length changes. You can have it go out, recalculate that, and then put it back into area. So you can access area, just as if it was a normal property, but at the same time, it's always kept in sync with length and width. So that's a really dumb example, right? Like, who cares if you're just doing that calculation on the fly? But let's say, I don't know, like you're having some super-expensive mathematical operation, or something that requires like, a database hit or something like that. I don't know, something that's a little bit more complicated, that you don't want to do. Yes, database hit is not a good example, but let's say it's like the quadratic equation or, I don't know, even something that's more complicated than that. That can be kept in sync just with computer properties, and you can access them as if they were normal properties. Which is super cool, right? Yeah. Promises might be a good example there, with Ember. Where, you know, you're getting a value back that's a Promise, and so you want what appears on the HTML page to be the result of that, and not have to sort of like, wait and listen for it. Use a callback, and rewrite it. You can just say "Put that value here," and when it updates from the Promise, it will put it there. Definitely. Like, it's kind of like a delayed setting, which is cool as well. Yeah, Promises are really big in both Ember and Angular. Not going to go over too much, like, what that is. That's more of like, a core JavaScript sort of thing, but something worth familiarizing yourself with, if you don't already know about them.

  18. Backbone Bootstrapping So just did Angular, we just did Ember. Hopefully those were good experiences for you. We're going to move on to Backbone, and then we'll do React last. But it's really fun to compare Ember and Backbone next to each other. You can see a lot of Backbone's influence directly into Ember. So, I'm going to go ahead and warn you up front that Ember, or Backbone and React are much more verbose. There's going to be a lot more code going on, so. Buckle up is what I'm saying, I guess. (chuckles) Okay. So if you remember from our little chat previously, Backbone is also based on getters and setters for its two way data binding, but this case, it's not free. So it's going to fire off an event, and you're going to have to tell, "Hey, this change, you should update my value." Seems kind of silly, but once you set it up once, it just works forever. So it's just, you entail a little bit more ramp-up process. Cool, let's get started. Let me go to router.js. We're going to do that, in frets of the app first, because you can't start a Backbone app without the router already existing. So, going to do window.TodoApp equals new, it's got some weird syntax here, but this is kind of common Backbone stuff here. Router.extend. So what's happening here is that you're extending a Backbone router, and then immediately running it to create itself. You could actually, like, create like a Backbone router, and then instantiate it, but you're only ever going to have one router. I can't imagine when it would ever be a good idea to have two routers, so just go ahead, and just instantiate it right away. Yeah, so this is just an instantly invoked function expression here. Okay, so let's jump into it, say route, kind of like Ember, routes are baked straight into Backbone. So if you want to do a multi, or a single page app and have multiple routes, you would do it here. In this case, we're only going to have the one route, which is totally fine. Okay? And then we're going to have our index, let's see, sorry, I got my notes mixed up here. Okay, I think we're okay. index, okay, and then we'll do start. Backbone.history.start, okay. So now we've bootstrapped our app a little bit. So we have that route, that's, yeah, just like I said, you're defining all your routes. The blank string represents the base route, like slash, right, and you're saying, when it's the base route, go ahead and run the index function, or the index controller, right, which is what we have done down there. We've created the index function. Haven't put anything in it yet, that's just the instantiation of it. And then we have a start function. That's not a Backbone necessary reserved thing, it's just a common paradigm to have all of your Backbone load, and then all of its load, then you run a little start function that actually starts tracking your HTML history, right. And it just does that by HTML push states, if you're familiar with that, which you can use to manipulate the history of the, excuse me, the browser. So, pretty straightforward, any questions on that? Okay. Just, this is essentially all boilerplate, so. You're going to find a lot of that in Backbone, a lot of boilerplate. Okay, let's jump into app.js. And we're just going to have like a one liner in here. Okay. So, Backbone is dependent on jQuery, so it's totally cool that we're just going to throw jQuery at it, it's always going to be there. Oops, and you can really just say, Todo, TodoApp, sorry, .start. Okay, and then that's actually going to get our app started and running, and tracking of the history. Even though, in this particular case, we're not going to be tracking history, it's just still the paradigm to get Backbone up and running, and your app going. Okay, save that, and now, like when our Backbone page loads, it'll actually start our app. All right, let's actually, let's get going with creating some of the models here. So let's jump into models.js. Okay, you're going to be, find that this is another common paradigm, just throwing everything on the window, because that seems like a good idea, right? No. (chuckles) No, but like, we have TodoItems, we're going to use them in multiple places, so we want it to be available throughout our entire app. Okay, so we're going to have Backbone.model.extend. Actually going to do anything special to it right now, so, that's it, okay. Again, if you had multiple models, I would recommend breaking them into multiple files. Once your app starts getting bigger and bigger, then those models are going to get longer and longer, right? So in this particular case, I am fully aware of how long they're going to get, so I'm just going to stick them both in one file, just so we can see all multiple things at once, kind of makes sense of what's going on. Okay, window.TodoItems, okay, equals Backbone.collection.extend. Okay. Here, you're just going to do a model, and that's going to be a TodoItem. So, this should hopefully be just intuitive, but just to go through it real quick, you're going to have a TodoItem, and then beneath it, we have TodoItems, right, we're going to have a collection of it. It's the same kind of paradigm that's going on in Ember. There's no enforced schema here. You can actually, there's lots of Backbone plugins for enforcing schema, if that's important to you, which is might be, and it could be. In this particular case, shouldn't have a, there we go. We don't care in this particular case. So, we're just going to be writing this all in vanilla Backbone. And again, I think I mentioned earlier, but I'll mention it again, very rarely are you going to be writing truly vanilla Backbone, usually, you're going to use something else. Marionette is just like top of the list for me, but there's also Chaplin. I think Facebook has one called Thorax. Bunch of cool ones out there for you to use. It's very easy to extend Backbone, so that's why. Okay, and then the model here, again, you can only throw, I guess this is kind of a schema, right? Like, your TodoItems can only have TodoItem in it, so.

  19. Views Let's jump over to views. Okay, so window.TodoView equals Backbone.View.extend. Okay, we'll do a render, function, okay, and so, what we're going to do here, which is kind of interesting, we're going to do this.$el. So, dot dollar sign el is going to be a jQuery wrapped DOM node, okay. So we can then just operate on that. You can actually take the dollar sign out, and the it's just like the normal node, that's just a normal DOM node that's not wrapped in jQuery. But since we have jQuery, might as well operate on that, since it's a little bit easier. Okay, and .html. And then we're going to do this.template, this.model.toJSON, okay. And then return this. The other thing is, we're going to put a class name on this, so it's going to have input-group, and input-group large, like, don't worry too much about that. That's just my own CSS classes that I've been throwing on the page. But that's the, let's see what I want to say, it's the class names of the parent element, in this case, it's a div that's encapsulating all of this. And if you want to affect those class names, you just do it this way. Okay, right now we do not have a template function. Doesn't matter what this is, like, so you can plug in any templating here that you want. We're going to use Underscore's templating, just because Backbone depends on Underscore, and it's already there, might as well use it, right? And if I was actually creating my own project, no chance in (silence) I'd use Underscore's templating. So that's totally up to you. I'm just, I've been trying to avoid copying and pasting for this, but there's, I'm just going to copy and paste this from the completed project. So completed-project, Backbone Todo, js, it's going to be in views, so just go ahead and grab that template monstrosity here at that top. Copy and paste that, like we can go over a little bit, like, what's going on there, but, this actually is not about the Underscore templating language, so I just wanted to sidestep that as much as possible. Yeah, so let's just delete that, rather. So, if you're familiar with Underscore, like essentially, you're just going to feed it some JSON. It's going to go through, and it's going to replace like that completed, and it's going to replace, like the class there. And then every time that render, it gets called, it's just going to call that templating function with the current data that it has in its model, and re-render that. That's kind of the, the paradigm here is that every time you call render, it's going to go back with the data it has, and re-render whatever you've passed into the render function, in this case, we also use like a template function for that to happen. If you don't really get what's going on in the Underscore templating language, doesn't really matter. There's like 1000 better ones out there, so just move on to one of the better ones, in my opinion. Any questions about that, that someone wants addressed? My wife hates when I just, like, breeze over things. She wants to understand everything, so, (chuckles) if there's someone out there, we can talk a little bit more about it, but, my opinion, there's much cooler things we could be talking about, so. All right. Yeah, so, just to kind of go over, like, what Backbone is doing here, like, you have your underlying data model, right. These are going to be like what actually operates on the data, and then on top of that, you have the views, and that's how your models look whenever you display them. In theory, you can have one model, and have multiple views that display that same model, as well, right. So let's go over the idea of a fat model, and a skinny controller. Has anyone ever heard that paradigm before, yeah, okay. Because everyone was, yeah, I mean, I make this stupid joke every time I give this, but like, everyone likes a skinny model right, ha ha ha. (laughter) You want to throw everything that makes sense onto the model, right, like, everything that like is operating on data needs to go on the model. This is always, always, always the problem with Backbone apps, is that there is just way too much in the view. Like, just take everything out of the view. The view should be stupid, it should just display things, and then like, not do anything else. Because in Backbone, it is so easy to put everything in the view, right? Like, say like, we're going to do our updateTodo, right? Like, it's really easy to just like throw all that stuff straight in the view, and then like, your model does absolutely nothing. Everyone's worked on, like, a Backbone project with like, hardcore engineers, like famous names you've heard of. And like, it was all in the view, and they were using like, superimprototypical inheritance on the view, and it was like, it was just mind-blowing, yeah, mind-blowing. That's incredible, like it just, like I was telling you like, one of the worst thing in the world is like, there's like war, and then there's like, bad Backbone code, like, it's just the worst thing in the world. Like if you inherited it, I'm so sorry, like, it's just terrible. And like, observing that paradigm of having a fat model and a skinny con, a controller and skinny views, like, will just save you tons of time. Everybody's complaining about the render function not having a comma after it. (laughter) We have OCD. I'm cool with that, all right, like, this is going to save me time later, thank you. Online participants. Online participants. I'm okay with that. Commas are like the bane of my existence when it comes to JavaScript, I forget them all the time. Okay, let's go back to my preaching. (laughs) So yeah, you want to like, move things that operate on data into the model, because that way that you are also opening yourself to being able to have multiple views, right? Because if all of your operations on data are happening at the view level, then when you try and move that model to be able to be used by another view, guess what, you have to rewrite everything, all over in your new view, and this just, like, you're either going to have like copy pasta going on, or just really unhappy engineers. (laughs) It's hard to test, too. It's extremely difficult to test, as well. If you keep it more, like, in the model, like, it's just so much easier. So just do it, just trust me. For future sakes, for whatever engineers you work with, and for the good of humanity. Okay, cool. So yeah, the render function, that's kind of the keystone of what's going on here, right. Like, that needs to be there, that's what's going to get called a whole bunch of times. Cool. Let's go ahead, and like now talk about rendering a whole collection, right. This is just one individual Todo. We're just going to go underneath here, window.TodosView equals Backbone.View.extend. Okay, and we're going to do addOne. It's going to be a todoItem. We're essentially right now going to code up like our ng-repeat directive. Okay, so var todoView equals new todoView of, and the model's going to be the todoItem, right, because we just received in a todoItem, we're going to render it with a new view. Okay. And then we're just going to do this.$el.append, right, it's just that normal jQuery business. And we're going to do a todoView.render().el, okay. Okay, so this is how you, like, display one of them, right. So how we're going to have to find a way to display all of them. So we're going to do an addAll, which, by the way, these things I'm showing you here are not, like, reserved Backbone words. This is actually just, again, another really common paradigm in Backbone. So this.$el.empty, so first, you got to get everything else out of there. And then you're going to say, this.collection.forEach. this.addOne, and then you have to give it a context, so it actually is operating on the correct things. You just pass this, as well. Notice that like here, I'm saying, like, where am I, like, the model, right. So like this, oh, they're right here, this.model, right. So this.collection just refers to like the actual underlying collection that's in that encapsulating object. Okay, and then let's go ahead and do like the render function now. Okay, and then you're just going to do this addAll, and return this. Okay, so let's, just put a couple lines in there, so you can see a little bit better. Let's talk a little bit about what's going on here. Again, this addOne, addAll paradigm, and then using both of those, or rather, addAll inside of render, it's just a really good best practice for Backbone. And doing this allows you yourself, later, that you have the ability to just add one, or you can do the addAll without calling the render. Like, it just opens up a lot of possibilities for you. So we essentially coded the, you know, hash each/ng-repeat right here. That's what this functionality is accomplishing, right here. Kind of verbose, right? But, you have very granular control of what's going on here, like, nothing is happening without you knowing it. Like, there's no black magic here. As opposed to like Angular, where, you know, like, some dark gypsy is like casting her spell over your code. Right, the Angular Goddess. Like here, you see everything that's going on.

  20. Backbone MVC So yeah, that renderOne has to always be there, which is why we do that in addition to the addAll. And then we also have the addAll, so we'll be able to use it later, as well. Cool. So let's go back to our router. Save that, go back to your router. Okay, and we're going to put some code into our index. So we're going to have dollar sign app. I'm assuming everyone has a pretty decent grasp, or at least a basic grasp, of jQuery. Are you okay with that? Cool. Yeah, hash app rather, right, because we're going to just throw this into the app ID, on our index, which I'll show you in a sec, .html, and then we'll do this.todosView.el. Okay, and then we're going to do this.todoItems.reset fixtures. And we also have to create our fixtures, because I did not do it for this project. Okay, so let's just go ahead and throw some on there right now. var fixtures, and again, we're just going to do like a series of, in fact, you could probably steal it off your Angular app, if you really wanted to. But yeah, it's just going to be like val, thing, completed, true, and we're just going to copy and paste a bunch of those. other thing, more things, that one's false, so, cool things, my thing, your, okay. Nonsensical data, who cares, whatever. false, and we'll do that false as well. Now I have some fixtures, okay, and then this reset function, just a sec, this reset function is just going to just essentially take all these fixtures and just throw it straight in there. So if you, you got, like, your data from an API, you would get it all wrangled up in however you wanted to present that data to your models, and then you would just call a reset with that new data on there. It would just go on there and fill them out. People are wondering here, opinions on Marionette, and if you have any experience. So, it's the only one that I have any sort of decent experience with. I briefly got to talk to the creator, which I can't, his name escapes me right now. I have good things to say about it, like, if I was going to go do a Backbone app today, that's where I would start. I don't really, I'm not familiar with the new, kind of like, renaissance of Backbone, because like, when Angular kind of came up in a furor, and everyone was like, "Let's get on the Angular bandwagon," and then Backbone kind of died out, and it's kind of come back as people realized, "I need more control over my app "than Angular will give me." So I think there's some new hotness around it that I'm not familiar with, but, Marionette's good, it's mature, it's used on lots of sites. It's definitely one I would go to. Cool, questions on what's going on here? Cool. So yeah, save that. Let's make sure we got everything I wanted to talk about. There's just so much to a Backbone app, I just wanted to make sure to get through everything. They're saying, extra comma on line 10, but that would only break an old IE, right? Yeah. And screw IE, just kidding. I actually really like the IE engineers, so. Derek Bailey is his name. Huh? Derek Bailey is his name. Is he a Marionette guy? Cool. Yeah. Cool, yeah, so let's go ahead and, we could try and, like, do this on the page right now, just nothing would happen, because guess what? We have not handled the reset event. (laughs) Like I told you, nothing is free in Backbone. It's all up to you. So, let's go back to ♫ Um So that data's being loaded in, it's just not being re-rendered at this point, so. Actually, I have a question. Sure. For you, on the router, so, in the middle chunk there, you have this.todoItems.reset. So I get conceptually what you're after, but is, so we have a todoItem model. Where is that attribute getting set on the this object? Is this a Backbone magical in the background, as happens, or where is that come into being? That, let's see, I might have missed something here. That's a good question. this.todoItems, oh, that's right. It's because it is being created, TodoItems, I feel like it should be created. Oh, that's right, I missed the initialize, thank you. Extra stickers for you. Okay, so we have this initialize function now. I didn't create it already, okay, good, that's why I missed it. And here, we're just going to instantiate all our fun things. So todoItems, we're only going to have one collection of it right now, but you could have multiple collections of the same thing, right, if you had one for completed ones, or something like that. todoItems, this.todosView, right, because you also need that as well, equals a new TodoView, and you're just going to pass it what the collection of, what the underlying collection is. So you're going to say collection, this.todoItems, right, todoItems. And then you're going to, start everything off, you're going to have that first render. So you're going to have this.todosView.render. Is that kind of $scope.$apply, is that Angular? This right here? Yes, the thing is that $scope.$apply just gets applied when you do things inside of Angular, and as a side tangent right now for Angular, it's really tough if you like, say you have this entire Angular app, and then you're trying to do jQuery events outside of it. Because you're working outside the Angular playground, like that stuff doesn't get applied correctly, because Angular can't track what you're doing. So digest cycles don't get applied, which is why you'd do like the $scope.$apply stuff. So this is similar, I mean you're essentially telling it to re-render itself, which is I guess kind of, what $scope.$apply does, so. Cool. So yeah, this'll render everything on the first, when you have your first load. On line five, is it, TodosView? Line five, Or is it TodoView? Yeah, you're probably right, it's TodosView. Maybe just make sure. Kind of got lost in my notes here. Okay, TodosView, TodosView, yes. Online people are sharp. Seriously right, like I just feel like I'm being dissected right now. Which I kind of like, it's cool. Can they just like come to me, like, to work, that'd be awesome. "You forgot a comma." Looking over your shoulder. I'm just going to live code Reddit up here, that sounds great. Cool, thank you anonymous internet strangers. I appreciate it. Okay, going back to views. Yes. Okay, so save this. We now have to like apply, or like, essentially provide for all these different events that can happen, so let's go back to views, okay, and we're going to just operate a little bit on the views. The todosView, rather. Okay, and here we're just going to throw in another one of these initialize functions. If you didn't guess, like, this is a reserved Backbone kind of thing. This just gets run when it's first instantiated. Okay, so you're going to say this.collection.on, add, do this.addOne, now you're going to say, "Oh, we get why we did all this like "random splitting up of functions, it's because of this." Okay, this.collection.on, reset, you're going to do this.addAll, this, and then this.collection.on, destroy, and you're just going to call a render, like, when everything gets taken away, just make sure that I get formally taken out, this. So these are event listeners, these are, it's just syntactical sugar for event listening. And specifically what you're doing, because there's going to be a differentiation here, is that when this happens on the collection, meaning like, this happens on my model, do these things. Because there's also those things that can happen to the view, and you'll handle those in a different way. But for right now, we're listening for events at the collection level. So that's why you're saying, this.collection.on, right? So this step, when something gets added to my collection, make sure you're running the addOne on here. So like, this gets added, and then, the this here is just like the context, right. So it's what this is going to be in here, and because, like, we're doing these operations everywhere, that's why that gets that way. Context is important, and confusing in Backbone. So make sure you kind of got a grasp of what's going where. Okay so, Does that make sense, like the events here, these are Backbone events, when something gets added, do this, when something gets reset, which is that reset function which we're calling with the fixtures, call this, and whenever something gets destroyed, do all this. Questions about that, pretty clear? Okay, going on.

  21. Filtering Let's try and render this now. Let's go back to our Backbone page, and we'll go here to the ng-todo, and we're going to go to, you can just change this to be Backbone. Okay, cool, so now like things are actually rendering, which is kind of neat, right? Got a nice little Backbone logo up there. And I'm on empty, cool, so, nothing works, right? You can change, but it's actually not perpetuating on the back end, or the data underneath, so. And same thing here, like you can change this, but notice like the thing isn't changing. So we still need to fix that. And if you remember, like, all the templating is coming from that Underscore line that I gave to you. Okay, cool, let's keep on trucking along, unless anyone's got any questions about any of that. Cool. So let's go ahead and start with filterCompleted. I feel like that's kind of the easiest one here. You have a question? I'm just getting an error, from TodoApp is not defined, so, in the, yeah, so, yep. So, make sure the TodoApp right there, right, the start, right. Okay. And then the router right here, like this window.TodoApp equals new, make sure that that's defined. Okay, go on, I'll catch up. Okay. Cool. So let's go back to models.js. Okay, and here we're going to do filterCompleted, which is going to be on the TodosItem, TodoItems, rather. We're going to do filterCompleted, and that's just going to be a function. Again, notice that we're not doing this in the view. This would be very easy to type the code into the view, very tempting, but, it's going to make you very sad later. Okay, so we're just going to do this.remove, this.filter, function, item. I'll explain the kind of craziness going on here, and return item.get, completed. Okay, this.filter, it's just kind of what we've been using in the other apps, right, like, filters the things that have been completed, and then, it goes and removes the, that array of things that have been completed. Did you find your issue? Yes. Cool. Pretty, I'm not going to say straightforward, but at least we've done this previously, so this shouldn't look at least foreign to you. Okay, and, yeah, put a semicolon there for good measure. So now we have the ability to do filterCompleted, but we don't have it wired up anywhere. So now we have to jump over to our view. So let's jump over to our views, okay. And here we're going to have a filterCompleted function, as well, in our todosView. I'm just going to throw it down here at the bottom. Sorry, another line with the comma. filterCompleted, function, okay. And all you're going to do is like this.collection.filterCompleted, this.render. And I'm trying to think about that, I actually don't even think I need that. Maybe not, I'll check if you need this.render. You often need to tell Backbone when to render, either by event, or by explicitly telling it. My guess is that I can comment that out. We'll see. Okay? So again, to repeat ad nauseum, very tempting to do this, just the filtering right here, right? Don't do it, it's just bad. Okay, so, let's go back to the router. And we're going to go into the initialize. So you know how I told you not to do jQuery event listening? It's, not going to say it's an accepted practice in Backbone, but it's at least common, and it's simple in this case, so we're just going to stick with it. And the other thing is that we're actually operating outside of one of the views, right, like, we're not actually going to render that view, or we're not going to render that button by a view. We're going to just put it right there on the page. In fact, you can open up the index.html, and see it down here, right, this Clear Completed is just right here, whereas the app is in here. So it's happening outside of a Backbone view, and so we have to handle that somehow. Very easy way to do it is just to do it in a jQuery event. So button clear, and we're just going to do your typical, run of the mill, .click. Okay. In here, just going to call window.TodoApp.todosView.filterCompleted. That makes sense, seems pretty straightforward. Okay, save that. I like to put them in the initialize, so like up front, you can see what's going on, what extra events I'm listening for. Kind of up to you how you wanted to handle that. I've seen people put them in different files. In this case, we have a small enough app, putting them in the initialize makes sense, so. All right, so, think that should be, should be working. Make sure I got everything here. Okay, let's just go ahead and give that a shot. Let's see, I'm over here. Okay, refresh, clearCompleted. I get any JavaScript? So I might need that render right now. It's my always my, do I need to re-render, or do I not need to re-render? That's always my issue with Backbone. I have being like, I've seen people who just throw render around willy-nilly. I would advise against that, it's not exactly cheap. It's not expensive either, but. So, there you go. It was actually happening behind the scenes, it just wasn't re-rendering, which is always, always a struggle, so. All right, cool, questions? So, I'm getting, when I click on the clearCompleted this last time, I'm getting the uncompleted ones appended. The uncompleted ones appended. How interesting, I don't know how you did that. Me neither. I'm impressed. (laughter) Unfiltered ones completed, I don't even want to start. (laughs) It's got to be close to the remove, right? Yeah, so I assume you're doing this remove, you're doing the filter, right? In return the item, getCompleted? Okay, I'm happy that, like, you can set that aside, I'm happy to come back to it later for you. Other questions, other crazy bugs like that? (laughs) Is it just like reorganizing them, or is it, it's just re-appending the same ones over again, so now you have more things than you had previously? Wow. I don't think I could even program that. Cool. Well not cool, but slightly amusing. Yup, found it. Okay, cool, I'm cur, I'm deadly curious, how did you do that? Missing set of parens in the call. Okay. (Laughter) There you go.

  22. Adding and Toggling Todo Items Let's go do the toggles now, those are fun. Let's go back to models.js. Okay, so this is going to go into the God, I have really bad notes for this, think it goes here, toggle. Okay, and then you're going to say, this.set, completed, and you're going to set it to be the opposite of whatever it is, right, so. Who you're going to, yeah, again. Set it to whatever the opposite of it is. Right, and what we're doing right now, is like the check box, right? That's ultimately what we're trying to achieve here. So this.get, completed, and we're just going to set that to the opposite as the completed. Pretty simple. Okay, let's go back to the events, or rather, the views. Look up there. Okay, and then, we're going to create another object right here. And you're going to see, this is actually one of the cooler parts of Backbone. It's going to be an object, it's called Events. Put a comma right there, and, we're going to do is change, on input, type equals checkbox, okay, and whenever that happens, call toggle, okay. And then here underneath it, we're going to call toggle, oops, and we're going to say, this.model.toggle. Again, you'll be tempted to just operate directly on your model from your view, do not do it. This is maybe the only case where I might, like, just shake a finger at you rather than be tempted to hurt you, because really, all you're doing is flipping a completed, right? Not a huge deal. Okay, and so, the other thing is, we're going to put an initialize up here. We're going to do multiple things on that toggle event. function, guess I'm being inconsistent here, okay, and this.model.on, change. As you might guess, you're just going to re-render. If anything ever changes, just re-render yourself. This is a pretty magic line. Well I said data binding is not free in Backbone, that line is essentially what makes that two way data binding work, right. Any time something changes in my underlying model, go ahead and update yourself, so. Now notice that there's, the events object, and there's the this.model.on, right. They're both listening for events, but there is a slight difference on where the events are. So the model, I'll just do it here. The model, it's happening on the underlying model, right? And they're like events, they're like changes, deletions, adds, things like that. The events here, rather, are coming from the DOM, right? And it's actually happening on the view itself. Okay, so the special sauce to this is, the first part is like a reserved word that Backbone has, maybe a dozen or so, and I believe you can also define your own. So that's, the first part is the name of it, the second and, like, the rest of it I should say, because you can have like multiple nesting and stuff like that, is just a jQuery flavor selector. In this particular case, any time any checkbox, which this is probably bad idea, you should probably put a class on it and listen for the class, but lazy instructor, just listening for any changes on inputs that happen to be checkboxes, okay. And then the last part is, what function do you, what is your event handler, right? So in this particular case, the toggle actually is receiving the event. We don't care, we don't care where it came from, as long as it's. Oh, and the other thing I should say is that, Backbone does actually like give you a little bit of scope to it, right, because there are multiple checkboxes, in multiple different todos, but Backbone is smart enough to say, like, this change happened for this todo, so only affect this one. In chat, someone's commenting, I should say, Jason's commenting that you should be using this.listenTo, model, change. this.listenTo, listenTo is a new thing in Backbone views. Okay. And the benefit is that you remove the view, the event listener gets cleaned up, whereas in the way you're currently doing it, the event listeners don't get cleaned up, and you have to do that manually. Oh, interesting, well there you go. So this.listenTo is, I think, a little bit newer. Right here in the initialize, is that what he's saying? Yeah. Okay. So it's like this.listenTo, model, change, this.render. Okay. Which is roughly the same thing as this. Cool, well I appreciate that. Like, definitely look into listenTo. I'm not familiar with it, so, we're going to charge ahead with the old paradigm, just like any good engineer would do. But definitely look into that. Thank you, Jason. Okay, so, I believe we should work now. So, yeah, check that business out. Things are getting crossed and uncrossed, it's just musical, okay. Questions on that? Yeah, I can see that, event listeners being a problem. You could get memory leaks if you had a lot of adding and removing of stuff from the DOM, so. Very cool, did not know that. See, this is why I need the online crowd to just be like, I need like 80 people watching me code at any given time. (laughs) That's awesome. Okay. Think, think we're good there. Oh no, okay. Completed, model, events, toggle, okay, back to router. Okay, we're going to add another jQuery listener in here. And this one's going to be for the new todos, kind of business that we're going to have. So button success, again, lazy developer, this is not about semantic naming of your, stuff, so, call this something more like, Your New Todo Adder, or something like that. In your selectors here, on the global document, and you should always be scoping into the view. Yes. Oh wait, this is the router, never mind. This is the router, so. Go ahead. Yeah, like this shouldn't be on the global document. Yeah. Yeah. You're fine. I lost my place again, okay, well anyway. Button success, .click, function, function, okay, and in here, we're just going to do, window.TodoApp.todoItems.add, and here, we're just going to make the value a, Hero's actually smart enough to put an ID, so a #newTodo dot val. This should all look very familiar to you, completed, false, okay. And then we're also going to set new Todos, .val, just going to blank it out, okay. Should be pretty straightforward, right. We're just adding a new value to our todoItems, with the value of whatever's coming out of that new Todo, and then we're just blanking it out. This is just vanilla jQuery, nothing too Backbone about it. Okay. And, that's it, right, let's check that out. Okay, other cool thing. Magic, just kidding. What's really happening here is like, we've actually just written already all of the wiring, and now Backbone is just like, "Okay, I get it now." And so some of this extra functionality just comes along with doing your wiring really well. So in this particular case, remember that we had like this.colllection.add, or onAdd, then just like, addOne? So, that's kind of like the, it's black magic that you're created yourself. So slightly less black, maybe like gray magic, or something like that, but pretty cool, right? Okay, code re-use, it's a beautiful thing.

  23. Two-way Data Binding Let's go back to views.js. Let's go ahead and start like updating, yeah, updating like the, when the view, someone starts typing in the view, we want the underlying data to change, to update, rather. Because right now, only the input's updating, and the underlying model is not quite updating yet. So in the events for here, okay, you're going to do change, form-control, and here, you're just going to call a simple update function that we're about to write. Okay, and then we're going to do update, text, did I call that text? No, I didn't, okay cool. function this.set, val, text. And it takes in text, too. Okay, pretty simple. I'm mixing shit up here, sorry. update, so, sorry, that's what goes in the model. It's this.model.updateText, this., so this is a neat little trick in Backbone, I'll about here in just a sec. But essentially, you can do like scoped jQuery selecting, which is kind of fun. Okay, and then you're going to do val. Okay, so that's exactly what this is, the dot dollar sign selector, it's only going to select from within that particular view. Okay, don't need text in there. So now I have to go back down to the model, and update text, so we're going to write updateText, function, and I just kept it, or I just copied it, so it's going to be this.setVal, text, voila, that's it. Text is a parameter in the function, that you're passing in? Now it's voila, okay, thank you. (chuckles) Okay, so now that, like, you can't actually see it being updated, right, but it's being updated, so, you could go back and type, and it should work. So. Let's go ahead and do the removes now. So going back to views.js, in here, so here, you're going to do click, button danger, okay, and then here, you're going to call remove. And then you're going to write a remove function, okay, and then you're going to call this.model.destroy, destroy is actually a Backbone function, it's going to fire off a destroy event. You just have to tell what to do on the destroy event. So let's drop back down into models, okay, and this is actually going to go on the todoItems, because what's really happening when you destroy something, is it itself is not really getting destroyed, it's just getting taken out of the collection. So here, we're going to need an initialize, okay, and you're going to have to say, this, dot, or this.on, right, because it's happening to itself. destroy, this.removeElement, this. Okay, and then removeElement, function, it's going to accept the model, this will actually, because this is destroy, it's going to hand its, the model back. All you're going to have to say is this.remove, model. That should be it, let's go check it out, making sure it works. Okay, so now things get deleted.

  24. Backbone QandA Trisha says, "Now that "we're going through this, I'm having a hard time "figuring out why someone would use Backbone. "Looks like you have to write the entire thing yourself. "Is it better if you need really custom functionality?" Yes, it's like you have very specific functionalities. It's really good for that, and the other thing is like, once you have like a Gmail scale app, right, you have like 10s, hundreds of thousands of lines of code. Sometimes these frameworks that enforce their opinion on you can be limiting. So rather than those opinions really helping you and get you started, right, once they start getting huge, they become limiting factors. They kind of like build walls where you don't wall, do not want walls to be. So the question then becomes, like, how much control do you want over it? Like, one of my co-workers at Reddit, chromakode, Max Goodman, just brilliant developer, and he just demands control over everything. And so he doesn't like these new frameworks, he likes Backbone, because it gives him that granular level of control, yet it helps him organize his code in a cohesive, sane manner. So if that's what you're essentially looking for, is just cohesive, good organization to your code, Backbone provides that. But if you're looking for a bunch of like, wrapped in, like, "Help me get, build these apps super fast, "and be really productive about it," don't write vanilla Backbone, I'll put it that way. But that's a great comment, so. Questions, comments, this is it. This is all the Backbone code, so. What are your thoughts, like, The template that, in the view, could it be in a file, I mean just load a file easily, that syntax that you've shown us? Let's go back here and show you. You're talking about like this huge, ugly thing? Yeah, that one right there, the template. So like, can you pull it from another file, is that what you're asking? Yeah, something like that. It's certainly possible. I don't think Backbone does it out of the box, I think you would have to write it, or whatever. But, that's certainly possible, I'm sure. One thing I noticed about our, we used Backbone at a (muffled) job, and we switched to Angular. And one of the big reasons we switched is, maybe the React will deal with this, but, with Backbone, when you removed a field, you re-drew that whole table, not just like, it got removed, it moved everything else. And so like with Backbone, you're always rendering more than you need to, and with Angular, you render only the change. So like with a text field change, it won't render beyond your div, and stuff like that. So it was much more targeted on divs. Yeah. Definitely, that's definitely a problem with Backbone, it being inefficient with its paints. If you do it with, if you pair React with Backbone, that will take care of that. And you can also be a bit more picky about how you do your re-renders. I did it the dumb way, which is also the common way. The dumb and the common way, so. That's good input, for sure. I just have one little comment. If you break that into subviews, and the parent view, then you have much more control over the app, and what portions you can render, rather than, you know, fully rendering it, you can just render your subviews, others can stay still the same. So, I don't know if that was considered. Definitely, so I mean like, it's not going to re-render your entire app, right. Like, it's just going to re-render what's changing. Like, the (drowned out by attendee) You don't know, it could be like a really large app, and it starts getting really complicated managing it. So then you're only rendering the minimum amount, starts to (too soft) Burdensome, for sure. Well, the most inefficient part of the browser that we're ever going to deal with as front end developers, is the DOM. Right, like the DOM is just, huh, I have lots of good to say about the DOM. It's just not fun to deal with sometimes. So, yeah, definitely. And for the templates, it's possible to kind of move it and break it into, you know, we used Require.js, and it comes with the handlebars plugin. So with that, you can have pre-compiled templates, small portions, and then, no matter where you want to be. That way, it's much more modular. Don't judge this particular framework based on that, like, ugly template thing going on right there. Like, that was just like, the minimum I could put there, so I could gloss over it, because I didn't want to talk about. Because any templating can go in there. You can even write your own templating, if you want to. Like, you can throw a function in there, and have it just return, like, whatever markup you want to do. This particular case, just wanted it to be fast and easy. They're basically asking, well Sandra's saying, "My boss got into Angular, "and we're architecting in SBA, "single page web app. "But, we would like some guidance "on how to implement web sockets in Angular." And then Nate seconded that, then, wanting a quick thought, or your comment on using web sockets with Angular. Yeah, so, as far as I know, no one has native, or when I say native, like, built into the framework, support for web sockets. So no matter what you're going to use a connection, or some sort of a, what's the word I'm looking for, like a plugin or an extension there. So that being said, I do recall seeing, someone has written like a specific Angular web sockets plugin, that you just inject as a service, and use it that way. So, that's easy. I'm not fully aware of any Backbone ones, but I'm positive it exists. Yeah, it was purely around Angular, they're wondering. Purely around Angular? Yeah I mean, I would first, like, search Github for Angular web socket stuff. I have, I don't have a lot of experience in it, so that's, I would just search for it, and see what other people have done about it, like Stack Overflow or something like that. More questions? That was it. Okay, cool, yeah web sockets, fun stuff. Any other questions from you guys about, Backbone, How do you test Backbone, maybe just in a, Backbone's a tough one to test. First of all, it requires really well written code, and the easiest part of Backbone to test are the models, particularly if you've taken my, like, repeated advice to put everything on the model, and nothing on the view. Then you can write, like, Jasmine, or QUnit, or Mocha, or Xenon, or whatever you want to do. And you just instantiate a model, give it some data, and start testing it, testing the functions and such, that make sense? There's no injection then? Is there any dependency injection? Not like built into Backbone. So you just have to roll your own, or maybe there's one, I haven't seen one, so. That's what's tough to say about the Backbone community, is it's huge, it's been around for a long time, so there's just a lot of stuff around it, so. I'm sure you're not the first person that asked that question, so maybe someone did it. Other questions? All right. Another question about how testable these frameworks are, but I think we covered that, kind of. I'm, we'll revisit at the end.

  25. React Setup Now we're going to go into React. React is kind of like new fanciness. It's Facebook's, it's Facebook's little child that they've been doing. All of Instagram, their web client is React. The comment feed on Facebook is done with React, and I think there are more components, but those are the two that I know. So this is a bit of a departure from what we've been doing so far. This not a full MVC. There confessed to be just the V in the MVC. And actually, they actually prefer to use an entirely different architecture called Flux. And we're not going to be talking a whole lot about Flux today, despite the fact that our app is actually a little bit Flux-esque. It just means that data only flows one way, right? It goes from, you have a component, and then from the parent component it goes down to the child, and down to the child, but it never goes back up. The only way to get data back to the parents is you have to go and basically dispatch it from the top and then from the top it then flows back down. So the data is always going like that. It makes it very easy to see what's happening to your data, because whatever is operating on the data, it lives next to the data, so really cool. And we'll have examples of that. So something a little bit different that we're going to have to do this time is that before we've just been working on the file protocol, because we're going to be using JSX transformer, we actually have to create a simple static site server. You can do that however you want to. Most people will use like simple HTTP server, or PHP-S. I'm going to use HTTP server, the node one, because that one's that simple So let's go ahead and open this up. We're going to have... Yeah, in fact, let's just go ahead and take a look at how that happens. So we're going to go over here. I have a my terminal here. Where am I? So I'm going to go to talks/jsmvc-pres/empty talks and react-todo, okay? So let's just clear that out. I'm just here in my react-todo file. If you have node, I'm not going to show you how to install node, but just a npm -g install http-server, if you want to use the one that I'm going to use. We're only going to do one thing in here, so it's not a big deal. But you're just going to do http-server. And it's just going to go, it just starts up your server, really easy. That's all we're going to do on the terminal. So we're going to change this to be, oh, that's not I wanted to do. We're just going to change this to be on 127, I think it's on 8080. Nothing there yet, but it's loading so- How did you start it from the terminal? Huh? How did you start that from the terminal? Just http-server, that's it. You just had from inside of the directory. From inside of whatever directory, right. Yeah, because right now I'm in react-todo. It just creates a web server from that directory. Thank you. Starts up the server, 8080. And then I moved my browser, so let me just move that back. So now I have react-todo, that's it. All right, we're going to be working in, if you've noticed, some of these are JSX, app.JSX, components.JSX, then everything else is just, yeah, normal. What is JSX? JSX, like Coffeescript, like TypeScript, like PureScript, like any of those other things, it trans-piles into normal JavaScript. It's not necessarily have to be paired with React, we're just going to be using the React full part of JSX. You can write React without using JSX. It's just painful in my opinion. It looks just like JavaScript, it feels just like JavaScript. The only part that's different about it is that you can put pure markup as if it was its own datatype into JavaScript. It's going to look weird, but it's kind of cool. So you can be the judge of that. You can feel free to do it without, yes, and so typically, if you're in production you would have something like Grunt, or even just the JSX tools, compile out your JavaScript. Right now we're just going to be using the JSX transformer. It's just a file they include that actually does the JSX compilation on the fly. So we don't have to be running Grunt in the background, or something like that. Yeah, so let's get started with that. This is always why we have to run the HTP server, is because JSX makes Ajax requests go grab those. You're going to get a cross-origin error if you don't use a web server. So, yeah, that's something JSX transformer is, it's like 10,000 lines, crazy.

  26. Bootstrapping One of the first things about this, and we'll just do it in both of our files real quick, is you're going to have to put this special comment at the top. This just lets the JSX compiler, whether it be the transformer, or the one that you do before, please translate this file, otherwise it will not translate it for you. So I'm going to put that in the app, in components, because this is the only two that we're going to be transforming. So, there you go. All right. So this is a little bit of Brian Holt flavored React. Like I said, React does not actually have any structure around it. There's no data layer, there's nothing like that. As such, we're going to kind of roll our own data layer as we go here. So I'll be sure to point like this is React stuff, and this is just Brian Holt throwing bull (bleep) on the screen. First, we're going to throw some bull (bleep) on the screen. So we're going to say var app = app, or new object. I like to separate all my components out onto different files. Like I have the communicator, I have whatever was going out and doing Ajax requests. I have what's actually doing the rendering, the different components for the different pages, all separated into different pages. As such, you don't want to necessarily care what order you're bringing them at, bringing stuff in, which is what this line serves, right? If I already have an extent app object, go ahead and use that. If not, then go ahead and create a new object and we're going to start building on that. And then we're going to wrap everything in an instantly invoked function expression. Again, I don't want to get too much into just vanilla JavaScript stuff, but this just a vanilla JavaScript-- We have plenty of stuff on the site. Okay, so, yeah, go buy two years of Frontend Masters, and just watch all of it multiple times. But, yes, nothing Reactful thus far, this is just all Brian Holt-flavored stuff. Yes, oh, yeah, you're just going to throw use strict in there, just for good measure. Let's go ahead and save that. This'll be a pretty short file, so most of our stuff's going to be done over in components. Just that same var app = stuff, var app. This is essentially at the top of all my react files. Sorry, app. Okay, and then I'm going to do app.components, because a lot of times it'll have multiple files adding components as well. Equals app.components, or object. Again, instantly invoked function expression. And a use strict. All right. Now let's actually get into making some real stuff happen here.

  27. JSX So we're going to do var TodoApp. This is going to be actually like our root function, our root component, rather. app.component.TodoApp, so this is more Holt-flavored React. We're going to do a double assignment here. And I'll explain to you why that's useful here in just a sec. React.createClass, now we're actually going to get into some real React. And we're going to do a render function. That should sound very familiar to you. And then what you return out of this render function is actually your markup, So parentheses, put that on a new line. And guess this is where this JSX craziness is going to start coming in. className="outer-container" Interesting text goes here. Did that just look bananas to you, right? Like you're just throwing HTML, like there's no quotes or anything like that, we're just throwing it out there. This is what JSX is. If you don't like this, you don't have to use JSX, and what you're going to do is create functions, or not create, but call React functions that are going to create those for you. However, I think just being very declarative and having markup in the end is going to benefit you. Something worth mentioning here. Because of how JavaScript works, and how JSX is, you're going to have to call it className and not class. And just the reason for that is class is actually a word that is used in JavaScript, so they have to call it something else. In this case it's going to be className. So everywhere that you want to do a class, you have to use className. You're saying do you need the parentheses in the return? No, you don't. But the reason why is otherwise you have to have the spline up here, oh, sorry, right there. That looks weird to me. So the Reactful way of doing it, as a far as I've seen other people's code is to put it on a new line and have the parentheses surrounding it. Makes for cleaner looking markup, in my opinion. Yeah? Is there any other keywords like class and className that you have to be aware of? Not off the top of my head. We'll start doing other things, but they'll be React-specific. Everything else should look just like totally normal markup. Oh, I was going to talk about this later, but this segues into a good question. So normally you have inputs, right? And, don't copy this, but typically that would be valid markup for an input. If it's a void TAC, you always have to have the closing trailing /, just because JSX is depending on that being there. And furthermore, though, I don't suggest it, you can actual do that, and that would actually be valid JSX. So don't, it's weird, but you could. But, yeah, like inputs, images, all that stuff, they need that trailing /. Does it give you like a compiler or something? So one thing that sucks about React, in my opinion, is their errors are just awful. And a lot of times it'll swallow errors, which is even worse, right? Like it will just not render, and you're like, what happened? And React's like I'm happy, why aren't you happy? (laughs) So, yes, that's an incredibly frustrating part of React Okay, let me just make sure I covered everything I meant to. This is the magic of JSX, yeah, cool. Oh, there can only be one root element. Okay, so if I did like this,
    and had like another div down here. This doesn't work. JSX needs your components to have only one root div. Even if you just surround it in a div, it also doesn't have to be a div, but it has to have one parent container. Okay, any questions about that? We'll display it here on the page in just a sec. So we're going to go back to our app. And we're going to have app.init = function, again. This is more Holt-flavored React right here. And you're going to have var TodoApp = app.components.TodoApp. So if you remembered I have this double assignment over here, this is why I do that is because I want it to be available in other scopes, right? Like this are not up, yeah, other scopes, right? And so in order for you to be able to create a new component, it has to be available on the local scope, and not just like one some other inside of an object, right? So, in this particular case, we're pulling it out of the components and making it available in this function scope right here. And as I code a couple more lines, that should make a little bit more sense. Oh, there we go. Okay, and then here we're just going to do React.renderComponent, We're going to have a and then we're going to have a document.getElementById This is just vanilla JavaScript. ("app") That's comma right there. Just to recap what's going on here, so we're making this TodoApp available, which is actually getting called right here. That's how JSX is creating these is it's turning those components into function calls. And, thus, it depends on a ToDo App function being available, which is exactly what this is doing. This is pulling out the ToDoApp, making it available for it to be called right here. Does that kind of makes sense? It's weird, right, but it works. because the other thing is like you can try and do this, app.components, but that doesn't work. It actually has to be out and available. Okay? And this is just a void tag, right? This is like a void tag for a component. You'll see that more as we get further and further in, but essentially we're saying we want a ToDoApp component rendered at the App ID. Let's go ahead and save that. Oh, and we also need to call the app.init as well, so we're going to say app.init(); here at the bottom. And that's just actually going to get our app up and rolling. So refresh. And unexpected token. Line 12? Trailing symbol. Oh, yeah, that's dumb. I just like semicolons everywhere. Now we have interesting text that went there. So we kind of see like the connection of how that's getting on the page? Okay, cool.

  28. Creating Components All right, let's just start going crazy with this stuff then. So we're going to go to the ToDoApp, we're going to do a little bit of boilerplate here for just a second. We're going to have a NewTodo. We're going to have a TodoList, and we're going to have a ClearCompleted. And these are all different components that we're about to defined. And so now if you tried to run this, it would error out because none of those functions would exist. So let's just go ahead and go and just kind of boilerplate these ones out. So var NewTodo = app.componenets.NewTodo. In this particular case, you can leave out the rest of the double assignments. I find it to be best practices. And I guess that's another thing that bears mentioning. This is a really young community. So the best practices are still kind of emerging. So while this might be my best practice today, I'm sure someone's going to say "that's stupid" tomorrow, and maybe even today, and say, "You should do it this way." So try and focus less on the app structure. You can build it however your heart desires, and focus more on what the React stuff's going on here. render;function, Return, and I'm just going to put an h1 in there that says, just let me know what it is. h1-- Can you scroll up a little bit? There you go. And that would now work for the new Todo. And let's just be dumb and copy and paste this twice. And we'll just change the names here. So we called this one TodoList. And just change this h1 to be Todo List. And this one we called ClearCompleted. And Clear Completed. Okay, so, in theory, now it should render, right? because now we have all that stuff ready to go. That was a lot of typing really fast, so I'll give a sec to catch up there. Any questions about going on here? It's pretty basic React, so hopefully makes some sense. So let's just check it out, see what's going on. Right here, refresh the page. Now we got some h1s on the page, New Todo, the Todo List and the Clear Completed. So these are like individual components, and now you've actually witnessed that you can compose components of other components, right? So they're nest-able, which makes them really powerful, right? Like we have one for displaying products on Reddit Gifts. That's just a React component. We coded once and now we can throw it all over the site, wherever we want to, it's pretty cool. And makes them testable, which is nice little feature, too.

  29. Component Lifecycle Let's go back to the TodoApp, yeah, this top one right here. So there are several functions that get run throughout the lifecycle of a React component. One of them is a getInitialState, okay? In this one, we're just going to return an object. And it's going to have one properties, and it's going to have a Todos, that's it. So let's take a second to talk about properties, or props, versus state. So as I told you before, data only flows down through React components, right? So from parents down to children, but it does not flow up. So the way that it flows down from parent to child is that there is this idea of props. So a parent can pass properties, it can pass data down into children, and the children receive them as props. However, a component can keep its own state. And why that's important is that you cannot modify props. Meaning that a child cannot modify its parents data, it can only receive them and operate them, or just they're essentially read-only to a child. Rather as state, the state is mutable, right? So the state is only kept on that particular component and it's only accessible, it can't be accessed from the parent, it cannot be accessed from the child, the state is only available on that component level. Now this seems a bit a semantic, we'll actually get into it and it'll actually start making sense of why that is. So the getInitialState, right? Since a state is only existent on that particular component, there's this ability to create an initial state. Here we're creating an initial state of we have Todos, but we have not yet received what those Todos are. In most cases, what you would want to do is you want to go out, make an Ajax request, get your state and then, yeah, bring it back and set it as that state. So let's take a look at what that would look like. We're going to use fixtures again, but we're going to treat it as if it was an Ajax call. So we're going to call this function called componentDidMount: function() (), comma, okay? Again, this is a react function. There's this idea of this component mounting. Before it mounts it calls componentWillMount, which just says "I'm about to go out into the page, what do you want me to do before I go out in the page?" And this one is componentDidMount, it means like, "I'm already on the page, now what do you want me to do?" So, typically, you want your app to go through and render once, and so you get a perceived page load. And then after that, you want to go out and make your Ajax request, right? So something shows up and it's like, oh, hey, wait a second, I'm still going to make some data requests, but here's some pretty things while I make these requests. So you're going to have var data - app.retrieveData(). This is just whatever, whatever you want to use to go out and get that request. You could actually put your Ajax straight in here if you wanted to. You can split it out if you want to. As you can see here, React doesn't really care how you get your data, how you store it. React is solely concerned with "How do I render it and how do I update it from the UI layer?" So we'll write that retrieveData function here in just once second. But we assume we have that data. We're going to say this.setState(), and we're going to set the state to be todos:data, right? And then if you want to, just so we can see that it happened, we'll just do a console.log here, console.log(this.state), just to make sure that things are actually happening, yeah. Well, you're saying make the Ajax request after it mounts. Wouldn't you want to make the Ajax request as soon as possible, and then after it's-- After it mounts then-- After you have that data available to you. Yeah, I guess the thing in here is like you don't want to block your UI from rendering. Now, you can use a promise to make that asynchronous. So I guess the best response to that question is I'm not entirely sure. This is just how React, like if you go to React's website, this is the way they do it in their tutorial. And this is the way that I've seen React code through it. So you're saying you mounted a component, now in its state. Yeah, well, and another very interesting thing that we're going to get into in a second is that React has the ability to pre-render its HTML, which is pretty super cool, right? Like you can have your node server go out and just pick up your React and render, because it's all just JavaScript, right? And it's all just returning like this made up markup. And so that would make sense that you would want to send the pre-made HTML down to the server, then it's down to the clients. The client picks it up. React then reads the dom and then it recreates that virtual dom. And, after that, that's when you want to go out and request and say, let's go with user details, and stuff like that. So there might be some fanciness that you could do that starts the Ajax request first. Then renders, and then updates the dom with that. That's worth a shot. That's an interesting idea, just one I haven't yet considered. But, yeah, this is the way React does in their tutorials, and all the React code that I've seen out in the wild. Do they do all their Ajax-ing here in componentDidMount? I think another part of this is that you want to make your components able to render without data. because your first render is going to be without any data in it, so that you'll essentially have all those bases covered as well. This is all extremely fast as well. So doing the call beforehand and the call afterhand might not make a lot of difference. So, anyway, let's go back to our app real quick. Here we're just going to return some fixtures. Just do like app.retrieveData. The way I've done it thus far is that I'll have like a communications object that goes out and grabs my Ajax data. And then it just returns a promise, and then I operate on the promise inside of the componentDidMount part of it. That's an easy pattern to get that done. I do have a fixtures.js for you here, it's right here. So nothing fancy here, right? It's just putting on the app object. We're just going to return that data. So it's return app.FIXTURES. Again, this is not a React thing, this is just me being helpful. Let's just go ahead and see if that's working using that console.log. We'll just pop up our dev tools right here, refresh. And, as you see here, we get a console.log with all of our Todos here. So it's kind of the workflow for that. Questions so far? Does that makes sense, the way that's getting done? Okay, cool.

  30. Passing Properties from Parent Let's go back to components. Here in the TodoApp.Render. We now have that Todos, right? What's going to be displaying those ToDos? It's going to be the TodoList component, right? So now we're going to start passing some props down from the parent state, right? So what you're going to do here is you're going to do todos= then anything between these single curly braces is going to be an expression that's going to get run. So in this case, it's going to be {this.state.todos}. So this is essentially React, I have this TodoList component, and I'm just putting this on multiple lines for clarity, because typically you're going to have multiple props you're going to pass down. So from the TodoList, we're going to pass down these todos to the TodoList component. It's going to be now a prop on the TodoList, So let's save that. Let's go actually code up the TodoList now. So Todo List right here. Let's put some space in here. So, unfortunately, you can follow along with me and write my own markup, but "todos". We're going to write another one of these expressions. This one's kind of fancy. This is essentially how the ng-repeat, the $.each, whatever, the addAll, this is the equivalent in React. What's kind of fun about it is it's actually vanilla JavaScript. So we're going to say {this.props}. Remember how I've been talking about props? This is what I'm actually talking about, {this.props.todos}. And, again, that's coming from here, up here, these todos match up with these todos, Going to do a .map, which is just that es5 function, el, index. And here this is just a function that's going to get run. And here we're going to return another component that we're about to define. And this is going to be called a TodoItem. And we're going to give it the todo, which is going to be (el), right? And we're going to give it the index as well. This'll be important for modifying the data structures there, because then we can let it know it's this index in the array, makes it super easy. So we're just going to say index={index}, And these are now going to be props on the child todo item, which we have yet to write. You're going to close that tag as well. We don't have anything to show for it, yet, but any questions about that? Does that make sense? Or maybe it'll make sense in the next five minutes as well. So var TodoItem = app.componenets.TodoItem = React.createClass. And here we're just going to have another render function. Scroll down a bit. Yeah, good idea. Okay, so we'll do a little bit more interesting things here. We're going to have an inputClassName. So if you remember correctly, or from the other previous examples, when you click the checkbox, it applies and unapplies a style, or a class, rather. That's what we're going to do right here. So it's always going to have the name form-control. And if(this.props.todo.complete), then inputClassName, we're just going to add that finished on there. So this is just simple string concatenation. If it's completed, then add a finished class on there. And then we'll just stick that string as the class name. Unfortunately right now, React isn't much more clever in its ways to do it. They have another thing called React Class Set, I think is what it's called. But, in my opinion, it's not much more easy than this. So do what works best for you. In the previous function, do you need to close the div tag? Did I not do it? I did not. Good call. So, yeah, in that previous one, you need to close the div tag. Thank you. Going back here. Just pack up what's finished. And now we're actually going to start coding up our return statement, which is the actual component itself. Okay,
    That's what we were doing all that string concatenation for, so that's what goes there. You just put it between the curly braces again. And it's typed text, and then again, closing /.
  31. Modifying Data So we're going to go all the way up to the To Do App. So, again, we kind of addressed this a little bit, but this is actually putting the rubber to the road, is that what modifies the data needs to live next to it, not only should it, it just has to, like pragmatically it must. So where is the value actually being stored? It's being stored in the state at the parent element. So that means all of our functions that modify it have to also live at that parent level. So we're going to do updateVal: function. And that function is going to take both val and index. And this is just pretty simple var state = this.state; I just do that for readability. state.todos Here, we're just doing simple updating of an array in JavaScript. And then we're just going to call at the end this.setState(state). Nothing too fancy about what's going on there. So one thing I should say, you've probably noticed right now that I probably, at the beginning of this, just could've just said this.state.todos Now we're not doing that, and we're actually using the setter right here for setState. Why is that? So that will actually will update the data, but it will not get all that neat functionality around that call, it's the re-render for you. If you did that, it wouldn't detect that something has changed, because it's not doing any dirty checking, like Angular, or anything like that. So I think what you'd have to do is like this.forceUpdate(), believe that would work, not entirely sure. Doesn't matter, this is an anti-pattern, don't do it. Instead do this. Like if you called the setState, then it knows like, oh, okay, stuff updated, it's time for me to go through this re-render process. So now this is in the parent. So now we need to actually call this from the child, right? because the child knows when it gets updated, so how do we do that? Let's go down to the TodoList, and we're going to say, right under the todos right there, we're going to say updateVal=(this.updateVal). You can pass values, but you can also functions down, right? So you're just going to pass this function down until you can use it. So, again, we need to pass it from TodoList. Oh, sorry, scroll back. Just right there, that's all we put, was the updateVal, which is just referring to this updateVal right here. And then down here, we're going to want to pass it down to its child, right? because that's actually what's being called. So from the TodoApp, to the TodoList to the TodoItem. So we're going to say updateVal=(this.props.) because it's coming from the properties, (this.props.updateVal). However, we're into a bit of an issue here, just speaking on JavaScript terms, that what does this refer to in this context? It refers to Todos, the actual array, because that's what's being mapped over. So we have to change the context right there, if you can see that, that first one, at the end of the function. We're just going to put a bind, right? .bind(this) That's just changing the context so that this, this particular this, right here, refers to this that we're thinking of. If you want to, I have no problem with this. If you want to say like var _this = this, or var that = this, and then do like _this, that works, too. Totally okay with that. I just like using bind, because it makes me feel cool. Actually, I think it's more expressive, but whatever you want to do, that works for me, too. That bind you said was just JavaScript function? Yeah, that's es5. Yeah. All right, thank you. Cool. Now we're finally down into the TodoItem. Let's go ahead and make that update value happen. So it's going to be on the change of this, so you're going to say onChange. Make sure I get this right. Okay, jumping ahead a little bit. This'll be fine. (this.handleVal). So I'm going to warn you of another anti-pattern here. It's really tempting just to make your parent handle the event, right? But that makes it less flexible. What happens if you have multiple things that call the updateVal? And it doesn't even necessarily have to come from the dom, it can happen programmatically, right? So you want that update value to work in multiple different context. So don't have it so you have to create some synthetic event that you have to pass into it so you can update the value. Just make the thing that operates next to the view, make that handle the event, and then make the thing that handles the data, make that just handle the data. It's just separation of concerns. So in this case, we're going to say handleVale: function, it's going to take in that event. So handleVal, and all it's going to do is say this.props.updateVal, I'm going to say (e.target.val), this is just normal JavaScript, right? Sorry, value, if you want to do normal JavaScript. And this.props.index);. I think that should work. So, again, this is just calling the updateVal, which is calling this, this properties up here, which is then calling, eventually, up to this function up here, handing it the val and the index, which is just using to update there. Any questions about that? Let's see if it works. So refresh. Now you can actually type, hooray. Who knew that would be such an accomplishment, so you can type in an input. Cool. Well, we're just going to use this pattern, and we're going to finish out the rest of those functions.

  32. Finishing the Interactivity So let's just write the rest of those functions. We're going to do toggleCompleted. Not going to take anything. And var state - this.state, oh, I suppose this needs to take an index still. It does need a value, state.todos and it's just going to equal to whatever the opposite of this was. Oh, just go right there. And then this.setState(state). Simple enough. Let's move that up so it's little bit easier to see. And while we're at it, let's just go ahead and do the delete as well. It's going to look really similar, again. deleteTodo: function. And this takes and index as well. Oops, anti-pattern. So I've actually done a bad thing. I'm going to reorganize my code a little bit just so some best practices I found, usually I have the React reserve functions, like componentDidMount, getInitialState, I'll have all those at the top of the component, I'll have all of my personal operation functions in the middle, and then the last one's always render. because then you can look down at the render, see what's happening, and look up, and see everything that's happening at the top. It just makes things easier to digest, right? So I'm going to move this componentDidMount up underneath getInitialState. And I usually have getInitialState as well be the first thing that I see. Just kind of have it kind of follow the lifecycle of the component. It makes it easier to read down and see what's going on. Okay, so going back to toggleCompleted and deleteState, we're going to have var state = this.state. And what we're going to do here is state.todos.splice(index) and we're just going to take one out. And then we're just going to do this.setState(state). Could you split that into three lines, because usually you have a lot more functionality? Yeah, so I operate on the state as a whole object. And then I go back at the end and set the state at the end. That's just an easy pattern I found. You could actually operate on this.state everywhere that you see state, just don't recommend it. Questions about that? My personal question is how does updateVal get called? Is it a React thing? Yeah, I'll show you. When you do something to an input, it just calls updateVal on-- It's not a React thing, so it's something that we defined. And I might've glossed over a little too fast, it's this onChange right here. Oh, okay. So it says handleVal, but-- And then handleVal is just something that we wrote right there. Oh, okay, yeah. So, yeah, all that's user-defined. So we're going to get into link state here in a sec, that just makes that a little bit easier. But, thus far, that's all been user-defined. Other questions? That's a good question, I think I went a little fast. (mumbles) Line 19. Line 19? Or 20, yeah. Update val, so, yeah, that's when it's actually doing the updating. So we have that updateVal that we created, then we passed it down from this one, to the TodoList and from the TodoList the TodoItem. And then that function is then being called from the handleVal function right there. So right now we're writing the handlers for the other two operations that we do, which is toggle and as well as delete. So we just wrote toggleCompleted, we just wrote deleteTodo, those are pretty straightforward. Any questions about those? Cool. So this is going to look just super similar to what we're doing, We did toggleCompleted=(this.toggleCompleted) and we're going to do deleteTodo=(this.deleteTodo). Sorry, I'm getting some errors, and I think it's on the previous one. They're warnings, actually, says "You provided a checked prop" "You provided a valued prop" on this one. React's just essentially telling you you did something really stupid, which is like you can't give them an input that they can't do anything to, which is what we were just looking at, right? So they're just warnings. I'm getting them, too, I'm sure. Yeah, I just filter them out now, because (laughs) I have so many of them. Which of these messages held. First of all, we're using the dev version of React. The production version won't show warnings. But, yeah, this is just React saying "You're dumb." Like "Why do you have only read-only inputs?" We're about to fix that, and so they'll go away when we fix it. Okay, so it's basically where all those inputs are that don't have that. Yeah. Okay. Like, notice, I have 110 warnings. That's not good. Okay. Cool. So toggleCompleted, deleteTodo, we just put those on the TodoList. We're then going to go use the TodoList and pass that down to the child. So here, let's scroll up, toggleCompleted=(this.props.toggleCompleted) and deleteTodo= (this.props.deleteTodo). We are now going to go all the way down to the child, and we're actually going to write handlers for those. So we're going to do handleToggle: function(e). And all we're going to do is this.proper.toggleCompleted. And we're going to say (this.props.index), Pretty simple. It's the same thing with handleDelete: function(e). You don't actually need the (e), I just do it out of force of habit, this.props.deleteTodo(this.props.index), because you don't actually need more data than just the index to delete it, right? Input, you're going to do oneChange equals (this.handle.Toggle) and the button down here, you're going to do onClick=(this.handleDelete), okay. Yeah, and this is kind of application of what we did previously. Any questions about that? Should hopefully make some sense. So now these operations should work. Let's just go check it out. We can check and uncheck, right? And it's also applying that style, which is what we did with the string concatenation, right? That's just now baked in. And we also should be able to delete things as well. Pretty sweet, right?

  33. Creating New Todos Create new to do. Let's go back to the, whoops, not that one. Yeah? Artem is asking, what will happen to the state mutating function, when major browsers (mumble) web markers, or any true concurrency for that matter? Obviously when you have mutable state, concurrency is just simply not an option. However, I can't see that being an issue. With the idea of concurrency is that you're offloading difficult processing into a background thread. The React rendering of the dom is not a difficult thing. React is extremely fast. because all it is your functions that you're calling here to render the these things, they're just getting called a whole bunch, and they're really cheap, right? So you can do it a whole bunch of times. So when you have like Web Workers or riverwalk, or any of those JavaScript concurrency ideas, I imagine what you would do is that you would spin off a threat, or a worker, or whatever riverwalk calls their stuff. It does its work, and then it calls back and sets the state. And then at that point, it goes through and re-renders everything. It's an idea anyway. When you set event handlers, or Jason's asking, when you set event handlers inside the scope, does this refer to the element, like normal event listeners? Yes, no, well, hold on. In the event handlers, does this refer to? Yes, it refers to the component itself. So like here, this.props.toggleCompleted it's referring to the todoItem component, so, yes. Good question. As you've seen here throughout React, context is extremely important, and it's something that you're going to use a lot. So getting comfortable with bind and apply, and some of those, it's going to be important, because sometimes you're going to want to call with a different context than what you presently have. Any other questions about that? All right, let's go work on createNewTodo in the TodoApp. So we're just going to come up here, createNewTodo: function, it's going to take in a new text, or something like that, newValue is what I called it. Pretty simple var state = this.state, my favorite new pattern, state.todos.unshift(), you might remember this from our Angular part. It's the same thing. And we're just going to have val:newValue.completed:false. Okay and then this.setState(state). Pretty simple, just taking a new value, creating a new object with it in it, and just unshifting that into our array. Again, you can use push if you're comfortable with push. Unshift just puts it at the top as opposed to at the bottom. Now our function is ready. Now we actually have to handle that. So let's go ahead and do that. We're going to do that in the NewTodo. So this is going to get passed into the NewTodo component. So createNewTodo= (this.createNewTodo). Okay so now this function's available, let's go up and code up that. So NewTodo. The thought of writing out all this markup is seriously bumming me out. So let's just go ahead and take this from the completed one. because that's all we're going to do right now is just put markup in. So go ahead and grab from your completed projects, there's a React Todo, js, components.jsx. Go down to the NewTodo and just grab this right here, this render function. And then we'll code out the rest ourselves, Oh, I guess that did put some interesting things on here. Yeah, I'll just delete this and then I'll re-code it in there. So you're welcome to leave it in there, but I'll talk about it as I put it back in. Right now, as it stands, this is just markup, right? Nothing special about it, this is just rendering markup. In fact, if we save it, and refresh it, it breaks. So awesome. Let's actually look at why it broke. Unexpected token, 73:4. Oh, I think an end to my rendering. You didn't close the rendering function. Like you closed the return with a parentheses, but you didn't close the render. There you go. Yeah, yeah. Okay. So now as you can see we have all of our stuff back here. Notice that this one actually does work, but that's because it's an unbound input, meaning React doesn't actually care right now what the value is in there. because essentially we had like no value equals something, so React is not going to try and change what's in there. Okay, any questions about where we are so far? I know we just did some copy and pasting, which is kind of jarring. Curious, anybody in the room understand the question Artem is asking, and to relay it to Brian? About state and stuff? You can read it, Brian, if you want. Yeah. I think I understand. The last 10 questions Your thing about setting state, and then mutating it somehow, and then doing a set state back, he's saying it's an anti-pattern? Might be. I just found it to be very readable code. With React, you can actually just set the part that you need, right? So if you need to just, you know, you just want to set this part of the todo, so you can say like set state with this. I found that to be burdensome and less readable, and more verbose. But I'm happy to admit that there's probably a better way to do it. This just works for me and I found it to be readable. It's always good to question like "Is this this the best way to do it?" "Are there performance implications here?" I don't think so, but I'm also open to saying there might be.

  34. Giving New Todo a State Let's talk a little bit about the new value variable that we're going to be tracking here in just a second, right? So we have this new value. The question you have to ask yourself is "Is new value useful to the parent component?" So you have the TodoApp and you have the NewTodo component. I would assert that, no, it's not useful. The only thing that that new value is useful is creating new components, which can all happen within the context of this, so that it should not be the state of its parent, it should be the state of the NewTodo component. So we're going to give NewTodo some state. Whenever you're operating on state, you're always going to get initial state function. And return this. So we're going to have just this newValue, and it's a new value is initially going to be just a blank string, right? So now we have an initial state. And then we're going to do a handleNewTodo. Rather, let's hold off on that for just a sec. We'll come back to that. We're also using what's called React with mixins. You can also get the version without mixins. But the powerful part of mixins is this thing called called linkState, which if you remember, we've been doing the passing around functions to update values, like in the state. React actually has a nice little way of doing it, it's called value link. So let's go ahead and check out how that looks. The reason why we're going to use it here, and we didn't use it in the other places, is its very easy-to-use value link if you're in the same component. So the state and the modification state's in the same component. It makes it super simple. And the other thing is that often, when you're modifying states, not only do you want to just modify the value, you also want to perpetuate that data into other places, or have any sort of functionality around whenever that value changes. And so this does not allow you that flexibility. This is literally just 2A data binding and that's it. Yeah, let's check it out. First of all, we have to use React mixins. If you're familiar with SaaS, if you're familiar with other things that allows mixins, I think PHP has it baked in now. That's what this is. Essentially you have common functionality across disparate components. So, in this particular case, the idea of two-way data binding is useful to not only this component, but many other components. It's a generalized functions. And so React allows for these kind of mixins. This particular mix in is one that React provides for itself. You can also write you own. So LinkedStateMixin. Now this is available within the context of this particular component. So let's go ahead and get that started here. So input value link was right there. So I just took it out. If you left it in, then you can just leave it in. valueLink= let's see, this.LinkState, and we're going to link it to the newValue state. Again, all this is saying is that this state right here, this newValue is now linked to this input. Little bit simpler than having an event handler and have the event handler modify the state. Cool. Now let's go ahead and now handle this new todo stuff. So there's a button down here, onClick=(this.handleNewTodo) let's call it that. And then we're going to have up here a handleNewTodo: function. And all this is going to do is, first of all, you're going to set this state to be a blank. So you're going to say this.setState({newValue: and that. This is just the same stuff we've been doing that blanking out that new input. I want to do this.props.createNewTodo. And then you're going to do, oh, and then you're just going to pass it in the value, correct? Yeah, so it's going to be this.state.newValue. because as you remember, that link state means that new value is always going to be up to date with whatever's in the input. Will we be able to the do that props before the set state? Or wait, never mind, you're just (mumbles) empty one. That' a good question, though. I think you should, but I also think this works. Let me try. Or else you're going to create all empty todo-- Yeah, it might create all empty ones. No it doesn't. (chuckles) Why? I don't know. Maybe it's just like there's just enough of a delay, there's enough asynchronous to it that it's- Oh, that's bad. That's bad, there you go. But it's just all-- So I wasn't going crazy. No, but now does it work? (laughs) Yeah, the weird thing was it worked. Well, I mean, I wrote the code that way. My guess is that it's not quite that fast. So that state has some sort of delay? Yeah. So it takes one millisecond. And that's like instant, yeah. How interesting. Yeah, because to me it seems like state of the new value should be empty. Yeah, I agree. Yeah, interesting. Cool, so any questions about creating new todos? Does the value link stuff make sense? The mixins idea makes sense? Calling the functions from the parents? How was the documentation from React? Great. It's good? Yeah, it's pretty good. At least I found it very useful and the React developers are super available. Like, you can hit up Pete on Twitter and he's really on top of it, or Vije, I don't know how you say his last name, but he's also super available. So when you add that mix in, is it just like any attribute if you add link in it, it links that to wherever you link it to? Or is it just like value, so for instance, classLink, or something like the classNameLink? Could you get that and then modify the class? I mean, it's probably anti-patterning, but I'm just wondering-- I don't think so. How that thing works. I think it is only-- Is it only on input values? It's only on input values, and it's only for state. Obviously it doesn't work on props. Now value link objects can be passed down from parents, so if you want to do like a value link from a parent to a child, you can do it through its properties. But, yeah, it only links an input to a state somewhere. Yeah, I guess text value, yeah. Okay, yeah, I get it. You can do it with checkboxes. And then you're buttons, I think. Never tried it with radio buttons, but I imagine that works. Input sliders. Everything has a value, so I got it. Yeah. That's a good point, anything you can get a value out of. Cool. For simplicity's sake, going back to our page right here, only clicking the button works. Like if you hit Enter, doesn't work. The way you would do that is you would surround it in a form, and then you would do an onSubmit event. That works. Tusijia said that when she had the new value state modification above the create, it actually was empty-- It was empty? All the time. Interesting. Apparently-- Maybe she has a better computer than me. (laughs) Better computer? Yeah. Coding (mumbles) with your computer. Yes, this is obviously makes much more sense, so it's a good catch.

  35. Clear Completed So let's just start back up at the top at the TodoApp level. And we're just going to do a clearCompleted. Your stickers are slowing you down. That's what Tusijia said. You're trying to figure out what I have? I wish I had a React sticker so bad. I don't. I actually bought an Ember sticker, because I caught a lot of (bleep) for giving workshops on Ember and not having an Ember sticker, so I went and bought one. She's giving you crap for all those stickers are slowing you down. That's probably true as well. I'm guessing I probably should read that. Just kidding. All right newTodos, var newTodos = this.state.todos.filter, again, this is like the third time you've seen this, so none of this should look super unfamiliar to you. Okay, return.el.completed, guess you need that. Bang, right there. And this.setState({todos: newTodos}). So as you can see, you can write setState methods just like that. That works as well. As opposed to, I mean, grabbing the state and resetting it however you... This works as well. Guess we can take this console.log out there. We don't need that. Okay, let's go down here to this. ClearCompleted needs its own little function right there. So clearComplete = (this.clearCompleted). And let's go down to the Clear Completed, right there. And this one, we can actually write out, it's pretty small,
    Clear Completed, Okay and close your /button, /div, that's all the markup we need. Let's go add a handleClick: function, takes an event, comma, and we're just going to do this.props.filter. We'll just call it clearCompleted. That's all it needs to do. Then down here on the onClick, we're just going to say onClick={this.handleClick}, Save that. Run back over here, and hopefully clearCompleted wipes out all our completed stuff. So even if you like add new stuff and then still clear completed. That's it. That's the entire React app right there. So let's talk about, in specifically, notice that this is 163 lines of code. You go look at our Angular app, it's probably 30 or 40 lines of code. So one's inclination, at least my initial inclination is to say, what the (bleep) would I care about React for? I want to write less code. React, while it may be a little bit more verbose to get up and running, because everything modifies the code lives next to it, whenever that code is modifying data in a way that you don't anticipate, you know that it's always going to be next to it. It's always going to be right next to where that data lives. That's really powerful when you're working in a big team, or even a small team, or even dealing with yourself three months from now, that you know it makes your code very predictable, and very easy to find where bugs are. It just makes that area very small where bugs can live. So I think it's a really powerful architecture. I'm a big fan and I like all these frameworks, but this is actually the one that's Reddit is moving forward with, for right now. So kind of interesting, kind of fun. And it's very, very, very performant. So all these are pretty performant. As long as they're written well, which is always a problem for everything. (laughs)

  36. React Questions Does anyone have any questions or comments? You tweeted that you felt like a wizard when you're using React, why is that? It was just one of those moments where, I'm trying to remember exactly what happened, but I remember that the feeling that I got was, I had written some code, and I had unintentionally reused code that I had written, and so something that I wasn't expecting yet to work had worked. And so I was like my past self had cast a spell on my future self to make code work. That's (laughs) more or less the function that I-- So the re-usability is really what-- Yeah. But you were just talking about, earlier, how directives is re-usable and how you were so excited there. Definitely. So how do you feel it compares? Directives are very re-usable. And you'll definitely get those wizardy type moments. My biggest complaint, and I've written a lot of angular, and my biggest complaint that I can leverage against Angular, is that I used to not be good at writing Angular, and I'm not implying that I'm now great at writing Angular, but my old code is awful, and it's really hard to follow. So they don't really give you a whole lot of hand in helping you structure your app. Now some people find that great. Some people that get Angular know where stuff should go and they have their opinions of how they want it to work. It took me awhile before I got that opinion. And so I have a lot of bad Angular now that I have to maintain. Whereas all the React that I've written, even the stuff that I was first starting out has very few anti-patterns in that, just because it's a bit harder to get there, just because of how they force you to let your data flow. And (mumbles) asked how are you doing your content testing in Reddit and specifically in React. It's in Jasmine. That's just kind of my flavor, that's the one that I get the best. You can use any of them. Actually Facebook has a framework called Jest, that is built on top of Jasmine, that you can use specifically for React. I think it works on other things as well. But, yeah, we're just writing unit test using Karma, using Grunt, and using Jasmine to kind of test these individual component functions. They kind of make them more functional, like functional-esque programming, so that they're just applying transformations as much as possible, as opposed to just modifying the state. So we try and separate those functional transformations away from the state mutability of it. And that makes those particular calculations and transformations very testable. And if you want to get more functional programming, on Frontend Masters, there's Brian Londsdorf, I think that's how you say his last name. His stuff is stellar, so I'd definitely check that out. Other questions? Do you find that more code required with React that takes a little more effort to keep the size of code in your head. Because there's more code, it seems like maybe a little less expressive, where you get more opportunities to do things your own way, which can make it less opinionated and harder for other people to work on each other's codes? I haven't yet found that. So the one thing to keep in mind is a big thing that's different is a lot of that logic lives in Angular's templates, so you actually have two places that you're looking at. Everything, including the markup, lives here. So that's why this is much longer. I don't know what it would be if you compared them side-by-side, including their indexes.html, going to bet Angular's still a bit shorter. Angular's very expressive for that reason, but you are splitting your stuff across multiple places. Like React, everything for the createNewTodo thing is all right there. You cannot go outside of there, except, I guess, in that top TodoApp, including its parents, right? You have only that ancestry to look at. And I find it sufficiently and not excessively expressive. (laughing) I feel like that's a cop-out answer. I don't have any issues with it, though. Yeah? The fact that the presentation logic, or the presentation is all wrapped here together is making me have bad memories of PHP. I know you can be more or less disciplined. How easy, or what are techniques for being more disciplined to make it so all the presentation specific stuff is not totally trampling everything, and so that it's a little easier to change and keep separate? That is a widely and often spoken criticism of React is that it feels PHP-esque, in that, not that there's anything wrong with great PHP. Great PHP is a great language, but that markup, and that functionality is living next to each other, which our developer lives we've been told that that's an anti-pattern, right? That you want to separate your concerns out. The reason why I've suspended that hesitation is that the way that they've done it makes sense to me. Kind of going back to this idea that everything just lives right there. Rather than grouping together, like these are actions, these are fuse, these are different things like that, they've said here's a totally encapsulated thing that does everything that it needs to and needs no help from no one else, other than its parents and ancestors, but whatever, however you want that to look. That makes those components very re-usable, and it makes them very portable. It's not very hard to move one component. We could take that newTodo component, and throw it on another To do List App, whereas something else we'd be adding in, and then we just have to replace the functions that it's operating on. So I've said a lot of things. I haven't exactly addressed your concern yet of what ways have I found to be more disciplined. I think that global app object has helped me be more disciplined, separating out different pages, or different types of components into different files, that kind of like logical separation of files, and such, helps them not to bleed into each other, because it makes it hard to call them from each other, which you shouldn't do, right? You should find different ways to bus messages to each other, whether that be by events, or other constructs, like maybe having common parents that then talk down to the different children. There's Facebook's Flux architecture, which has the idea of a dispatcher, which I don't want to get into right now, but that's something worth looking at, that there's essentially this dispatcher that lives above all the parents, and then dispatches different information down to the correct ones. Those would be some of my, at least, my initial reactions to that. Does that feel like I answered your question? Okay, cool. Artem's asking, "Any good resources or particularly helpful resources, aside from Facebook's main GitHub repo about React, externals templates, React and JS flavors like Coffeescript and stuff like that? I mean, just additional resources. Yeah, so you said beside their actually repository page? I'm just still going to say that that's the best one. Their tutorial's spot on, really, really, helpful. Walking through that's really helpful. I went through the ToDoMVC.com, version of their TodDo list with React, that was really helpful. Pascal wrote a really great version of React's To Do List. What else? Well, we'll go over to Coffeescript in a second. Other than that, it's still young enough that it's kind of hard to find some of those resources. There's some good blog posts on it. Hitting up their Freenode is usually pretty helpful, I've done that a couple times. And then Stack Overflow. That's probably the resources that come to my mind that I've used. Just to talk about Coffeescript for a second. I know people like Coffeescript. I'm okay with Coffeescript. I have good and bad days with it. As far as I know, there's not a good way to integrate JSX and Coffeescript together. I haven't seen one, I don't know if it exists yet. We're actually talking about writing some sweet js macros for JSX, so that we can kind of modify it. because some of this is a bit clunky and repetitive, and I feel like it can be written better. But, right now, the suite JS does not have a JSX transformer in it yet, so it's kind of a undertaking. Anyway, they don't play nice yet as far as I've seen. And I hope that gets fixed soon, for sure. Other questions? Are you using it in production? This week. I actually was supposed to finish before I left and I did not. Our new shopping cart on RedditGifts.com is going to be all in React. So it's going to be cool. (laughs)

  37. Wrap-up Unsolicited Opinions Why Backbone? Dead simple to interact with a REST API. If you're kind of familiar with Rails-y kind of style, like, or Tastypie for Python style of API, Backbone works really well with those. Like the getting and the putting for like models and stuff like that with, yeah, model-style API end points I think is what the more technical term or whatever is for it. It's a very good way to organize your code, and then it just gets out of your way and says, "Okay, I've given you the little bit of structure, "now go figure it out yourself." Really bare bones, you're never going to have, Backbone is never going to be your like limiting factor for your performance, like Backbone itself, right. It's just because there's not a lot to it. And it works great in large applications. It is slow for prototyping, I would not prototype in this, in Backbone, personally. Why React, I know I have a spelling mistake up there, but yeah, it's designed for optimal efficiency. The bottle-neck is on the browser is has been the DOM, it always has been the DOM, and my guess is that in the future it will still be the DOM, and React minimizes every single interaction it can do with the DOM to help you go faster. It makes paints and like repaints and all that kind of stuff and re-flows very very efficient. That forcing of one-way flow of data makes it super helpful for debugging, it just makes it so like there can only be like four or five places that the bug can be. Whereas like it could not be sprawled out across your application. I think Angular has that problem a lot. It's very web component-esque. Which is nice, I like web components, I think it's the future. It's easy to compose components of other components. It's easy to introduce React to your current stack. It's easy to introduce like a one components or two components on a page. It does not require very large commitment. And we talked about React renders server-side at rendering. I'm super excited about this, and I know Angular is not concentrating on server-side rendering. I don't know about the other ones, but I can only guess that they're also not concerned right now with that. The fact that you can send down pre-rendered markup and then React takes over that markup as opposed to like sending down the markup, and then having React re-render everything, no, it just like takes over and then it just keeps going from there. Not only that, you don't have to learn like another server-side template. Like you don't have to have Django templates render it, and then have it go down and have React take over. That would work, but I wouldn't recommend it. Rather what you can do is you can have React render it on the server, send it down, and it's all React, it's all one file, right. Like there's no special magic about this. So super cool, really really excited about that. So Angular and Ember, they kind of scratch the same itch in different ways, and they're like perfect use cases, they're super fast for prototyping, really super awesome. They have weirdness at like large scales. Like you're going to run into weird edge cases. I've found this in particular with Angular, like there's just weird things that you find you would have never expected, but they're both pretty fast as long as you keep to good practices, you can even start working with them at larger scales. So why Angular, it's the directive. That's just the coolness, the sexiness of everything that is Angular, it lies in the directive, it's super powerful. It's a very awesome way to influence the DOM in a declarative fashion. The ease of using the plain old JavaScript object. You get to bring all your current JavaScript knowledge, and apply that to Angular, which I think is really cool. And while it's monolithic right now, Angular is kind of decoupling all of its pieces, so you can just kind of piece it together. I think that's awesome. Like if that had never happened, like if they'd left the router baked in, because it used to be baked in, Angular-UI router would have never come out, and Angular-UI router is just great, so. Ember, computed properties, the fact that you can kind of compose properties that are computed from other properties, and they're always kept in sync. It's really powerful, particularly if you're doing some expensive calculations, or things that you just need like right away, as opposed to having the paradigm of accessing a property versus accessing a property. This is a personal opinion of mine, having worked in Ember and having done lots of work in Angular, I have very weird like WTF moments with Ember. There are some moments, like when you're doing ngOptions, which is like you have a select and you want to populate its options with an array. The domain specific language on it is just frustrating. Like every single time I end up on stack overflow, and I've done it like dozens of times now. Maybe I'm an idiot, well probably an idiot, but that's okay. Angular has just weird DSL places, so. Though I believe Ember's barrier of entry is higher, I think like, once you get into it, it helps you go super fast and as fast as Angular. Like I think this particular workshop makes it seem a bit harder to get into it, it is harder to get into it I think, but once you know how everything's working, like if I essentiate a ToDo app, right, then like the ToDo router is going to exist, and the ToDo controller's going to exist, and all that stuff just is getting instantiated for you behind the scenes on the fly. Once you get that, it helps you go super fast. Ember has great docs, great docs, great community. If you make fun of Ember, Huda cats might come yell at you, but that's cool. He likes to yell at people, but their team's really great, and their docs are awesome. Angular has still to this day produced docs, in my opinion.

  38. Extended Features There's tons of cool things that we didn't talk about, like extended features to these frameworks. Cool things that we didn't talk about, we didn't talk about Backbone interacting with APIs, but that's a cool feature about it. And we did this with Vanilla Backbone. The great part about Backbone is the Backbone community. There's like Backbone.validation, right, like that's a really cool thing that just goes through and does like validation for you. Like there's just tons of these little Backbone things. It's like jQuery right, like there's just a jQuery plugin for everything, right. I kind of feel sometimes that way about Backbone. And Backbone seems like a lot of code, but like now that we have that ToDo app up and running, we could have just kept going and going fast, right. It's that setup that kind of sucks about Backbone. Ember, and I also apologize for the wall of text, right, but it felt better than going through like a thousand slides, so. Computer properties, like seriously, they're just like the greatest thing. We didn't actually set them up, but they're pretty easy to set up, and this is something that I haven't discussed yet, but I think is a crucial point, especially with comparing Ember and Backbone. Ember is a framework, they sit at their framework, and like it is supposed to be like the scaffolding that you build your app on. They are very particular at Angular, they say that Angular is not a framework. I kind of have my disagreements, but they're insistent that it is not a framework. It's a superheroic framework. Yeah, I mean like yeah, super, yeah, they did use to call it that, but they insist now that it is the tool set that you use to build your framework. Now I mean, we're splitting hairs, right. Like it's a very subtle difference, but it really comes down to their philosophy that Ember wants to tell you how to build your app, which is okay, right. Like they actually have really good opinions on it. They have really smart people that have done lots of these things, that have great opinions about it. Angular does not want to tell you how to build your app, it wants to help you, and it says here are your tools, now go build up like the scaffolding so you can build up your app. And like that's the directions they're heading off into, like for the future as well. And everyone says that Angular directives are amazing, but guess what, most of that stuff can be accomplished with Ember components and Ember views. Like it's not that we're doing things that can't be accomplished otherwise. The only interesting behavior that's hard to replicate is that kind of mixin directives. You can have multiple directives on one attribute that can be used across different ones. Kind of that extensible web kind of stuff. So that said, okay, directives are still really cool for that very reason that we were just talking about, is that they are just like, they're extensible, and they can be applied, and they can be combined. And you can also do like the component stuff-esque if you, like web component stuff using like the element level of directives. Filters, and we went over filters a little bit before lunch. Very powerful, and kind of the sky is the limit. Your imagination's the limit of what you can do with filters. And then custom services, like that ability to dependency inject where things are necessary is really cool and makes things super testable. Of all of these, my opinion is that Angular is most testable. So if you're super big into testing, you're probably going to be super big into Angular as well. React, we glanced over mixins just a little bit, but writing your own mixins is kind of cool. I don't have any experience in it, just kind of glanced at what other people are doing. But the ability to share functionality across unrelated components is powerful. I mean, it's kind of why we like directives, right. React is made with functional programming in mind. Like they have a lot of like core values, like referential transparency, and some of these other things like independence, and some of these other cool things that make it very functional in nature. It makes it, again testable, right, and it makes it very easy to fit into that kind of paradigm while you're writing React. So kind of cool, I mean there is mutability associated with it as well, but just keep that in mind. React, or Facebook made React with Flux in mind. I'd recommend checking out like Cortex's library or Fluxxor. More Fluxxor, because that one's actually meant to be a framework for Flux, which is you use Flux instead of MVC, right. Like they're competing paradigms, but it's pretty cool. And then the server-side rendering is just kickass and amazing. Okay, so what other questions do you have? That's my Steve Holt snoo, like that's the one that was almost my snoo, but then I switched to the other one, so. Cool, well thanks for coming, follow me on Twitter @HOLTBT, and thank you, thanks for coming.