 Thanks for coming to my talk you guys. I really appreciate it. My name is Jim Jones. I work as a Rails engineer, consultant. I'm currently at One King's Lane and I've lived in San Francisco for the past five years. Just recently moved back to Nebraska because my wife and I had a baby and I love everything this karaoke and beer and I love being a dad and I really love the city of San Francisco. On a slightly side story, one of the first experiences I had when I moved to San Francisco was I went to the Taco Bell and I struck up a conversation. This is the Outer Mission Excelsior, like one of the few Taco Bells in the city. I struck up a conversation with the cashier and she started complaining about the rendering differences between her Windows phone and the Android phone. I'm pretty sure she said the word render and I thought to myself, I go, holy shit, I'm in another place. Then I had a secondary experience where we went to Wells Fargo. We were opening a joint account right before my wife and I got married. The banker asked me, hey, what do you do for a living? I go, yeah, I'm a software engineer. His eyes light up and he goes, hey, what language? I go, Ruby. He goes, oh, my God, I wrote a few scripts to automate some of the balances I need to know at the end of the day. Who's the second? Where the fuck am I at? I really missed those sorts of interactions and such. It was a whole new world and it was where I got to meet lots of the people that I had really well respected over the years and such. Great experience. When I got there, I went to a company called Z-Benz and we eventually got acquired by StubHub and then after that, I ended up striking out on my own doing consulting. I just had these whirlwind of experiences when I went to San Francisco that I got to tell my grandchildren about and going through an acquisition and being out on my own and learning on my own. That's just a little bit of a background about me. Today we're here to talk about dynamic sites and dynamic sites with Rails. We have a few options here. We have just raw JavaScript which is actually becoming a little bit more in favor now that implementations are starting to match up with the modern browsers and such. It's probably not as far fetched as a lot of people seem to believe. We have JQuery which obviously it's going to take care of a lot of the browser idiosyncrasies and differences and such. That's always the go-to on a lot of projects. We start to get these higher structure layer of abstractions. We have Backbone that's going to give us a little more structure to our front end. We have EmberJS that we're getting even further with all of its nice conventions and such. Then we have the Directives with Angular that are really, really powerful and give us even more structure to our app. Then there's this little step child that no one ever really talks about and not even sure most people are really aware of what the capabilities are in the current Rails stack. The point is that everything has its place and that the front end framework certainly have their advantages. Then we also have the server side JavaScript rendering which we're going to show where its advantages are and where it shines. We're going to go through a few parallel implementations here of the exact same app. I'm going to attempt to do some live coding and commit presentation suicide. We'll go from there. First off, we have to qualify this. For anybody who's been with Rails for a long time, I'm not talking about RJS. I think a lot of people still call it RJS and this is probably maybe a problem with the evangelism of this particular subset. If you guys remember, it depends on how far back you go with Rails in the history, but there's functionality called Ruby JavaScript. You probably remember a very explicit method naming conventions like this where you had link to remote and here's this really cool URL hash where we're explicitly telling our controller in action and such. We have our page.replace HTML. We would get these JavaScript requests and then we'd get this page object and we were able to either replace a particular HTML element or we were able to update an HTML element. I think that this was the Rails way of trying to solve for the sweet spots of what the dynamic sites were doing back then, which were just basic updating and such. But at the end of the day, it was very constraining and it ended up getting ripped out of Rails core. In fact, I was trying to figure out when the transitions went from just RJS responses to raw JavaScript responses. I was looking at my Agile books and I think the Agile 2 still was citing RJS. So I assume around it was Rails 3 that we started to see just the standard JavaScript suicide requests, but someone else can crack me. We started to kind of take the kid gloves off of our JavaScript requests and I think it's around Rails 3 that we start to allow for free form JavaScript responses. I think this is going to be better demonstrated with some code. Let's see what we can do here. I have this application. This is just a standard Rails new. Is everybody okay on that? Can everyone see? We just have a user model. We just have a name on it. I've already done the DB migrate on it, but that's about it. That's all we're at at this point. What I would like to do is currently we have this functionality. It's listing of users. We have a new user. We want to add a user and we would like it to dynamically update. Okay. So the out of the box is like, all right. So we've got that. This is just the plain scaffolding coming right out of the box. So now how can we get this where it's a dynamic where we would just start adding users to our table and without pulling in any sort of external JavaScript frameworks? So we'll go back to our source and I'll kind of walk you through on how we're going to go ahead and massage this code, right? So this is where you guys get to laugh at me because live coding never goes right, right? So let's see if we can create some magic here. Let's just do that. Okay. So first I'm just going to apply an ID to the T body of our table and I'm going to go ahead and render out all the users and so that's just going to iterate over our user collection and it's going to call the user partial on that. So we're going to go ahead and we'll create our user partial. For those that have actually seen this in action, you'll probably be pretty bored. But I think this bears repeating that I've consulted at a lot of companies and it might be people who tend to be newer to the Rails community tend to reach for their front end framework right away. They say, oh, Ajax, dynamic updates. Hey, we need to pull in a front end framework for this. And so the whole point of going through this exercise is that you can see this built up and you can see that there's a lot that comes in the box for Rails and a lot of your simple dynamic updates may already be taken care of and you may not have to add any more dependencies. So I just want to drive home that point by going through this. So let's just say, let's take that. Sure. Save it. So now we've got our sweet partial, right? Let's go here. Let's make sure it's still rendering. Nice. All right. So now we've got our partial set up. Okay. Now we're going to allow for a name to be entered right directly from the index. So we'll come over here. Let's get rid of that. Let's just say render. We already have our nice little form extracted out because Rails is good to us for that. So let's make sure that that's rendering. Oh, so it needs a user object. We'll come over to our user controller. So here we're just going to say user.new. All right. So now we've got our form. Awesome. Great. So what if we enter a name here? Let's say sir. Okay. We're still doing an HTTP request. Okay. Great. So now how we alter this is we'll go over here. We'll look at our form and we'll just save remote true. And we're going to get into the magic behind this flag a little bit later and we'll actually look at the implementation behind it. But just know from going forward that this is what enables the asynchronous submission of forms. All right. So we've got that. Let's go ahead and refresh. Tim. All right. Nothing. So we don't have anything. So let's see. Let's see what's going on at the back end here. All right. We can see we posted the users and it was hitting users controller create as a JS. Right. So now we've switched from standard HTTP post to a JS request. Okay. So that's a good sign. That means we're at least posting up our data to the server. And if we were actually to hit a refresh on this, we would see that like Tim was posted. Right. So now now that how do we get that data and we get it back to rendering? We come over here. We're going to go ahead and remember how we applied that ID of users to the the T body. We're going to go ahead and do a little jQuery magic because that's included out of the box. We'll just say users and we'll say dot a pen. And here's a nice thing is that this particular template is going to be called create.js.erb. And so that implies that erb is doing a pass on this template before it serves up the raw JavaScript. So this is just another action template. Right. And so that empowers us to go ahead and render out all of our partials, render out the the very views that we've already built. And so we're going to get a lot of reusability out of this. So you're going to find that for a lot of simple dynamic updates, you're going to be a lot more productive with this. So we just want to do an escape JavaScript and we'll render user because we already have our user partial, right? And that was the one that that constituted a row in our table. And we're missing the parentheses. No, sweet. So we'll just say users a pen, we're going to render out. So now we'll call this create .js.erb. So that's implying it's a JS request. And it's going to be processed by the erb. Right. Now let's say I'll care. Try this. Let me say, Oh, no, nothing happened. So maybe there's something went wrong with my JavaScript. Let's take a look where it fell down. Let's see. Okay. Use control ksjs commit. And then soon it's trying to get user controller shot. All right. So we forgot one thing here. We're going to use this controller on the create. We want to make sure that it's going to render the default JS template. So we're just going to go ahead and plop in the format.js here. Now let's try this again. Boom. So now if we take a look at the lifecycle of this, we posted the users. We process users controller create as JS. And then you can see right here that it rendered users create .js.erb. Send it client side. And the default behavior for jQuery is to go ahead and evaluate a JavaScript request. And we'll dig more into the internals of that in a little bit. But just think of it as really, it's going to be really beneficial for you to see the full implementation of that, even though it's a little crude. So. All right. So just reiterate, this is not rjs. This is way more freeform. This is just raw JavaScript with erb processing. And that raw JavaScript is just getting sent client side. So just it's getting that template will get processed by your template process processor. It could be handle could be our ERB. And since this is ActionView, we get the full reuse of partials. We get all of our normal helpers. We get all of that included. It's just another type of template. All right. So I mentioned that we're going to look at some parallel implementations. What I have set up is we're going to take a look at the, there's a, there's a site called to do MVC that has a to do list implemented in various front end frameworks. You have like EmberJS, AngularJS implementations. There's also a plain old Rails JavaScript response implementation as well. So I want to walk through some of the specifics of that code so that you can start to get a feel for a real world application. Do slides for top. All right. Let's just take a look here at our never request. All right. So if we take, say, do slides for top. All right. We'll take a look at this response. And this is just going back to the raw JavaScript response for the create method. You can see that the response is basically just to send back raw JavaScript. Right. And so we've got our to do list here. We're pending our list item. You can see the escape JavaScript method has properly escaped all of our quotes. We're just re initializing our entry for the to do back to blank. And we're setting a few properties. And so that's it. If we take a look at the, the form, the form code for that we just have a form for, we're just initializing a new to do. And we're just setting the remote true flag on it, similar to that initial implementation that we walk through. Here's our model, pretty trivial model, just have a couple different scopes for completed and active. And we have our view. One thing to note here is J is, is basically an alias for escape JavaScript. And so that can lead to a little bit shortened code within your, your JS templates. But the most relevant portion is just this to do list. We're just pending. We're rendering out our to do. And then we're just going to go ahead and re initialize our value. And we would just see this create.js right within our views for that particular, for that particular resource. Here's a controller. Now I want to walk through what some of these helpers expand to. And so you have a little bit more background so that when things start going wrong, you aren't drawing a blank space and saying, why did this guy recommend this as an alternative and start cursing my name? If we were to look at that form for help or call and see it expanded, we would see that the action is set to to dos. And the most important portion is that remote true ends up being extended to a data remote equals true. And we're going to see here in a little bit that this is something that jQuery UJS is actually looking for in order to do the asynchronous, the asynchronous submissions. Right here, if you start digging through the jQuery UJS, jQuery UJS is the portion that is actually in charge of doing the asynchronous submission under the Rails JS. We're going to do document delegate for the form submit selector and digging through that method. If that remote flag has ended up true, we're just going to go ahead and do a Rails.handle remote further down and we'll look at these events later on. But you're going to see on the handle remote implementation, you'll see a bunch of different firing of events and there's going to be a series of events that you can actually listen to that are quite beneficial in terms of like for disabling controls, re-enabling controls, doing proper error display and such. Here's our controller action. You could see the to use controller create. It was as a JS request. That's the important part. And it's important to note that we rendered out just using a standard partial. We escaped it. And this is also available if you're using Hamel as well. You can just do a Rails string and it provides an interpolation right there. So you can still do the escape JavaScript render and still do that same output under Hamel. Here's the final portion. When jQuery's when it requests, it makes a JS request and it comes back. There's going to be a global eval on that particular request. And that actually becomes important when we start going over how to debug these things because evals aren't pretty when the code is incorrect. And so I'll give you a few tips on the debugging coming up after we go over these other implementations here. So it's important we're going to gloss over these front end implementations really quick. But it's important to kind of note some of the differences here. So not woeful. So you wouldn't appreciate that. All right. If we start looking, breaking down the views on this Angular implementation, some of the, obviously some of the more important parts is like the to-do app. And then we have on our ng-submit, the other directive for an add to-do. We come over here. We look at our controller. And this is taken directly from the to-do MVC implementation. We just have our add to-do. We're saving. We have a couple of promises here. And it persists that out depending upon what store you have, whether it's API or local storage. Here's the services that provides that insert function for the store. And they're just posting to the API as to-dos. It's important to note that this is obviously you have full control over that. And so that actually becomes important when we're discussing the advantages of the client-side frameworks. That's definitely on the to-do list. Sometimes. Not now. That would be boring. We've got with our EmberJS implementation, we've got our in-line handlebars and in-line handlebars template to script. So those are eval and with JavaScript client-side. That's important. We have our controller. We're off just creating the record and saving it. And we just have a very simple model to represent this. So our client-side advantages, we have immediate rendering where because these templates are implemented in JavaScript, we can immediately render it to the screen regardless of whether what the result is. We could take that chance if we wanted to. And so that's certainly an advantage where it's hard to compare that even to like a 50 millisecond response time server-side that you certainly get that immediacy with that if that's how you go ahead and design it. You can do asynchronous persistence also on the speed side where you can just go ahead and delegate that persistence out and you can still display things in the meantime and you'll get that immediacy, that quick update to the user interface that will delight the users. And then there's also like graceful error retries. Since you are controlling this persistence loop that you can also do some nice graceful retrying if we lost internet connectivity or lost one of the servers and such. And this could be totally transparent to the end user. So you have that level of granularity with the client side and you have that level of control. All right, so there's a few gotchas for the JavaScript server-side responses that I think once you're aware of it'll make it a little bit more pleasurable experience as you kind of do a deep dive into them. Debugging is definitely a big time gotcha and I'm going to go ahead and just jump over here so you guys can see this firsthand. So like I said, when the JavaScript response gets sent back it actually is going to eval that and the big problem is any eval fails silently. So if you happen to have a problem with your JavaScript and you just have this little typo in there, we go ahead and we're gonna say try this three. We say create user. Oh no, it just fails and there's nothing, right? And there's no guidance or there's no server-side response because obviously we're just evaluating the template at that point, server-side, client-side just eval it, just throw it hands up, didn't do anything. So that's definitely one of the frustrating components that new users basically have to figure out how to get around and there's a couple of different ways that you can attack that. This is kind of a primer for where I'm going for the debugging but we talked about all the different UJS callbacks and how they're triggered throughout the life cycle of the asynchronous requests and here's just a large table of the different states from within that asynchronous request that are available to you and these probably don't get utilized enough or people aren't aware of them but the one that we are concerned about is the Ajax error and this will actually get thrown, this will get called when there's an eval error and this is really helpful. You can drop this say like in your application JS or somewhere else but if there is an error, excuse me, with the eval, we can at least go ahead and do a console log and output what that error text is so that you're not totally in the dark. I remember there's the old RJS, excuse me, the old RJS would actually wrap the code in a try catch block and so I'll show something else along those lines, excuse me, sorry. I actually have a pull request out for Rails 5 that does just that where it'll take the code, wrap it in a try catch block and sends a series of metadata for where the error occurs with it or oh my gosh, excuse me. I have a pull request out that tracks where JavaScript is generated, whether it's within a partial or within a template, sends that particular metadata over for the JavaScript request, wraps the execution in a try catch block and then depending upon where the error is at, it'll say hey, you have a JavaScript error and it actually occurred in the user.html.erb partial or the user.js.erb template and so it's trying to do some mapping back to where this JavaScript was actually produced and it'll give a little more insight into the context in which this JavaScript was generated on the server side but display it in a context in which people are used to debugging on the client side. So it's slated for 5.0, I don't know if it'll make it in, but it's been tagged, so. One big gotcha is if you are starting to do some replacements of HTML elements on your JavaScript responses, you're gonna have to go ahead and rebind those events, right? If you had like click handlers or something on certain div elements, you went ahead and replaced those, that particular handler is going to be lost, so you have to rebind those. One way you can certainly do that is you could start to trigger callbacks, like on our cart summary, oh okay, we can just trigger an updated app and then within that updated app we could just go ahead and rebind those very events that we had set up first. Some of the advantages for JS responses, obviously since we're in action view, we get reuse of partials. So you can see in these two different examples, we've got our create.js.erb, where our user is that append and we're rendering out our user partial. And then within that's for that same resource on our update, if we're doing an asynchronous dynamic update, we can just do user with the user ID and we're just gonna replace with and we're gonna render out this user, which would call the exact same partial. So you get all the advantages of action view right there within your JS templates. Along with that you're gonna have access to all your different view helpers, so that's gonna include caching. So you could cache the hell out of these JS responses and get really lightning quick responses. And potentially less JS load, that we're just sending over the pieces that need to be executed at that particular time. So it certainly could constitute a reduction of JS, depending upon what you're doing. And there's also slight, depending upon a yes, an easier execution flow that because these are templates, they fall in line with the way the rest of the flow of how Rails app generally goes. And so you would know, okay, I've got a JS request, I'm just gonna look for this particular corresponding template. And it just will follow all the same sorts of conventions. So there's no deviation from that sort of mental model that's going on. All right, finally, when do they make sense? I think they tend to make sense when it's something, when it's an interaction where the user expects some sort of level of persistence, something that's stored, something that, like a comment or you've added a cart item and you want to update cart counts, you want to update, say, taxes or totals in another column. Something where the user is expecting some level of persistence. I think this is where they can really shine and they can certainly help to simplify a code base just for the fact that you get so much reusability on there. And so I would just leave you with this final note. This was an article published not too long ago on Medium from Dan McKinley. He was a principal engineer at Etsy and he just says, consider how you would solve your immediate problem without adding anything new. And so when you start to look at the dynamic updates, when you start to look at the pieces that you want to do, when you want to make dynamic, really, really give it a second thought as to whether you would want to adopt a full-fledged framework and that sort of overhead or whether the JS responses would be sufficient in updating the individual pieces on the page. Thanks you guys, I really appreciate it. Thank you.