We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Crossing the Bridge

00:00

Formal Metadata

Title
Crossing the Bridge
Subtitle
Connecting Rails and Your Front-End Framework
Title of Series
Part Number
54
Number of Parts
94
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Javascript front-end frameworks like Ember, React and Angular are really useful tools for building out beautiful and seamless UIs. But how do you make it work with Rails? How do you include the framework, share data, avoid expensive repeated network calls in a consistent way? In this talk we will review a variety of different approaches and look at real world cases for creating a seamless bridge between your Javascript and Rails.
Process (computing)Right angleSoftware frameworkConnected spaceBitPresentation of a groupPattern languageGame theoryMultiplication signSound effectDifferent (Kate Ryan album)WordPlanningMobile WebSoftware developerFormal languageSlide ruleFront and back endsSoftware engineeringComputer animationLecture/Conference
Core dumpWritingSoftware frameworkClient (computing)1 (number)CodeCartesian coordinate systemImplementationBasis <Mathematik>Mobile appGreatest elementRevision controlPoint (geometry)Term (mathematics)View (database)Adventure gameFlow separationPattern languageDifferent (Kate Ryan album)Complex (psychology)Shared memoryCASE <Informatik>Slide ruleProjective planeGoogolMilitary baseRight angleEndliche ModelltheorieAxiom of choiceMathematicsPairwise comparisonSoftware developerWeb pageService (economics)InjektivitätScripting languageSystem callInteractive televisionRobotFrequencyWeightBitPosition operatorWordMeeting/InterviewComputer animation
Subject indexingNamespace1 (number)ImplementationLibrary (computing)Single-precision floating-point formatComputer configurationCodeGenderUniform resource locatorRevision controlSoftware frameworkAreaContent delivery networkProcess (computing)Sinc functionComputer animation
Library (computing)Computer fileComputer configurationPhysical systemHydraulic jumpWrapper (data mining)MappingGroup actionSystem callCartesian coordinate systemRight angleClient (computing)Query languageLatent heatComputer animation
Point (geometry)InjektivitätRootGame controllerWordRoutingKeyboard shortcutTemplate (C++)Factory (trading post)Computer animation
DivisorEndliche ModelltheorieWeb pageLimit (category theory)Multiplication signArmSystem callTemplate (C++)Cartesian coordinate systemView (database)Level (video gaming)Right angleFunctional (mathematics)UsabilityConnected spaceKeyboard shortcutResultantDirection (geometry)Graph coloringQuery languageGame controllerEstimatorWorkstation <Musikinstrument>Complex (psychology)Writing2 (number)Factory (trading post)Code1 (number)SynchronizationComputer animationLecture/Conference
Latent heatMoment (mathematics)Right angleOvalCartesian coordinate systemReplication (computing)View (database)PhysicalismCodeComplex (psychology)WordWrapper (data mining)Library (computing)Process (computing)Lie groupMultiplication signComputer-assisted translationFigurate numberBitHazard (2005 film)Level (video gaming)Data miningStandard deviationPattern languageData structureConfiguration spaceKeyboard shortcutImage resolutionComputer animation
Data structureComplex (psychology)Element (mathematics)Right angleBitMultiplication signGame controllerEndliche ModelltheorieIntrusion detection systemOcean currentSerial portRootComputer animationLecture/Conference
System callFigurate numberRoundness (object)Server (computing)Point (geometry)Key (cryptography)Maxima and minimaRight angleStructural loadEscape characterInformationRange (statistics)System administratorComputer animation
Game controllerBitVariable (mathematics)Cartesian coordinate systemDivisorEndliche ModelltheorieWindowClient (computing)Serial portObject (grammar)CodeRadiusPattern languagePoint (geometry)Formal grammarRight angleCycle (graph theory)Open sourceArray data structure
Data storage deviceEndliche ModelltheorieObject (grammar)Computer fileRootAdaptive behaviorCartesian coordinate systemLocal ringRoutingSerial portWindowDefault (computer science)Configuration spaceIterationStructural loadSystem callString (computer science)Replication (computing)Client (computing)Server (computing)Absolute valueSoftware testingVideo gameTemplate (C++)Self-organizationAssociative property
NumberObject (grammar)Element (mathematics)InferenceRootEndliche ModelltheorieRoutingCodeSystem callCache (computing)Right angleAttribute grammarElectronic visual displayIterationParameter (computer programming)Data storage deviceVolumenvisualisierungComputer animationLecture/Conference
Endliche ModelltheorieDifferent (Kate Ryan album)BlogWeb pageKeyboard shortcutStructural loadPattern languageServer (computing)Interactive televisionIsomorphieklassePoint (geometry)Cartesian coordinate systemBitClient (computing)Multiplication signSerial portTerm (mathematics)Differenz <Mathematik>VolumenvisualisierungTheoryWeb browserScripting languageSystem callConnected spaceProcess (computing)FacebookMusical ensembleComputer animationLecture/Conference
Game controllerForm (programming)BitTerm (mathematics)ImplementationComputer fileElement (mathematics)Subject indexing
Dependent and independent variablesConnectivity (graph theory)Line (geometry)Network topologyServer (computing)Category of beingProcess (computing)Scripting languageView (database)Structural loadElement (mathematics)Form (programming)Right angleComputer animationLecture/Conference
Connectivity (graph theory)Different (Kate Ryan album)VolumenvisualisierungServer (computing)State of matterPoint (geometry)Category of beingOrder (biology)Electronic mailing listCodeLogicFunctional (mathematics)Form (programming)Computer configurationComputer fileView (database)WordInternetworkingControl flowVector potentialEuler anglesLine (geometry)
Connectivity (graph theory)Touch typingServer (computing)Multiplication signConnected spacePattern language1 (number)Key (cryptography)Client (computing)VolumenvisualisierungTwitterLine (geometry)Structural loadImplementationGoogolWindowWeb crawlerRoundness (object)Cartesian coordinate systemWebsiteWeb pageIsomorphieklasseMassJava appletScripting languageProcess (computing)BootingDependent and independent variablesComputer configurationCellular automatonUsabilityProduct (business)Replication (computing)Point (geometry)BenutzerhandbuchService (economics)Object (grammar)Computer animationLecture/Conference
Game controllerObject (grammar)WindowSoftware frameworkStructural loadMessage passingAbsolute valueEndliche ModelltheorieContext awarenessINTEGRALRow (database)UsabilityArtistic renderingConnected spaceBitTwitterBlogNumberService (economics)Multiplication signView (database)Lecture/Conference
Service (economics)Exterior algebraCASE <Informatik>BuildingValidity (statistics)AdditionVolumenvisualisierungComputer animationLecture/Conference
Cartesian coordinate systemConnectivity (graph theory)Declarative programmingTemplate (C++)File viewerView (database)Absolute valueDivision (mathematics)Computer animationLecture/Conference
Slide ruleCartesian coordinate systemArmDebuggerFront and back endsData miningDifferent (Kate Ryan album)Object (grammar)Process (computing)Projective planeCASE <Informatik>Server (computing)Asynchronous Transfer ModeTemplate (C++)View (database)Term (mathematics)WindowFlow separationSoftware frameworkReal numberMereologyPoint (geometry)Right angleWebsiteComputer animationLecture/Conference
Transcript: English(auto-generated)
Welcome to Crossing the Bridge, Connecting Rails in Your Front-End Framework. My name is Daniel Spector, and my hope out of this presentation
is that you discover patterns in the best practices for integrating Rails in JavaScript. So a lot of times, this is what you see, or the slides cut off a little bit? We can't lower it down? Okay. Huh. Then I guess you're gonna have to hear me more. Less reading.
It's all good. So, this is what we're trying to avoid. A, my presentation skills, obviously. But B, you know, terrible bridges. Instead, we want this. I'm from Brooklyn, this is near and dear to my heart. And so when you're integrating JavaScript and Rails, you wanna make that seamless bridge, that seamless connection. So this is our game plan.
The first thing we're gonna do is we're gonna understand the trade-offs that you're gonna make. Choosing to use a client-side MVC framework is not without its challenges, and so it's important to understand that before going in. Next, we're gonna look how to deeply integrate your framework with Rails, and when we're gonna do that, we're gonna explore different patterns, different ways of sharing data in a consistent and maintainable way, so that you can use it to best effect.
This is me. What's cut off at the top is my name. My name is Daniel Spector. I am a software engineer at a company called Lifebooker in Brooklyn. I am a graduate of the Flatiron School, and then at Lifebooker, we do Rails, JavaScript, primarily Ember. I also was involved in a lot of mobile development, so I have some Swift experience,
and we're recently moving over to Clojure. But enough about that. What are you about to get yourself into, right? This is JavaScript. It is often messy. Nobody will say that it is a beautiful, coherent language. It's gotten a little bit better with the new syntax, but still, you're gonna run into difficulties.
This, I think, is kind of the general, relatively applicable. This is courtesy of Alex Machiner. He's an Ember JS core team member. It is generally easier to write an app, at least especially in the beginning, writing in Rails, having HTML being served up instead of a client-side JavaScript MVC framework.
And it's important to always think about the bigger picture. Understand the technical challenge that goes into something is really important. You don't wanna think about something, have a great new idea, then dive right into the implementation. What's the best way we could put this in? How can we use it? What are the features? All of that. It's really important to understand, before you do that, take a step back, think about the trade-offs, right? And you will encounter a lot of trade-offs.
This is some of the fun that might await you. You will encounter duplicated models, right? Separate code bases. If your user has to change something on the Rails side, you're gonna have to change it on the JavaScript, right, and it gets often very messy. And just overall complexity in general. You don't know when you're debugging whether often you're looking at a client-side problem
or whether you're looking at a server-side problem. And when I talk to people about this, I usually get this kind of objection, right? That my customers, my clients, this is what they need. They want this kind of experience. This is absolutely what they're requiring. The truth is, not really, right? Clients, customers care about really one thing,
one thing only, or three things, I guess, if you count the commas as separate bullet points. Maintainable, sustainable, performant applications, period. Right, it should be maintainable. Your developer should be able to understand it easily. This should be sustainable. Things should be able to be debugged, right? And it should be relatively well-performant.
And if you're not careful, you can run into a lot of gotchas when it comes to client-side MVC frameworks. You don't wanna run into a case that you have problems with this and you're not delivering what's best for your clients and for your customers. But now that you have been warned, you can make, oh, the top of that is a blurred-out curse word,
but anyways, you can make incredibly awesome applications with client-side MVC frameworks. Adventure to guess that a large portion of this room uses Gmail on a daily basis. That is a single-page app. If you really want to, you can scroll to the bottom and click Basic Version to get the HTML with the full-page refresh and all that jazz, but nobody does that, right?
Client-side MVCs can make some incredible applications. And especially if you are very graphics-heavy, very charts-heavy, things like that, things with a lot of really complex user interactions, then it may absolutely be the case that your first choice should be a client-side framework. But just understand that there are trade-offs. So that says recap on top that's being cut off.
Never lose sight of your ultimate goal. Your ultimate goal is to provide the absolute best experience that you can for your users. Understand the trade-offs that you're gonna have, but we're gonna explore a couple different ways where there may be a solution, right? There may be a way to mitigate some of these problems to create better applications. All right, let's dive right in.
We are going to create the absolute simplest version of To-Do MVC on Rails. To-Do MVC is a website. We're able to see the same application implemented in different JavaScript frameworks, so you can really get a nice comparison to it. The reason it's doing that is because very often the frameworks look completely different, and the ones that we're gonna be talking about, they really do.
So in terms of, there's gonna be a lot of code. Hopefully we won't get too cut off, so we should be okay with that. But it's nice to keep a reference so that it's kind of consistent what we're going to do step-by-step. So this is what we're gonna be looking at. We're gonna be looking at Angular, we're gonna be looking at Ember, and finally React. And so we're gonna,
these implementations are relatively complete. If you follow the slides in SlideShare, then you should be able to implement these applications simply as you see them. But what's important, though, to focus on is the patterns. We're gonna explore different patterns of how we're gonna connect these, how we're gonna share data between Rails and our JavaScript. And so really focus on how this is implemented.
So let's get started. This is Angular. Angular is developed by Google. It has two-way data binding very much at its core. When your model changes, your view changes. When your view changes, your model changes. You don't have to write any of the glue code for that. Depends the injection. It's kind of built into a heart of it also.
We'll see that in a second. But Angular 2 is coming. This is something that you should be aware of. Angular 2 is not really the same framework as Angular 1. It is completely different, both from syntax-wise, both from a philosophical point of view. And so it's not like Angular 1's going away. There are thousands of applications at this point built on Angular.
But you should absolutely be aware that if you're starting a project right now in Angular, there's a good chance that in 12 to 18 months, Google's not gonna support it anymore. And so really think about that before you do choose to do it. But if you are, we can jump right in. So the first thing that we're gonna do is we're gonna get our Rails project API ready. Like I said, this is gonna be very basic.
Okay, not too much is cut off. So we have an index method. We have an index and a create, so basically two endpoints. We're gonna namespace everything under slash API slash todos. And any get request slash API slash todos is gonna give us all of our todos, and then we're gonna be able to create new ones. Does that work? There we go.
So the other frameworks that we're gonna talk about actually have official implementations with Rails, but since Angular doesn't, we're gonna try out Bower. Now when you're including JavaScript frameworks or libraries in general, there's a whole bunch of ways that you can include it with Rails, right? You can use a CDN. It's a perfectly valid option.
You can copy everything into vendor assets. Very often there will be gemified versions of libraries, which is simply just a nice asset pipeline helper to get the JavaScript in. But we're gonna take a look at Bower. And Bower makes it really, really easy to include pretty much any JavaScript library that you want in your code.
It's one centralized location for all the packages, and there are thousands of them in there. It integrates really nicely via the Bower Rails gem. So this is what it looks like. You have to make sure that you have actually Bower on your system, so just make sure that you NPM install that. And then all you do is you set up in your gem file Bower Rails, you initialize it, and now you have a Bower file. Very similar to a gem file, instead of gem, it's asset.
And so we're gonna bring in Angular and a couple of optional libraries. So how do we manage our client-side data? This is an Angular specific question. So we could go, just use standard, really jQuery Ajax calls back and forth. Angular actually has, it's just really a very basic wrapper
that it uses around, I'm sorry, jQuery's Ajax library. But instead we're gonna use ng-resource. And ng-resource is in, I won't read it to you since you can't see it, an optional library that maps basic CRUD actions to specific method calls. So we're gonna scaffold out a very basic application
so you can kind of see how it's gonna look, and we'll talk about it more from there. So this is Angular. This is kind of the entry point that you'll see. We're gonna call this todo. And you see we're including ng-resource and ng-route. This is an example of the dependency injection that Angular has. And then we just do a little CSRF magic to make it work with Rails.
And then we have one route, it's the root route, and we're gonna inject the todo controller into that. Right, now what we're gonna do is we're gonna set up a factory to hold our resource, and then we're gonna pass that factory over and inject it into the controller, which is gonna bind it to the template. Right, so this is what our factory looks like. Okay, so we'll cut off at the top,
but you can kind of get the gist of it. Everything is gonna live under slash API slash todos, and so this is gonna tell us, every time we make a call, this is the end point that it's gonna hit. And then we have our controller. And this controller is all about, what you don't see under the hood is the data binding that comes here. Right, so on instantiation, we're gonna call scope.todos,
which is just gonna query a get request for slash API slash todos. It's gonna have one function called addTodo. All it's gonna do is it's gonna grab out that model and save it, which is gonna make a post. And then it's gonna re-query, and it's gonna clear out that model. So the first thing that you'll notice is that there's no glue code.
We'll see the template in a second, but we're not manually going into the DOM, updating the views and things like that. Two-way data binding is gonna make sure this all stays in sync. The second thing that's, I'm sorry, the second thing that's important to note is that it's relatively compact. Angular is relatively simple,
and so if you're writing especially smaller applications, this is kind of all that you need to get set up. Right, and this is what the template looks like. We just ng-repeat the user directive to iterate over those todos. And then on submit, we're just gonna call our function. And this is what makes it really nice. But there's a kind of a hidden problem here
that might give you pause. If I go back to this for a second, right now all we're doing is calling todo.query, right? And that's, for this specific application, all we need is just to make a get request for those todos. But let's say you had a little more complexity, and large applications will have a lot of complexity. So let's say that you need to first understand,
well, is a user logged in? If that user's logged in, then I need their todos. But maybe I only want the ones that are completed. Maybe I have a whole bunch of things that I need to understand. It's very likely that you can make a whole bunch of API calls simply before you're rendering out anything to your user. And so that results in a lot of animators, right? You see the loading bars, a little spinner there.
And it doesn't make for the greatest user experience. And especially because, so we're, I think all of us are kind of used to really fast broadband connections, but not all your users will be. And so in a really fast connection, you won't even notice the lag. But on a slower connection, you absolutely will. And for usability for user standpoint,
it could be very tricky. Nobody wants to go to the page and the first thing they see is just a loading bar that they never know is gonna stop. So this is what it's gonna look like. And pretty much in all the implementations, this is exactly what it's, this is exactly what we're doing. So just to recap, data binding in Angular, very powerful, right? There was no Vue glue code.
There's nothing that we needed to make sure that bound, that worked, it came together. If you're gonna be using Angular, I'd highly recommend any resource or a wrapper around that. There's one specific for Rails if you'd like. This just makes your request really easy, that you don't have to write out a whole bunch, dollar sign, Ajax, the data, the method and all that. Makes it really easy to use.
But here's the problem. Here's the pattern that we need to solve. These multiple API calls to initialize your application get really tricky. And this is gonna be, this is the problem that we're gonna try to solve. And we're gonna try to figure out a way to make those a little bit easier to work with and make the experience for your users a bit better.
Let's talk about Ember. Ember was created by Tom Dell and Yehuda Katz, who may be in the room at the moment. Ember was made for large, ambitious applications. Ember is big. There's a lot to it, there's a lot of complexity to it, but the reason that it's there is because you need that kind of complexity
when it comes to large applications. And so for managing the structure of that, for working it all together, it works really, really nicely. Ember favors convention over configuration. And Ember has a client-side persistence library called Ember Data, and it works wonderfully. If you've ever tried to write one on your own,
it is horrible. It is a really tricky problem to get right, and I think they knock it out of the park. They did a really great job in making this really easy to work with. So, Ember CLI is the new standard for working with Ember applications. There's a couple talks tomorrow, one on Ember CLI Rails and one on React Rails, that will really dive into this.
So I'm not gonna spend too much time on the specifics of Ember CLI, but if you're getting started with an Ember application, this is absolutely what you should be using. It integrates really nicely via the Ember CLI Rails gem. So we're gonna switch it up a little bit. Instead of just having to-dos, we're gonna introduce the concept of a user, right?
And a user will have many to-dos. And then just assume, again, this is really for demonstration purposes, assume by the time that you hit this controller and how you're gonna get to it is via, you know, your Ember controller, assume by this time we have a concept of a current user and that current user has to-dos, right? So now this is, we're gonna get set up.
We're gonna need, obviously, Ember CLI Rails. We're also gonna need ActiveModel serializers. ActiveModel serializers will work really, really nicely with Ember and will make it a lot easier. So we're just gonna generate our serializer. You know, set it up with embed IDs at the top there. And then this is what it's gonna look like. And it's important to understand the structure.
This is actually very basic. There's only one resource. There's a lot of complexity that it could handle. But at its heart, there's gonna be a root element, right, of to-dos and then everything under that. So this is what we're trying to accomplish. We're going to, instead of using JSON calls and instantiation, right, so when Ember loads, instead of making a bunch of JSON calls to kind of figure out what's going on, what we're gonna do is we're gonna preload Ember
with that information, right? Why are we gonna do this? First things first, we wanna minimize round trips to the server. We don't want, you know, first, we gotta go to Rails, get the HTML, request the JavaScript, then I gotta figure out a bunch of stuff before that. There's a lot of round trips that happen. And this will make it a lot easier for our users.
And that's really what the point about this is, right? If you're preloading this data, if you're loading this data into Ember before it gets there, you're not gonna see your loaders, you're not gonna see your animated spinners, none of that, and ultimately you're gonna have a better experience. And that's really what's key. So we're in this, you can't really see, but we're in the same controller that we were before.
I titled it very creatively, the Ember controller. But so we're gonna grab our to-dos and then we're gonna call preload. And preload is going to set up an array and it's gonna just do a little, you know, magic just to prepare our data and then pass it to the active model serializer or the array serializer to grab it all out. Now you can use this preload method everywhere
in your application if you want, assuming it's going through the request cycle at start. So I can call preload on my to-dos, I can call preload on whatever other resources that I have. Once it's there though, we're gonna have this, you know, we're gonna have this preload variable and then we're gonna pass it to Ember via the window object. And so we're gonna set up this window.preload Ember data
and then we're gonna just call to Jason on everything that's in there and it's gonna be an array of arrays. And then render out Ember. I saw this pattern, I believe at first it was used by Discourse before they were on Ember data. But there's an open source anime application called Hummingbird that did this really nicely and so I've adapted it for my own applications.
So let's get set up with our client-side code. First things first, you gotta initialize, you know, Ember CLI, just has, you know, one config file. By convention, I'm gonna call it frontend, keep it at the root. And then I'm just gonna generate, you know, a new Ember application. And now we're gonna set up two things.
So the command on the top is actually important. We're gonna generate a resource of todos. Once we generate a resource of todos, that's gonna set us up with a model, a route and an index, I'm sorry, and a template. Then we're gonna need an adapter and then we're gonna need a serializer. So this is what Ember looks like. This is gonna be our model. It's gonna have one attribute, our todo, you know, it's gonna have a name which is just a string.
And what's important here is that we're gonna use a specific adapter. Now Ember uses, Ember data uses adapters to communicate from the client-side to the server-side. And it comes with a bunch of them. There's the fixture adapter for tests, the LS adapter for local storage. But default though, the JSON adapter is called the REST adapter. And that's what you generally use.
However, Ember hopefully also ships with the active model adapter which integrates perfectly with active model serializers. And if you're using Rails and you're using active model serializers, you absolutely should use the active model adapter. It makes working with it really, really nice and easy. And this is what we're gonna set up. This is gonna live, you can see at the top,
at slash initializers slash preload.js. And so very much like Rails, you can set up initializers in Ember. And what we're gonna do is on initialization of Ember, we're gonna first make sure that this is coming after our Ember data store has instantiated. Ember data store is where everything is really kept by Ember data.
And then we're just gonna iterate through that window object and we're gonna push it into the store. And this is gonna load up on initialization. What's great about this now is that we're gonna initialize Ember data objects. And it's gonna infer based on that root element, so based on to-dos, by convention it's gonna understand that now it's gonna push all these into the to-do model.
And what's amazing now about this is that it's all there now. We don't have to do anything. So we're just gonna set up our routers, set up our resources, our route. Now you're gonna see a lot of Ember code. This.store.find model, right? So ordinarily you'd see this.find.store to-do, which would make an API call to slash API slash to-dos.
Instead though, we're just gonna call all. We're gonna tell Ember data, give me everything that's in the cache right now, because essentially we've pre-cached all the attributes that we need, all the models that we need, and then we just render it out. And now we just have our template, iterate over it, and display the names. And this is really, really powerful,
because now that whole concept of spinners and loading bars and all of that, it's gone, and it's amazing, right? So don't fight Ember. Use conventions like after-mall serializers. Pre-loading is extremely powerful. It simply makes for a better experience for your users. It means that we don't have initial page load for spinners.
We don't have those loading bars. It means that your users, when they go to your application, especially in slower connections, they see it, and it's there. And then after that, do the regular client-side stuff. Make that first interaction with your application the best experience it can be. Finally, let's talk a little bit about React. So React was developed by Facebook,
and it has a completely different way of reasoning about how this all works. So instead of two-way data binding, which I should mention Ember does as well, there's one-way data binding. And so when the model understands that something has changed, everything re-renders. Okay, actually not. It would have to re-render.
Instead, it keeps a virtual DOM. And the virtual DOM is essentially kept by React, and it'll do a diff, right? So it'll have a virtual DOM. It'll know that things will change. It'll diff that with your actual DOM that's running in your browser, and it'll just go in there and change what it needs to. It's really efficient. It works really well, and it kinda solves the problem of this data binding issue.
Well, most important thing that it kinda leads us to, and the final pattern that we're gonna look at, is isomorphic JavaScript. Isomorphic JavaScript is this buzzword, I guess you could say, that simply means rendering your JavaScript on either the client or on the server. And because React is a virtual DOM, it doesn't need to use that to diff. It could use that to render.
And so we're gonna see a pattern now of using React to render, instead of just passing JSON data to the client side, right? Let's just render it straight from the server. Instead of going through all those initial API calls, we're spitting out HTML at this point. The first time I saw this,
in terms of React Rails implementation, was a blog post by a guy named Ben Smithit, and helped me out a lot in terms of this initial implementation. So this is what our controller looks like now. Our controller now is gonna pass the hash, at least on the index, and it's gonna have a todos, which is just gonna be all the todos, and then some form elements, which we're gonna need to implement with Rails.
I imagine in the future with React Rails gem, this is gonna be a bit easier in terms of the form stuff, but we still need all that CSRF protection and all that jazz. So this is our gem file. We have React Rails in there. We just install it, and we're kind of off to the races. So the first thing that React Rails gives us
is this view helper. This view helper, yeah, you can see the whole thing, okay. So we're gonna call the todos component to render out, and we're gonna pass in the property of that load JSON, so we're gonna call to JSON on that element, which is really just holding our todos and the form stuff. But the magic, though, is in prerender true.
Prerender true is all you need to do to render now on the server, and it's done, and it means that when React serves it, it's gonna serve it as HTML. The magic behind it is that it uses unobtrusive JavaScript, so it's gonna mount some data components, then React is gonna take it over, but it works really nicely, right. And React itself is built around components.
Components should have one isolated level of responsibility. If your components are a thousand lines long, I mean, unless you're doing something crazy, you're doing something wrong. Everything should be really small, really modular, and it's nice because then when something goes wrong, it's usually really easy to debug and figure out exactly where that came from. So this is going to be our todo list component.
Sorry that the top is cut off. React has a concept of props, properties, and state. Props are passed into the component and are mutable. State is managed internally by the component and is mutable. So at the top there, we're calling a function called getInitialState, and all that's doing is just parsing out the props that are coming in
so that they're available for the component to use. We're gonna have one function called newToDo, and all that's gonna do, again, we're just gonna pass that down. You're gonna pass a lot of things to different components in React, and that's gonna be some of the logic that the component needs in order to handle what happens when you have a newToDo. And finally, the render function. The render function is the only required function
that you have in your React components, and what you see here looks a lot like HTML. In truth, though, it's not. This is what's called JSX. JSX is an optional file extension, I guess you can say, that allows you to specify your views in what looks like HTML but isn't actually.
So this is really just JavaScript code when it gets rendered out, but now I'm setting up my div, I'm going to list, and I'm gonna create two components out of this. I'm gonna have my todos.list component, which is gonna hold the actual list, and I'm gonna have the form, and I'm gonna pass into those the properties that it will need to do what it needs to do. Let's take a look at the todos.list component first.
All this is gonna do is just map over those todos that were passed in, and then it's gonna create another component out of each of those called the actual todo component, which is just gonna be a list item. Again, very small, very modular. It really does make your code easy to work with. It's an investment up front, but if you do it this way and something breaks,
you'll be able to identify it really quickly. And now the form. So the form, I'm sorry that it's kind of cut off at the sides over there, but essentially all it is is just one function called handle submit, which then handles what has been passed into it once the form data is actually serialized and things like that. And then the form just does a little magic,
again with CSRF protection under the hood, and is able to post. And this is the same todo list that we saw before. What's amazing about this though is that it's all rendered on the server. We didn't have to do any, so forget about loading to get initial data. Everything at this point is straight HTML. Everything at this point has been rendered out.
Right, so each component only should have one responsibility. Don't make your components massive. Don't make them do a whole bunch of stuff. Keep them really small. It makes it really nice and easy. Pre-render on the server. We didn't even talk about some of this, but SEO, Google can't really crawl heavy JavaScript applications.
But for SEO purposes, this is a huge win because your initial page load is gonna be straight HTML. This is crawlable in a second now. Usability, especially for accessibility points, for users who are on slower connections, rendering this on the server side is gonna be a huge win for you.
And again, I need to stress that we don't really consider these because a lot of us have very fast connections and those initial ones are, it seems instantaneous. And you think to yourself, why is this such a problem? If you're on a slower connection and your users are gonna be on slower connections, it becomes a problem. It does become a problem. And so you use the magic, right?
Use the magic of UJS, which makes, in React at least, this is really nice and easy. It renders out from the server as HTML. The component will pick it up and then it'll do all its magic from there. And this, I think, is the final pattern and what we're gonna come to. Isomorphic JavaScript is the future. Doing this has so many benefits,
I can't think of a good reason not to. React has this obviously built in. Ember 2.0 is going to have fastboot, which is gonna do something very similar. And Angular 2, I haven't seen specifically that they're gonna enable server-side rendering, but the way that it's currently being structured and it's currently being built,
I can imagine that this won't be an option for you. So this is kind of where we come from and where we're going, right? Initially, our application starts up, we make a bunch of API calls, there's a lot of loaders, there's a lot of things that have to be rendered, and in general, especially in slower connections, it's not the best experience for users.
So one implementation is to just preload that data. Pass it via the window object, pass all the JSON over. We still have the problem of crawlability, we still have the problem of accessibility, but at least we don't see those animated GIFs just going round and round. But if we can server-side render, why not? Why not make it your sites have SEO?
Why not make it that you're providing a great experience for a user? And I think this is really what's key and I'm pretty confident that the future of JavaScript, clients.nbc, which do have some amazing benefits, will be this, will be that initial server-side render. So thank you very much. I'm happy to answer any questions. If you wanna tweet at me
or get in touch in any other way, please feel free. That's my Twitter, that's my blog, and yeah, thank you so much for your time. I really appreciate it. Guy over there.
I think those are the benefits. I think from an experience of your users, right, and they don't necessarily care. I'm sorry, I didn't repeat the question. The question was whether there are any other benefits for using server-side rendering versus SEO or usability. And I think, to me, that's a great reason for it. I don't see the drawbacks, right?
I don't see the reason why you wouldn't necessarily start server-side rendering. I don't think you lose anything. And I think that the frameworks like Ember 2.0 is gonna have this really easy for you to work with if that's something that you are interested in. And it just, especially, the connection is also something that's really big. Tom Dale, he wrote a bit of a blog post about this
where he couldn't understand why Twitter had switched over to server-side rendering, at least on first initial load. And it was because, for a lot of users, it's really fast, they don't even notice it. But for people on slower connections, it's actually, it becomes a really big challenge for them. And you wanna make, especially that initial one,
as best as possible. Yeah, absolutely. The question was about GON. GON is a gem that you can use to pretty much do what I did automatically. The reason that I did it in this particular context is because I wanted to show the integration with Ember data, how that can work really, really nicely. But if you simply wanna pass objects
to your JavaScript framework, and again, this will work for Backbone as well, really nice and easily, check out the GON gem. Then whatever you set in your controller on the GON object will be available in window .GON, and then you could pass arrays, you could pass active model records, active model records as JSON, and things like that.
Yeah, I've used it before, it works really nicely. Yeah, I've used Brombone, right? Brombone's a service though, it's something that you're paying for monthly. I'm sorry, so the question was that it is an alternative to doing pre-rendering for SEO. There are services like pre-render.io, like Brombone that will handle this for you,
and that's absolutely the case. But then again, it's a service that you're paying for. You're paying additional money to have your website crawlable by Google. That's something that I'd like to be able to do on my own. To be honest, I haven't heard of pre-render.io, but I imagine it costs something similar to that. And so it's not cheap, and so if I'm building an MVC, or if I'm building something that I wanna validate,
I don't wanna have to pay some monthly cost to make sure that my website's crawlable by as many people as possible. So the question was that React is very small, right? React is really just a view layer. The question was whether you can use that kind of small component base to generically introduce into your application
with Angular and Ember. With Angular, yes. With Angular, all you really need is the div that you'd specify where that renders out. I apologize, some of it was cut off, but there's a declaration on top of that template that shows you where it's actually being injected. So if you put on the HTML tag on top, it'll be your entire application. But if you wanna use Angular and just one div on your application,
you absolutely can, it's very easy. Ember, not so much. Ember, again, I could be contradicted by the creators in this room, but Ember takes over. Ember will take over your application. It's much harder to use small components of Ember. You'd really have to work at that. But for Angular, absolutely.
Right, so what I left off of all these slides is that, so the question was what are you gonna do when your application is tightly coupled, which it seems like, from your front end to your back end. And so what I left off of these slides is that what you're assuming here is that you're serving these frameworks out of your Rails applications. When you're starting up, when you're writing the monorail, this is absolutely true.
But often a lot of companies, mine included, will split off into various APIs to manage that place separately. Those, if they're serving JSON, those don't even have to be Rails applications, ours most, are starting to not be. So what we've chosen to do is we render, we use Rails on the front end. So we're using Rails to process that front end.
When it needs to, it calls out to the server to grab all the data, and then it renders out Ember from that Rails template. But yeah, if it is completely separate and you're only running Angular, and you're only, or whichever one, you're only running the server, then I would definitely encourage you
to use, it's not like Ember data is really nice in terms of making that transition as easy as possible. But yeah, for instance, you're not gonna be able to pass anything via the window object or anything like that, so that is the general concern. Yep, which one would I pick?
I don't wanna start any wars here. I saw a couple people walking in with spears before, it was very intimidating. Everything has a different use case. For large applications, I would choose Ember. I think that it is, I've worked with it a lot, it's really nice to work with, but it's really for large, ambitious applications. They make that very clear on the site.
If you're using something small at this point, I would choose React. And again, React is really just a view layer. There's application architectures around React to kind of integrate and make it work really well. But I would probably focus on those two, and mainly because you don't, when it comes to this syntax for Angular at least, this is gone.
These slides aren't gonna be obsolete when Angular 2 comes along. And so I wouldn't, if I'm starting a project today, I wouldn't put myself into a deprecation mode at onset at least. Anybody else? No, well, thank you so much for your time, everybody. I really appreciate it. Thank you.