 All right, the three of you liked it. The rest fell asleep, fair enough. I'm Gottry, I'm very happy to be here today. You can find me on the internet as a chink and code. I am a co-founder at a consulting agency called Ruhals. We're in Vancouver in Canada. If you need help with the Rails app or Ember apps or Ember training, we can probably help you. Speaking of Canada, I recently became a Canadian. So, thank you. It was a great country to be in, of course. It was a pretty long process, but at the end of the process, I basically get to go see a judge who handed me my citizenship certificate, right? When he shook my hand, he told me that now that I'm Canadian, I'm the face of a nation and I should always look out for opportunities to promote a nation and the values that we believe in. This is a responsibility that I take very seriously. As you can see, that's Conan O'Brien up there doing his thing, and up there in the audience, that's me with my Canadian flag. So, I figured no one really wants to sit in a boring talk right after lunch anyway, so if you don't mind, I would just use this time to push my Canadian agenda. As you probably realize, Canadian programmers are often underrepresented in the programming community. This is not because there are very few Canadian programmers, quite the contrary, but it's because they blend in so well with the Americans around them that you don't usually notice that they're there. This is no coincidence, of course. Canadians spend a lot of time learning about American cultures and values. This is a TV show that we used to have. It's on public television. It's 100% real. It's called Talking to Americans. It teaches you how to do this properly. If you don't believe me, you can look it up on YouTube. So I think it's only fair that we spend a little bit of time learning about Canadian and Canadian culture and learning about differences so we can better understand each other. So this is a great example to exemplify the differences in the values of our countries. This is how you report temperatures in America, of course. You probably are familiar with this, but for those non-Americans among us, the F stands for freedom. And of course, the system is called the degrees of freedom. This makes a lot of sense, right? And in Canada, this is how we do it. Obviously, the C stands for Canada. And because everyone else around the world, outside of America, uses the same system, you usually just say, oh, it's 11 degrees and people understand that, right? But if you're talking to an American or you just want to be extra clear, you can always say it's 11 degrees in Canada. You've probably heard of that expression before, so now you actually know what it means. Similar differences exist when it comes to programming. If you want to store Boolean variable, you probably do something along the lines of, it's empty or it's loaded. In Canada, we prefer to name them MTA or loaded A. If you happen to be a Ruby programmer, I made a library to make that easier for you. You can get that by running gem install Canada. Thank you. I realize most of you are JavaScript programmers, so you probably don't know what Ruby gems are. I was told that you can run this command alias npm igloos gem. To be honest, I have no idea what it does and it moves some sort of compatibility layer. Yeah, I don't really understand npm, but I tried it and worked for me, so. Anyway, I hope you learned a little bit about Canadian programming and we should probably get back to the actual talk before I get permanently banned from this conference. I'm pretty bad when it comes to naming things and when I was preparing this talk, I had a lot of trouble coming up with a good title for my talk. In fact, one of the feedback the organizers gave me when I submitted my proposal is sending the lines of, oh, I think this could benefit from a better title. So I figure I would take some inspiration from one of the most popular websites on the internet. So I thought maybe I would name my talk Free Terrible Hacks to Remember Law or perhaps a design pattern you should embrace. Yes. Or perhaps more simply, what colors are this slide? Naming aside, what I actually want to talk to you about today is adapters. For those of you using Amber Data, you might be aware of this thing called DS.Adapter, but that's not what I'm referring to specifically. When I say adapters, I really mean the generic concept of adapters, something that you might call the adapter pattern. The idea is actually pretty simple. Let's say you bought a vacuum cleaner that has one of these free-licked pins, right? And fortunately, the sockets you have at home is all too late, well, so, too pinned. So to use this vacuum cleaner at your home, you would need to put an adapter in between them. In this case, the adapter is doing a pretty trivial functionality, just like basically two wires in there, right? But in other cases, your adapter might need to be a little bit more elaborate. When Apple released the Lightning cable, they realized people had existing stereo systems at home that they still want to use, so they need to make an adapter for that. Now, this adapter is a lot more complicated than the one on the previous slide. These ports have very different specifications and they speak completely different protocols. One of them is even reversible, so you can't just stick a few wires in there and call it a day. However, in terms of functionality, they are both perfectly capable of accomplishing the same thing, which is streaming audio from your iPhone to your stereo system. So what Apple did is they basically put a little computer in there that decodes the signal on one end and transform it into something that the other end would understand. It's a pretty elaborate hack, but it works pretty well in practice. So what does that have to do with programming? Well, let's say you've just acquired a sensor that measured the current temperature. Unfortunately, this driver is programmed to report temperatures in the Canadian scale and your system expects temperatures reported in the degrees of freedom everywhere. So, of course, you can go ahead and rewrite all your code, right? But whenever, whether there's a feasible idea not really depends on how heavily you're invested in your code base. For example, it probably doesn't make a lot of sense to rewire all your sockets just to use a vacuum cleaner. So as an alternative, you can just write an adapter for it. Just like the real world adapters, the adapter code would expose an interface that the consuming end expects and internally it would dispatch these requests to the object that is wrapping. Now, this is pretty much the whole idea of an adapter and you probably use this pattern many times whether you're consciously aware of it or not. So, to show you how I would apply this pattern in the real world, in Ember apps particularly, I would like to show you the side projects that I have been working on, all right? Okay, so this is hack and use. You might be familiar with this, but if you're not, it's basically a website that you can post links to and people can bolt in them and leave terrible comments. So it is a pretty cutting edge in terms of design and functionality for a website that's built in the 90s. You just scroll through the comments and that's pretty much all you do, right? Okay, so what I did is I wrote a Chrome extension. So when you go to the hack and use website, it would seamlessly take over and whoops. And if I can find my cursor, I can maybe click on a few links. Okay, so you click on that and then it will show you the article and you can see the comments and you can fold them, hide them and stuff. I was told that there's an Ember link somewhere on the front page, but I can't really find it on there. Yes. Okay. Anyway, that's the extension. What else do I want to show you? Right, so you can switch different filters. That's pretty not interesting. What I'm going to do is to prove that this is actually running on live data, I will submit this extension to hack and use right now. And okay, that's live. If you want to follow along, it's at chaingo.github.io slash hnreader. I will show that later. But let's see. Latest submission if we refresh. Oh, it's not there. Yes, maybe I got famed or something. Anyway, we'll come back to it later and hopefully you can check it on your computer. Maybe you can see it on your computer. What else? Okay, finally, this one last thing. This is a completely useless thing, but it's pretty cool to show right here. So as you can see, there's a preference for how you would want things to be hidden by default or not. So if I slide this slider, you can see that is synchronizing that between all the screens and it's actually re-rendering their comments. I don't know if you can see it, but yeah, it's actually re-rendered that live on all three tabs. So yeah, I guess it's not very useful, but we will talk about the implications later. So that's it for the demo. Let's get back to your slides. Right, okay, so if you want to check out a code, is that my GitHub account is called hn-reader. So I hope you like the demo. Wow, that's a pretty cool Amber app. It's what does that have to do with the adaptive pattern, right? Well, in order to build a hack news reader, you would have to first get data from somewhere somehow. Normally, you would just talk to an API and it would send you back to JSON and you would be able to render those JSON on the page dynamically. And this is what Amber data would expect as well. But there are a few problems. First of all, at the time I started this project, hack news isn't really having an official API and so I have no servers to talk to. I could also use one of the unofficial APIs, but it's hard to tell which of them are still maintained or how reliable they are. They also don't have all the functions that you can find on the web interface so I can't do everything I wanted to do. Lastly, I can build my own API, of course, but I was way too lazy for that. I just want to get to writing front-end app and I don't really want to maintain and write server-side component for this. So if you take a stab back and look at the hack news website, you realize, actually all the data you possibly need to render that page is already on here because you're basically just taking elements from here and transforming into different representation. So if you can fetch the HTML page from the server, you can just parse all the data and turn that into JSON feed or whatever you want. In fact, this is how an unofficial API works. They just have a server sending request to the hack news server for the HTML page and then they parse the data out on the server-side and they send you back JSON. But since my extension runs in the hack news domain because it's taking over the hack news website, we don't really need to go through a server for this trouble. We can just make an HX call to the server, fetch the HTML page, parse the data locally in the browser and turn it into something that Ember data would understand. And that's exactly what I did. This is some pseudo code to show you the idea. Basically, you make an HX call to get the HTML page and then you run it through an HTML parser and then you extract the elements that you want it. From there, you can build the JSON feed that you wish you had. Now, I should warn you, all the codes I showed today on the slides are just pseudo code, so don't copy this and try to run it. It's unsafe. Just look at the GitHub for the actual thing. Now that we have the JSON data, it would be great if we have a way to store it locally and to use it to render our templates. Now, of course, in the Ember world, the default answer to that is Ember data. But Ember data is really designed for fetching data from a JSON API, right? So it can possibly work with some elaborate hack like this. That might have been true for Ember data a year or two ago, but today Ember data is actually pretty much just a local object store for modal data and it actually makes very few assumptions about where your data are coming from and how you're fetching them. Out of the box, it does expect your data source to be a JSON API that behaves according to certain specification, but yeah, so if your API happened to check all the boxes on the list, you can just plug it in and it would just work. But if your API doesn't behave exactly like Ember data expects, or in my case, if your data source isn't even an API at all, it doesn't mean that you're out of luck. From Ember data's perspective, the thing on the other side is really just a data source of some sort. The data source is something that can provide it with the right data and needs at the right time. And so all you need to do really is to drop an adapter between them to help them talk to each other. This is such a common pattern and such a common requirement that Ember data has actually built in support for this. They're called the DS adapter and DS dot serializer class. I can't get into too much details, but roughly the adapter is responsible for fetching the data in the server, so making the HX call, for example, and the serializer is responsible for interpreting the data and massaging them into the right shape that Ember data expects. So if you implement the right methods correctly, when you do this dot store find stories that Ember data is gonna know to use these adapters and serializers to fetch the data. Igor did a workshop on Ember data adapters yesterday, so if you have any questions about this, you should probably go talk to him instead. The second problem, okay, right, so that's a data problem. The second problem I ran into is URLs. Now, you probably know that Ember is pretty opinionated when it comes to how you should structure your URLs. For a page like this, you usually have a slash for application route, and if you have an outlet on a page, you would have a stories segment, and then maybe a story ID segment for the panel on the right, and then finally, the last outlet at the bottom for the comments tab, you would have slash comments for that. So the router API actually offers you some flexibility to control how you want these things named, but in general, you would have one segment for each outlet that you render into, and you can't really deviate too far from that before you feel like, oh, I'm managing all the things myself, I'm fighting the framework a lot. So this is a perfectly reasonable design by default, and it works great for 99% of the things that you're probably gonna build. However, in my case, my extension needs to maintain 100% URL compatibility with the Hekenuse website because when people go to news.ycombinated.com, my extension is gonna take over. If the URLs doesn't look the same as the original one, then when they share it with the friends, it's not gonna work, or when they click on the link from Twitter or something, then it's not gonna go to the right place, so that's not gonna be very nice. To give you an idea, here are some of the URLs I have to work with. On the left is what I would like to do based on Ember's opinion on URLs and my UI nesting on the right. That's the URL for the equivalent page on Hekenuse today. So you probably saw it coming. Let's throw in an adapter for this. On one hand, we have the Hekenuse URLs, on the other hand, we have the Ember router, and we just have to put an adapter in between to make them talk. What is not obvious, though, is where you would drop this adapter and what the adapter would look like. It might help if you take a step back and consider what Ember is actually doing with the URLs. If you think about it, the URLs is really just a way for Ember to serialize the current state of the application. When you first open the app, Ember is gonna deserialize the state from the URL and figure out where it should go first, and as you use the app, it's gonna update the URL, so whenever you refresh or share the URL, the app is gonna go into the right place. With that in mind, the thing that we need to adapt should become more clear. What we actually want to do is to adapt on how Ember reads and writes these serialized states, and from there, we can probably trick Ember into seeing a different URL than what is in the address bar. As it turns out, we're once again not alone in solving this problem. Out of the box, Ember actually has to support two types of locations, two types of URLs. The first one is called the history URLs, which is like the normal URL, and the other one is the hash URLs for older browsers. To support these two types of URLs, Ember once again uses the adapter pattern. These two mechanisms are encapsulated in two classes called history location and hash location, and they expose a uniform interface for the rest of the stack to consume. This is great news because we figure out how Ember has an adapter for this. We can probably just write our own adapter for our needs as well. So as you can see, this is pretty simple. Basically, we define get URL and format URL, which Ember uses to fetch the URL from the address bar or from the hash. In this case, we just call it super and we transform the URL internally according to our mapping, and when Ember tries to generate a link, oh, sorry, when you use the link to helpers in your handlebars templates, Ember is gonna call format URL and turn that URL into the right format before putting it in the href attribute of the attack that it generates. So, yeah, because Ember already has to support these two URL schemes anyway, once we implemented this correctly, everything just works across the stack, and to be honest, I'm a little bit surprised by how well this worked out because probably no one else uses the location adapter for this purpose, but I think that's actually a great testament to the power of the adapter pattern by slicing things at the right boundary, the right abstraction. Your code can actually work seamlessly with use cases that you have never imagined when you wrote the original code. Okay, finally, I'm running a little bit low on time, so I'll go through this one pretty quickly. If you remember, I showed a trick where sliding the preference slider on one tab changes everything in the other tabs as well. The problem I was actually trying to solve is that I would like to store the preference in local storage because I want them to persist across browser sessions and all that. So, but at the same time, I would like to bound to those values in my templates or in my controllers and my routes, and I need to figure out a way to do that. In Ember apps, the data bounding functionality is provided by Ember objects or more accurately, the Ember.observable mixin.ember.object uses. If you put them side by side, you realize that although the local storage and Ember observables has pretty different API, functionality-wise, they're actually pretty much equivalent in the sense that they're both implementing this thing called key value observing. Basically, you can say I'm interested in this key when it changes, let me know, and that's pretty much what local storage is as well. So, if you write an adapter for local storage that exposes these interface, then the rest of the Ember stack, the templates, the observers and everything else can just treat it like a regular Ember object and bind to it accordingly. So that's what it did. I don't really have much time to go into details here, but yeah, please look at the code on GitHub and you can find me at the conference if you have any questions. All right, so with these examples, I hope I have showed you the power of the adapter pattern. I think this is a pretty important pattern for us Ember developers to learn because when using an opinionated framework like Ember or Rails, a lot of people will tell you that, oh, that's a bad idea. You should be using small, composable libraries instead of big framework because what if your constraints doesn't line up perfectly with the framework's choices, like you're out of luck in that case. I don't think that's necessarily the case. I think if the framework is doing its job right, a lot of time, if you can be a little bit creative about the problems that you're trying to solve, then sometimes these solutions are just one adapter away. And in fact, if you are using a lot of small, composable libraries, you're just writing all those adapters yourself whereas an opinionated framework just have all of those adapters written for you by default and if you don't like it, you can just replace the adapter and replace the free adapters that you can't use and you use the 35 or 50 adapters that comes with the framework and instead of writing all 50 yourself. So I think once you're down the path of enlightenment, the possibility here is really endless. While working on these slides, I have come with several ideas that I would like to share with you. As you might know, the latest version of Ember supports two templates implementation called handlebars and HTML bars. And then I thought about this a little bit and I remember this slide that I saw somewhere else. On one hand, you have HTML and then you have like div and span and images, like things like that. On the other hand, if you're writing an iPhone application, you have corresponding things called UIView. UIView and UIImageViews. And so I thought, hey, like I would, maybe I can write an adapter for that. So I'm very, very excited to be reviewing this secret project to you. It is called Cocoa Bars. And for all of you Ember Convent attendees, you're gonna get exclusive access to this project today. Not only will you get exclusive access, you're gonna get exclusive commit access to this project. Because I believe in doing everything in the open with community involvement, they're actually exactly zero commit in this project at the moment. So please get to work. Anyway, that's all I have prepared for you today. I hope you learned something new and you have some new ideas to take home with you. I apologize for the excessive trolling. And to Ramadi for that, I would like to end this on a positive note. So if you fell asleep and you don't remember anything else from this talk, please remember one thing. If Chen can call, then so can you. Thank you very much.