 Okay So for those of you don't know me. This is my name. This is where you can get me on on Twitter at Nick's. I'm a Rouse developer long-term Rouse developer. I'm from Wellington in New Zealand and I'm now obviously living in London I'm working on this. This is called gelato.io. It's my startup It's a tool for Having really cool API documentation. So if you've got an API you want to get some more developers onto it You want to make your docs really cool come and see me and I'll and I'll get you in on the better of that So you might have noticed that I have a bit of an accent and I'm not from here completely different to Aaron's accent, obviously We we actually came the long way here So we went like this and all the way from Shanghai to London. We were actually on a train So apart from a little sort of gap in the Baltic States Where are the EU is apparently still building the tracks makes it hard to catch trains? So yeah, I feel like we I know a decent amount about trains and journey So I thought I would take you on a bit of a train journey today So this is all about the things I've learned and the problems I've encountered and Things you can do when you're building something with in the JS and so that's my beautiful title slide The alternate title for my presentation. Can you tell I like titles? I've had three title slides is how I learned to stop worrying and love the hamster Speaking of which I'm obviously pretty new to Ember. I've only been doing it since about October last year So I might get stuff wrong In fact, I probably will get stuff wrong if I do please let me know afterwards because that's how I learn new things So like I said, we're going on a bit of a train journey So I thought I'd use something that you guys are probably all familiar with but like I really love the underground But everybody here is like this is the worst thing ever So we've got five stops First off we're going to talk about getting on the right train obviously pretty important. Then we're going to talk about getting set up We're going to talk about some translation difficulties dealing with isolation and insanity and then the Zen of Ember The train is now ready to depart. Please mind the closing doors So the first ever any successful train journey is obviously getting on the right train So I was building my startup I knew what I was going to build and I knew that this was the kind of UI I needed This is what a modern web application looks like it's got this dynamic responsive UI And yeah, I also knew that there are a bunch of different ways I could get this heaps of different JavaScript frameworks in fact almost too many We kind of had this I had this sort of paradox of choice. So this analysis paralysis effect where you know There were so many good options, which one was I going to pick? One thing to keep in mind is that it's not just about going fast. I love this here So this and the slide I showed before is a picture from the Shanghai Monorail And I love the Shanghai Monorail not just because it's the world's fastest regular commuter train And I got to fly at four hundred and thirty kilometers an hour along magnets But also because it's a really really awesome development metaphor You see that the Shanghai Monorail leaves from Shanghai Pudong Airport and goes to half way to wherever you want to go At which point you have to get off get on to the regular slow crammed subway and get into Shanghai proper So it's a really good reminder that going fast is all well and good But where are you ending up? What's the problem you're solving? What's going to matter to your customers and what's going to make you money? So obviously for me I had my problem. I knew what I was building. I was building July 2. I so I knew I needed this Dynamic responsive UI looked on the ember website and lo and behold the first words are and it's all for ambitious web applications Great that sounds like me. I'm definitely building an ambitious web application I need to make sure that I'm pragmatic not idealistic because it's a startup. It's just me I don't have a whole lot of money I can't spend three months spending my wheels trying to get the right dependency injection framework going and so There you go. The next line on the on the ember.js homepage. It's more productive out of the box. Excellent sounds like me And then the last thing is well, basically I'm dumb. I need lots of hand-holding I need to get up to speed and need a nice easy ramp up And so again guides.emba.com is a really really great resource and there are a lot of tutorials out there And a really really great community. So yes, great This actually happened after I picked ember as a language and it kind of reinforced my decision I was initially sort of worried about the Google ability of ember if you will excuse the terrible pun But then you heard I started talking about this idea of stability without stagnation Which I really like, you know, I've got a business to to make customers. I've got to make money So I don't want to have to go rewrite everything just because some programmer somewhere decided that there was a slightly better version of Ivory Tower and now I should have to write everything in a new language This is what I was doing. This is what my JavaScript code used to look like admittedly It would get a bit more complex every so often and it would start to become a copy script class but effectively what I was doing is I was Listening for direct DOM events on DOM elements and going and updating Another DOM element of the same DOM element based on those so it was kind of an if this then that or this or do the other thing You know this kind of procedural thinking So this here, this is the handlebars you need to give you that dynamic response of UI example I showed you earlier and this is when I when I wrote this for the first time This is when I knew that I had the right tool for my job So it was much more declarative much more about here's what you need to give me the UI I want rather than in this case do this but do this but only if it's a you know If it's a rainy Tuesday, and I'm wearing a blue t-shirt do that It's much more about you're declaring what your application looks like All right, so great. We're on the right train. We want to get set up. This is a train in Vietnam So I'm a pretty stuck in my ways rails developer. I I knew what I wanted I knew the tried and true so what do you do when you want something new as a rails developer you go and find a gem You go install the gem and then so of course I ended up with ember rails Now ember rails is a really nice gem. It's just a little bit kind of like a slow Train a little bit rickety. I had issues with getting the asset pipeline to work at all or in a performant way I had deploy problems that testing set up was either non-existent or I really couldn't work it out And there was a distinct like the main issue for me was that was a lack of standardization There was no obvious place for all of my components to go. There was no obvious place for all of my controllers to go So what I did is I went along to the ember linen project nights and in And I think multiple someone's there suggested that I jump on to ember CLI. Thank you for that Jumping on the ember CLI is like getting on to one of these sweet bullet trains He's got like 250 kilometers an hour and you wouldn't notice they're as smooth as butter. It's really cool Suddenly everything made sense like everything had a place. I knew I had my bearings I had testing baked in I even had an ember command And this is brilliant coming from rails because I was used to having that rails command To do everything for me used used to having the God command. So it was nice to be able to do in the s in the G Ember test and just have that working First issue I ran into Ember CLI ships with its own server and then you've obviously got your rail server with them You're the embassy li server runs by default on port 4200 and your rail servers running on port 3000 So you're technically speaking cross origin. So now you've got to go and Set up all the cross origin resource sharing headers and do a whole bunch of really boring stuff to try and actually get Two apps that are both running on your local machine talking to one another So I did this I just chucked in the rack reverse proxy gem and effectively just transparently proxied anything Beyond the slash app and in my rails application just Transparenly proxied that on to port 4200. So yay as far as they're concerned. They're both on the same post no cause problems You only have to do that for development because it's just like a couple of lines of engine xconfig to do that in production And you've got a nice compiled slug. So yeah, if anybody wants to steal that, I'll probably put the slides up Another thing that I really wish I'd kind of understood better when I got into ember CLI was ES6 modules Ember CLI makes really really heavy use of these and I just kind of thought I can figure it out So this here is a copy verbatim from this blog post by someone a lot smarter than me He's one of the founders of discourse. So you should go and read that blog post if you if you're like me And you didn't don't really get ES6 modules. It's worth understanding one of the things that again didn't seem to penetrate for me was that Was that the ES6 Resolver of sorry the ember CLI resolver does some clever things with the paths So if you've got a mix in an app mix ins it will do your app name slash mix in slash super mix in so you your app Will map your app name will map on to the slash app folder So initially that's confusing but then you're like, oh man, this is really cool If I want to import something from my app, I just use my app's name It works for ember CLI add-ons as well So if you happen to be using the ember CLI accounting add-on accounting.js add-ons everybody say thanks to Miguel You can import functions from there just using the name of the add-ons You can just do accounting slash format money really really cool to have that resolver around to do all the path munging or that rubbish for you Another sort of part of the ember CLI story, which I think is potentially a little bit undercooked or maybe still working on Is installing third-party libraries? I think I've managed to figure out a way that this works for mostly everything So we'll see we'll go through my sort of flowchart and we'll see what you all think So the first thing I do if I want to install a third-party thing is I check ember add-ons comm see if somebody's been really nice And made an embassy a laishim for me if there is it's really easy to install it ember install add-on Namely add-on bam. You're done jobs done There's no ember add-on. Okay. Well, hopefully there's going to be an NPM package Most modern things have an NPM package somewhere and you can install that really easily NPM is still whatever the library is called Don't forget the dash dash save dev I had no idea what that meant initially and then I realized that what that does is it persists your your third-party library version everything to your package.json in a similar way to your gem file or Kind of like a cross between gem file and gem file lock And if you don't have that everything is going to break on production on other people's machines because it's not going to have any of your dependencies No NPM package. There might be a bowel one So for a bowel package you can look on bowel.io or I don't really like this search thing So I just look for a bowel.json and to be fair most things have that Installing a bowel package is pretty easy similar to installing an NPM package Again, don't forget that dash dash save dev And then the one other step you need to do is you need to make sure that broccoli knows about it So you need to pop it into your brock file.js Normally in the bowel package There's an AMD or required js compatible file that's been built in like a slash disk directory That's called like you know dist everything that's in this third-party package.js and you can just import that file and In the CLA will work its magic and so you can actually use it Last resort, what if there's no bowel package? This is some like jQuery plugin that's been gathering dust on GitHub for six years You still can use it with in the CLA You just slap it into slash vendor and then same thing you would use you import it in your brock file So just import vendor your lib, whatever you might also have to add it to js and RCs If it's a global like on window so that your test stop complaining This is our mascot. He's a panda called Mr. Pung from Hong Kong Sitting on one of those bullet trains kind of contemplating is what I was going for there Seems you can't see his face. It's hard to tell One thing that I'm still like kind of trying to work out is asset sharing So I have the rails app serves the log in log out forms or that rubbish and the ember app does the application itself They obviously both have buttons the buttons have the same CSS I want to share them should I be serving that CSS through the asset pipeline with sprockets Should I be serving that CSS through broccoli and through the ember asset pipeline? How do I share those things around and so I'm interested if somebody has a solution to that? Maybe they can tell me about it and I can steal that All right, third stop Dealing with translation difficulties. So for those of you who don't read Cyrillic. This is a Starbucks coffee in Moscow And it's fairly easy to get your rails app spitting out JSON that ember can understand Most people tend to use active model serializers They've recently embarked on like a pretty ambitious rewrite and I think that's sort of dovetailing in with the JSON API stuff So my suggestion is to stick with the 08 stable tag for at least now that's worked really well for me This is the config you need to put into your serializer classes to have it generate JSON that ember can understand You need to tell it to embed IDs and include models So this is the JSON that you get out basically So if you have a developer and a developer has many meet-ups What will happen is because you've told it to include IDs developer will end up with a meet-up IDs Property which is an array of IDs obviously and because you've told it include true It will side load the meet-ups for you which means that you get all the meet-up information without having to do a second Ajax request. So that's really really cool Another problem I hit and this was kind of an issue of my own doing I decided that I was going to use these Instagram IDs Which are really really cool. They are sort of these pseudo time stamp shard based unique IDs That you can generate with a postgres stored procedure I won't talk too much about them because the blog post is really cool when it's with Chahia So basically the idea behind them is it's kind of the same as UU IDs You don't want to leak the information, you know users slash 63 means you've probably got 63 users if the next one is user 64 Not entirely necessary, but kind of cool worth noting that they are 64-bit integers and by default Active Model Serializer will send them through in JSON as integers and we all know that JavaScript does not deal with 64-bit integers Very nicely. In fact, it doesn't and the 53-bit integer you get back instead The supplementary integer it looks sort of kind of like this. So initially you're kind of thinking, huh That's really weird. Why is that ID not found? And then you realize 64 bit So this is the monkey patch that I use for Active Model Serializer to get it to treat everything as a string ID So it's pretty simple. It's Ruby, you know monkey patch bust up in the class tell it to treat everything as a string Cause it back up again If anybody wants that code then more than welcome to steal it Jbooter I think a lot of people grab Active Model Serializers and they think yeah Jbooter I don't need that. There's kind of a reason it's the default for Rails It's a really good declarative way of talking about the JSON response from a particular action And it's really good when you need to paint outside the lines slightly You can do stuff with a whole bunch of methods in your serializer and things like that But I find that it gets really unwieldy really fast and this also means you can access your view Helpa logic So if you have stuff for avatars or images or any of that kind of asset path stuff asset pipeline stuff You can access that in Jbooter. So definitely worth checking out This is New Zealand by the way You should all go and visit We're contract bound to Pitch New Zealand to everybody who's not Akiri And they sign it on our visa You kind of get this uncanny valley effect a little bit when you're going from Rails to Ember in terms of the terminology Because they're both MVC frameworks they tend to use the same terms But things that are called the same don't necessarily have the same job Or work the same across both frameworks Models nice nice and easy They're basically the same across both frameworks Controllers a little bit hard So the thing that does the job of retrieving model information from the database And then kind of pushing it up the stack with minimal processing in Rails We call that a controller in Ember that's called a route So And this is extra confusing because in Ember you also have controllers But their controllers are closer to what rails people would potentially Call a view model maybe So in rails you have kind of the view helper view model stack And then in Ember you have components and template pairs And they can be nested down and things like that I just about put controllers in there But Ember 2.0 controller were going away So I put component there So just imagine it sees routable component Another thing that really really confused me And again it sounds silly But it was just a bit of an a-half moment when I finally figured it out Is the actual definition of the routes So in rails and your routes.rb you save resources hamsters You get those seven magic actions You get the index get update all of that In Ember when you say that you just get the collection routes You don't get all the edit and all of that guy So you just get the tutorials route and the tutorials index route You also get the loading and error kind of substates But you get those for everything So if you kind of want a similar routing call To what you've got in rails You need to define each thing individually So you can do that by just passing a closure To the second parameter of the resource call So it seems obvious but it's really confusing Because the API is super similar In rails it's called resources this And it spits out a bunch of them In Ember resources this only spits out the collection ones What we'd call index in rails land Dealing with isolation and insanity So if you take this video and loop it for about three days That's what riding a train through Siberia looks like It doesn't change much This is Mr. Pung again He's staring out at the Gobi Desert And the testing story in Ember CLI Sometimes feels a bit like this They've kind of gone down this path Of having each unit completely and utterly isolated From anything else So they have this really cool needs functionality But this is the actual needs array From one of my components And you can see that it just gets crazy fast And we're talking about a pretty small app We're talking about something that I can bust out in four months So it's not huge So effectively for those of you who haven't seen Has everybody seen the needs stuff before? Do I need to explain that? General nodding of heads Okay, I won't explain that So sometimes this is me Literally herding yaks in Mongolia When there were yaks I was like I am going to chase these yaks And take a photo of it So that I can use it in some tech presentation At some point They're pretty fast You've been doing well to get close enough to shave one And they jump as well They jump over the little ditches and everything So anyway Sometimes it felt a bit like yak herding testing Sometimes it was a bit like yak herding Going through and writing tests in embassy ally Because you would have to go through And if you had a CSRF service That was generating getting a rail CSRF token You'd have to fake that out for your component test If you had an embedded data store A DS store, you'd have to fake that out If you had models coming out of the store You'd have to fake those out And so you end up building this whole like House of cards around before you actually Can test the bloody thing that you're trying to test As you can tell it drove me a little bit nuts Fortunately that has changed Yes So This landed this morning actually I jumped on IRC I chatted to Robert Jackson It turned out that the thing I wanted Needs going away Was like 90% done And he pointed me to the last 10% I got it done and we landed it So you can now just specify integration true And that means you get to decide what subset Of your application you want to test at any point in time So thank you Robert And thank you Jamie for steering me In the right direction and everything It's actually really really really easy To pitch in on this stuff And I love this IRC process I mean obviously the one sign Of a healthy open source project Is that they encourage and welcome contributions A further sign of a super healthy open source project Is that there's a transparent and easy process To go through in order to get those contributions accepted So this is really really cool In order not to go insane When you're in a very confined space For four days and you can't leave You need to remember to clean up after yourself So again where else developers We're used to each request being largely item potent We're used to getting a brand new clean slate Every time somebody does a get or a post or a put Or whatever Done work that way in Emberland You were going to be in this browser environment For a while those transitions That Aaron was talking about Are not getting you a whole new browser environment So you best be tidy If you're going to do something like this Inside a component So here we go I've got a component What I'm doing is When I'm inserting the When the components inserted into the page I'm saying I want to do this stuff When the windows resize So I'm listening to a jQuery event Outside of the component element When the components inserted If you're going to do that You've got to do this as well So when you're destroying the element You've got to go and unbind that resize listener Because obviously Ember can't do that for you Ember doesn't even know about it Destroying the components Not going to do it by default Because your listener is on window So you've got to remember to do that Otherwise this is what happens Somebody decides to resize the window in your app And you end up with like 358 exceptions In your array gun and your email inbox Is screaming at you So yeah make sure you do that This error message Coming from one of your handlebars templates Cannot read property description of undefined This one had me tearing what little hair I have left out It was so frustrating It's like that will remember what does it mean What this means Well can anybody spot a bug? Yeah see exactly it's really tough to spot Bam! It's the wrong friggin closing tag So like I was going to say this seems dumb But heap of smart people are like What's the issue? So yeah if you see this Cannot read property description of undefined And it's coming from one of your templates And you don't even have a property called description You've never thought about description Or like told Ember about it at all That's what's happening You've nested the bloody things wrong Yeah so I'm probably going to try and Land a patch to make that say You're a dumbass and you nested things wrong Heaps of really good resources We've already talked about the forums tonight This is Jamie and Aaron helping me out Thanks guys It's really really good to go on there And the best part is If they help you out and it's useful You can go and buy them a beer at the pub Really soon There's also this guy called Chris Ball Who's made a really cool resource called It covers a bunch of what I talked about tonight And a heap more stuff So definitely we're checking out There's a mailing list on there So you can just get emails Last but not least The way of the hempster So again being kind of a stuck in the mud Rails developer I was writing everything in coffee script Because that's what you do in Rails land And you know You abide by the rules of DHH Ember seems to be a bit more On the ES6 side of things So I went ahead and Drunk the ES6 decaf cool ad So you still get all of the really nice things That you want from coffee script In ES6 You get If you've got those fat arrow functions The lexical bis functions You can do the same thing You just need to add a few more special characters You actually do need to have those Method parentheses at the front there unfortunately You also got string interpolation In ES6 they're called template strings All you got to do is replace those double quotes With back ticks and swap out your hash For a dollar sign And you've got string interpolation Awesome There is a ton more to ES6 That does not even count As making a scratch on the surface Babel is the new name for 6 to 5 That is the JavaScript transpiler And they've got a really good learn ES6 section So I suggest you check that out Computed properties in the ember object model So computer properties are kind of Like an ember object superpower They're really really cool So just a couple of them That came to mind when I was writing this Alias So you can get a two way binding Which means that if I update API resource or resource They'll both stay in sync Really really cool If you're like me And you like to save a bit of typing You can use it for Like a default value So if you want a one way binding That's really cool And you can also do these kind of Enumerable style Properties where they'll go through And so that changes made Berlin will be true If any of the properties In the parameter list are true So that's really really cool as well And you can extend that out So you can observe Any of the Elements of an enumerable So here I have a model The model is a meetup Meetup has many talks And this computer property Will go and set that talks change Berlin to true If any of the dirty Berlin's on any of the talks change So that's really really useful When you have a belongs to And you want to set the dirty Property on the parent model Again turns out that There's lots of help around So guys at imageas.com Has a whole object model section And it's definitely worth At least skimming through that There's a ton more of those Computer property macros And they're all super super useful Initially I was kind of treating Handlebars a bit like ERB So I was thinking about it In a procedural way I was doing these ifs And if you try and treat Handlebars like ERB You're going to have a bad time Because it's not like ERB at all This is how you should do that So here in my model I just add a computer property Called display title And what that does Is that goes and sets the title To unnamed if the title is If the title is blank Otherwise it returns That the model title And because I've got title As the first parameter To the computer property there It'll update every time The model's title updates And I can just do that In one quick handlebars tag Brilliant This is really nice I've got my domain Concept represented in my model It's in a testable Reusable kind of way And it's more declarative And less procedural So I'm actually talking about Here's what this looks like Rather than here's how this behaves Another really stupid thing That nobody told me But I wish I'd learned earlier Is that you don't have to do Get, get, get, get, get, get, get You can just chain them on Like I'm airing my dirty laundry here It's all the stupid shit that I did You've also got first object And last object Thanks Jamie for telling me About that one On any ember innumerable So you don't have to use Like any nasty hacks Or what I was doing Was using underscore js Every time you don't need it Embassy li also has A bunch of things That you never knew you needed But now all of a sudden You cannot live without And for me that's definitely Live reload I kind of scoffed at this You can get it set up for Rails But it was kind of like Eh, it's not that tough To press the refresh button Oh my god, this is awesome It makes me feel like a wizard Because by the time I've Command tabbed back to my browser It's refreshed and I can click everything Ah, it's so cool I knew that I'd kind of Converted over to this When I found myself staring At a vanilla Rails app And thinking, why the hell Isn't it refreshing? So that's the end of our journey We're in London This is London from the top So thanks very much to Giselle And yeah, thanks to Flickr people For the photos Yeah, questions? How was the Wi-Fi? Actually in Vietnam I bought a SIM card For like seven New Zealand dollars With unlimited data So seven New Zealand dollars is like Three pounds, fifty pence Yeah, and that was Not quite that bad And it was free unlimited data And I was sitting there On the train coding away It was great It was better than Russia Can you say about the fuselage To your model page Where you were looking at The computer title The way I would normally do that Is put the computer property In the controller Because controller really is a view model Yeah So I keep the model clean With the raw data And then if I'm going to Place that with unnamed Or something else that's different Put that in the view model So I keep the model clean Especially if you're using something Like embedded data You're not editing the model You just post it back And it's excellent interface It's the same as the data You actually post it back Yeah, I mean embedded data Won't post that back By default But if you look at the model It would look as if it would Yeah, I think you could definitely make An argument for putting it Into the controller or the component Because it is a display thing In this case I'm using it everywhere So it just sort of made sense To me to put it at the highest level Basically because the only other option Would be putting it in a helper And sharing it across And it just seemed way too complex But yeah, you're quite right In general you probably should Put that stuff in the component Rather than in the model Also I'll just back up Two things Which is the get, get, get Caught out by that I only learned that recently And the embedded computer stuff In the guides there's loads And they're really powerful And you can chain them So something like that You could do that with computer properties By chaining them But then you get into this sort of Like I've got four extra Computer properties on my thing Just to have one thing But if you've not looked at it It's been five minutes It's really great And there's community Supported ones as well Oh really? Yeah, someone's Someone's written for you I have a friend named MRCPM Most of the initiative with me I know I am the manager And he's basically a bunch of Useful general groupos And he found one of them One of the main things That has to give to the world Is that you can actually Compose computer properties And you don't need to create Extra keys That you don't care about You can say something like An embedded computer And inside you use an embedded Computer port And inside you do an embedded Computer default value Nice What's that called? MRCPM? No, no it's not It's MRCPM MRCPM Alright Man, I seem to run into Your stuff on the internet Everywhere I look Miguel It doesn't use CLI on the middle Because it started before It was a thing But it's another movie It's pre-CLI It's pre-CLI It's answer history Sweet, anything else there? Everybody's looking at me already Sorry, can you go back to the slide When you were registering The jQuery component You were watching the window resize Watching the window resize It's clean up after yourself Yeah No, the next one This one Yeah Yeah Will destroy element and did insert It's kind of annoying that Those hooks are not named As two sides of the same coin Like it should be Did insert element or like Will uninsert Will remove element or something Like there should be First born problems Yeah Alright, that's enough from me Thanks