 I'm going to get going, so my name's Chris Fagani, so my handle on Twitter is Lindy Hop Chris, so this might put it into context as to what I'm up to, but it's Lindy Hop Chris because I teach dancing in my spare time, teach swing dancing, but I decided to swing Chris, probably wasn't the right handle to have on Twitter, so Lindy Hop is the main type of swing dancing if you've never heard of it. I teach for a group called Swing Patrol, so if you ever want to give some 1930s dancing ago, then check them out. I'm building something called Dance Cloud, so it's for dance organisers to use, it's basically a cloud service, hopefully does exactly what it says on the tin, so that's what I'm working on at the moment. It's going to give you some backgrounds. The aim of this talk is to demo what I've done so far, so it's not yet production ready or anything, but it's getting towards a point where I can start playing around with it in a real environment. A little bit of backgrounds. As I say, it's a cloud application for dance organisers. I'm currently piloting some capability this year basically. My aim is to launch a bit more publicly in January, February, basically piloting it with the dance school that I teach with, which is nice and easy to do. For this year, there's a behind the scenes admin app that I didn't do in Ember. I was learning JavaScript at the time, so I decided to do a lot of it myself and came to the end of it, deciding that I should look at one of those things called an MVC framework or something that's probably the easier way to go. The thing that I'm working on I'm going to demo is it's a public facing web app, so members of the public will actually go in and I'm building that using Ember, so that's what I'm up to. It is my first Ember application. This slide is why I chose Ember.js, so it's not got no link to I'm not trying to plug it unnecessarily or anything, it's just what I chose. My architectural design from the start was I wanted a complete separation of the server from the client, so the aim is that the server is just a restful API and I can then connect any client I want up to the API. There's a number of use cases for the dance world where I decided that was not going to be my approach. It's not the only way I could have done, but that's the way that I've gone. For me a big reason for choosing Ember is I'm self-taught, so I'm learning as I'm going along and programming, so from my perspective convention is a really great thing. I love the fact that Ember just follows conventions and if you stick to these conventions then hopefully it should just work. For me that was really probably one of the biggest reasons for choosing Ember. I like the Ember convention because I think I was looking around at different MVC frameworks. There's Ember and Angular and there's a whole load of stuff if you Google it as saying people shouting that you should use Ember and people shouting that you should use Angular. When it came down to I looked at effectively the framework syntax and the Ember one made more sense to me. I looked at some Angular stuff and I'm sure if I delved into it I could probably get my head round it, but Ember just seemed to make a little bit more sense for me personally. I love the documentation guides, cookbooks, API docs. I've been using them loads in the last six weeks as I've been building this application. Ember data for me is actually a big plus so it's not there yet. There's problems with it. It's actually moved on quite a lot since the beginning of September which has been really good and I'm using it in the application I'm going to demo. It's the potential of it. I was trying to work out how to format my API for instance and actually if I'm using Ember data I just format it the way that Ember data uses. It gave me a framework to copy. It's not there yet. I'm having a few problems with it and I had about five days where I was bashing my head against a wall at one point trying to get my head round why it wasn't working. But I got there eventually and for me it's a plus point for it and community. I've been using things like Ember Watch just reading through issues on GitHub and all that kind of people trying to help fix stuff that's been really good for me. So just before I demo the app just basically what's going on on the server. I've got a custom built framework on the server which does things like I've got multiple tenants at dance schools sitting in the same database and my framework enforces the tenancy so that there's no leakage of data across different dance schools. I've got role based access control and all the business logic is enforced on the server so I suppose linked to that question about security. It doesn't matter if someone goes in and changes something in the Ember app that I've built because the logic, the final say on the business logic is on the server. It's written in PHP just because that's all I know so I don't know. Probably if I went out and learned Rails, Rails might have been a better fit but it works fine in PHP. I'm basically just currently just serialising directly to the Ember data style of JSON so this is a screenshot of a dance event. At the moment I'm exactly copying it so there's no conversion as it goes into Ember data. That is the format that Ember data understands. But my actual slightly longer term plan is actually to serialise to, if you haven't heard of it, it's JSON API standard that's emerging. It's quite well documented if you go to JSONAPI.org. I think YCATS on the Ember team said that he'd like longer term there to be a JSON API adapter in Ember data. So my longer term plan is actually to serialise it to the JSON API standard. Just to explain what this app does. It's public facing but it also has sign-in so it has a state where you can view stuff, not sign-in but then there's some stuff that you have to sign-in to access. Basically the idea is you can browse upcoming events, you can register for those events. So for dance schools there's normally questions involved as people are registering so it does those questions but then it also then needs to issue the ticket and so the person needs to pay for that ticket. So that's basically the workflow managing. You probably describe it mainly as read with some write in terms of Ember data, a lot of the objects that are going through Ember data are never changed so that makes it a little bit easier. One reason why I've chosen Ember is the future capabilities. Actually I want to plug in, it's not in there at the moment but a calendar that the user can fully search and everything like that. And it's actually far more efficient for me to do it in Ember because a dance school is not going to have a huge number of events coming up. So actually I might as well just download all of those events into the Ember data store and then just let the client do all the filtering and searching of it. It's going to be far more efficient for me. There's going to be a lot less hits on my server so that's kind of future. So my challenge has been doing this, learningember.js. As I said it's the first time I've done it. My only real experience was coming to the May hackathon that it had in this office. I worked on Jamie's team and to be honest Jamie pretty much did most of the programming and I was sitting there kind of amazed at what was going on. So I've gone from that state to building what I'm about to show you. So these challenges are kind of things that weren't, didn't easily jump out of the documentation. So I've had to do a lot of research to figure out how to solve them. So they may not, if you've got more experience than me, you may instantly know how to solve them. But these are the ones where I had to do a bit of research. So it's hosted on a wildcard subdomain where basically, I've got it there, tenant.dancecloud.com where tenant is the name of the dance school. But the server is going to enforce only getting records off that. But of course a user could type in anything.dancecloud.com. So the first thing it has to do is rather than showing the application has to validate whether or not the subdomain is actually valid. There's a lot of countdowns in this which I'll demonstrate which took me a while to figure out the best way to do that. I'm using Stripe as my payment system which if you haven't heard of Stripe I really recommend you look at it. It's really new to the UK but has been going in America a lot longer and it allows you to do credit cards via an API. I don't know, hands up if you have heard of Stripe. A few nods, right? So I had to work out how I was going to get that working my Ember app. Ember data is still in beta so that's been a bit of a challenge. So I'm going to show you the demo and then I'll come back to how I solve some of those things. Let's see if this works. I should probably say it's not my laptop. Before something comes up. So I'm typing in this swing school. This is on my demo website so swing school is the tenant name. So let's keep our fingers crossed. Should we just wake it up for me? This is where it all starts to fall apart. So what it's actually doing here is it's checking swing school is a valid tenant name before it fires up the app. So this is the app. So as I say it's not toasty finished. The workflow is all there but I've got some cosmetic stuff to do. So at the moment as I say I want at some point there to be this really comprehensive calendar that people can search and view stuff. At the moment it's just basically just listing the dance events that are in the dance. I can't see where the mouse has gone. There it is, cool. So for instance if I click on this. So it's showing the dance event. So at the moment this is what I mean about it mainly being read at the moment. So it's downloaded the list of upcoming events and just allowing people to search it. One thing that's been a bit of a challenge for me kind of getting my head round is my models I have tons of relationships. So actually a dance event is actually this page is made up of about I think it's about seven or eight different models just in total. So I've really had to get my head round promises because a lot of those are I'm side loading some. So the Jason package that's coming back from the server has some of those relationships side loaded but others aren't. And some I've kind of been playing around with pre loading some meta models. So just getting them all off the server in one go. But what that means is a lot of my relationships you've got some of promises and some aren't promises. So I've kind of had to get my head round that quite a lot. So but it's really good once you get your head round it's made me actually clean up a whole load of stuff because I've realised that actually I can do things a lot more efficiently. So that's been really good. So just to kind of demo a bit more of the of the workflow. So I'm going to click register now registers something only a user can do. So as I'm not signed in it's taken me a bit of use the before model hook to redirect through to the sign in page. So I'll just use. All right. So that's obviously authenticating with a server and coming back. So I'm now signed in. So I've got it up there. The signings all handled by the application model. I've built an application model that deals with all those kind of things. And so that's why it's now this is kind of part of the application template up here. So this is where it does. This is what kind of guessing most of you have seen ember apps, but this is kind of a right section of it, the registration so you can choose different settings for these questions. And embers decided which questions to display to the user based on what the nature of the event is. Apologies if some of you this is probably going to be far too simple, but if you're new to it then. So I click next. So it's checked with the servers to whether or not tickets available because there's with the dance. The whole reason I'm building the system is with some dance events. There's situations where you may allow someone to register but not sell them a ticket straight away. Effectively they join like a queue of people and they're waiting for a ticket. So in this one it's checked and the server said yes you can sell the ticket straight away and it's given a counter. So if you use things like Eventbrite for buying tickets they do the same sort of thing. They give you a time limit to purchase and the reason is because you don't know who else is out there trying to buy tickets at the same time. She needs to effectively issue a ticket but for a limited amount of time and the person has to complete that booking at that time. This is where I've got all these timers. So you've got this one's the 30 minutes, the defaults given 30 minutes. So I can now proceed through and so this is actually the ticket that the servers issued. It's saying that I've still got to pay for it. But it's in my, you'll notice up here I've now got a shopping basket which has got a countdown which has kind of been quite easy to do. It's really easy with Ember because you just get it observing the models. So that's been quite easy to do. Just from a design point of view getting all these timers one thing I've been really keen to do is actually allow a lot of dancers probably want to buy tickets for multiple events at once. So if you go on to Eventbrite you can only buy multiple tickets but they all have to be for one event. You can't buy for multiple events. So for me I want, it kind of works better if you allow them to carry on shopping a little bit. But you need to make sure the users are aware of how much time they've got left. So you've got these countdowns. So I could in theory, I don't know whether anyone wants to see me buy another ticket. But say I've gone off and bought another ticket. So this is where Stripe comes in. So let's hope this works. Cool. So I'm going to demo the integration with Stripe. So just handling the workflow for how this is going to work. So this pop-up here is a Stripe pop-up. It's called the Stripe checkout. What it does is it communicates the credit card details with Stripe, not with my server, and passes back a secure token to me that I can then pass to my server to charge the credit card. So I've got test numbers, so I don't have to plug in my own credit card number. So if I put in a test number that will decline to... So Stripe has passed it back to Ember that's then passed it off to my server. So you see that my server tries to charge the card and it comes back as declined. So that's all being managed through the controller. So I'm changing properties on the controller to change the workflow on the screen. And then if they try again... It's time if I try with a card that succeeds. I know this number off my heart. It's always better when you're testing to actually purchase a ticket. So let's put 14. So let's keep our fingers crossed and hopefully this all... Someone will go through. Yeah, so that ticket is now purchased. So that's kind of a really quick rundown. I've also done some forms as well. For instance, you can register as a new user through the sign-in process. So that's kind of the other part of it. I don't know whether anyone wants... Is that kind of a good enough quick run-through of everything? Yeah, cool. All right, so if I go back to this... So as I say, if some of you've got more experience than me, you might know how to solve these problems straight away. But this took me a little while and I had a really nasty solution for it. I just randomly tripped over someone's comment on Discuss. The end before and it was like a light bulb moment. So I can do this a lot simpler. So this is how I solved the wildcard subdomain thing. So you basically defer application load until subdomain has been validated. So what I was trying to do before was load up the application but get it not to do loads of stuff until the tenant had resolved. And then basically show an error page if invalid or start up the app if it is valid. So it's actually really easy. It was this someone mentioned this method called defer readiness and advanced readiness. I don't know whether people know about those, but that was made really simple. So what you do is you fire up the application but you immediately tell it to defer readiness. So then I have a... Whatever you're going to do, I'm using jQuery, a getJson to a particular URL that validates the subdomain and then if it's successful you just tell it, say, app advanced readiness and off it goes. And obviously I just then have an error page that's basically just displayed using standard jQuery if there's an error coming back. So that's how I dealt with that one. If anyone... Basically if anyone's got a better idea of how to do these things and do let me know but that's the one that I came up with. The countdowns. So when I initially tried to solve this, I had lots of countdowns going everywhere. So there's some pages where, for instance, shopping basket, if I bought three different tickets, they'll all have three different countdowns plus there's the basket going on on the top so that's four countdowns already. Plus there's actually other things in the background checking whether or not something has expired because it wants to do something when it's expired. So I kind of had lots of countdowns all over the place which obviously it's a bit inefficient so it's best if you can avoid it. So I managed just through, because I was doing lots of research on Google, I managed to hit on a... I think it was a pull request for adding a new cookbook. So this solution is actually based on that. I can't take credit for it. But I was trying to find the link the other day and I couldn't find it at all. It seems to have disappeared. But if I find it, I'll try and post it. Basically, it uses the idea of a clock service injected into controllers and I inject them into components as well. So you basically just observe the service. There's only one timer going on, basically. And I use, each time you saw one of those little countdowns, it's actually a countdown widget component that I've built that says a single component that's reused. So this is just the quick kind of how it works. So you have an app.clockservice, which is an Ember object. It's got this tick function that goes on in it so that when it initializes, it starts running. And the more efficient... So you can use setTimeout, the JavaScript one, but it's better to use the Ember... I've been told it's better to use the Ember run later, which is the Ember run loop. So that tells the Ember run loop that in one second I want you to rerun this, which will add a second on to the clock service. And then there's just this property called pulse, which is the main one that I observe. So what I do is, in Ember application, I do an initializer which injects it. So it's injected this thing called clock service into controller and component because they're the two places I use it. You could inject it into other things that you're using elsewhere. And what that means is... I don't use this observer one. I mainly use it around properties, but I have computed properties that observe clock.pulse, which means that they update every time the clock pulses, which is once a second in my build. It could be anything you want in yours. So that's basically how that works. I can't take credit for it. I kind of copied it off somewhere, but I think it's going to be... Hopefully it'll go into the cookbook because I tried doing tons of research to find out, took me a long time to find the solution. So I'm really hoping they do actually add that to the cookbooks. Cool. Any questions I should say? No? Cool. Yeah, I'm finished. Oh, okay. I want to say about the... It's not the main thing. It's been really since you initialized it because then it's part of the application's configuration rather than manually creating it and then deferring it and initializing it. So that you create the application that runs the initializer, the first readiness does the request for me. Oh, I see. So that pulls the code into the application code or something? Well, how do you... The moment you say like, application will create the first readiness and then do your thing manually and then you can... By creating initializer you basically say, this is part of how the application initializes itself. Right, okay. Cool. So it'd be the same code, but just pulled into that kind of initializer. Cool. Yeah. On that topic, there is also a lot of async routing code that Alex McNeill has been using. Yes. So I think that might be useful for that kind of stuff as well since 1.0. Yeah, I did... So that's how I was used... That's how I solved it initially. So I was doing... It was on... I was returning a promise from the application model route. But what I don't... What I kind of wanted was there to be no application template or anything. I just wanted... Basically, if the tenant is invalid, I just wanted effectively like a 404 page. They know that's just completely wrong. I didn't even want the application to do anything. So that's why I kind of moved it into that. But yeah, that's definitely the other way to go about doing it. You can do it through the promises. You just want to show a 404 page. What is that you do on the server? Because doing this on the client side is now... You've now got a slower loading for everyone who's typed a writing of the directory URL. Yeah. As you could just render a 404 page on the server number into the ember app and if you find it difficult to put them on the jersey of people. Yep, you could do that. Yep. Yeah, I mean I'm not saying that I've got like the right solutions. Just kind of saying that this is where I'm at with it. Yeah, I mean the biggest thing from my... So I'm self-taught. So it's a little bit of kind of like building on like as I go along. So I try and do as much research as possible and things like that. And yeah, my server knowledge is kind of not totally there and there's a limited amount of what I can do on my server at the moment with the package that I've got. So I need to move to a better package basically in the future which will help me with that. So yeah, cool. Don't know if anyone's using ember data using the current beta. Anyone using beta 3? A few people. Yeah, it's a lot better than... There were quite a lot of changes when it went into beta. I used... Beta 1 caused me a huge amount of headaches so loads of problems like belongs to relationships weren't even working and stuff. So luckily this version is pretty good. With what I'm using it for I'm not having many problems at all. So just in terms of... It was going through a lot of development in September and October although that seems to have slowed down for November. I don't know whether anyone knows why that is or anything. But it's good that it's heading in the right direction, I think. I'm still getting some issues. For instance, what I want to do is when a user signs out I want to keep all the public models in the store but dump all the user store ones and I'm finding that really difficult. Unload all seems to be the method that's there to do that but it is very inconsistent and it causes errors if a model is in a loading or a dirty state. So that's just one example of there are still issues out there. The thing that I'm excited about the next version of Ember or maybe 1.3 is the loading and error states that Alex is doing. They look really good. So I should be able to do better loading pages because I've got a lot of promises being returned from the model hooks and particularly error states as well. So if my server comes back with an error I can handle those a lot better. I'd like to start using AppKit or an equivalent build tool or something like that but I haven't wrapped my head around that yet. Testing is a complete... How to test the number apps is a complete mystery to me at the moment because that's something I'm going to learn at some point. That's it. I'll take questions if you've got any. Did you use one of the many Bootstrap integrations for Ember or did you just use the CSS? No, so I'm sticking with just the CSS at the moment so I've looked at some of the Bootstrap integrations. There's bits of them that I don't like or I haven't quite got my head round as to why I'd want to do it like that. I was actually quite interested by the Adapar Bootstrap widgets that came out recently. They were in the latest Ember weekly newsletter. It was linked to them and they looked really, really good. I'm planning on... Some of the interface will work better with a few models popping up, for instance, but I'm doing that as a later thing rather than at the moment. I don't know whether you've got one that you'd recommend. Well, I guess the Adapar one sounds good because they've got a lot of good stuff, but there was one called Bootstrap for Ember, which was really good for all components. Mostly you can do just the CSS, but there's the JavaScript stuff and there's some things that are quite hard like bottom links, like the active class being on the roll element and stuff that's kind of... Yeah, I've solved that by just... I don't think it's the right solution at the moment. I've reopened link to and get it to add... If it's adding an active class to add it also to the containing li element, so I've kind of fixed that manually at the moment. I did find with the bootstrap that... This might be entirely unfair, so please correct me if you think this is unfair, but I just wanted the speed at which they were correcting some of the obvious mistakes because there was two stuff, there was problems with the little dialogues. Someone was just documentation, they were asking, in some cases, they were specifying they wanted an Ember object, they actually wanted a JavaScript object, or vice versa, but in other cases it was just pretty obvious the effects which worked. I didn't... I haven't experienced any of that interaction with them, but it is the only one I've seen... I obviously haven't seen the Adapar one, but that was the only one that was bootstrap 3 when I looked. It seems to me that my impression was that it was very well done, what hasn't done it, so I expected it a little more, and maybe that's why it makes my tasteful appear. I think it's also a time thing for me, I'm trying to stick as much CSS as possible and I can go and improve things like that a little bit later. You mentioned you're using Ember data meter 3. Have you got as many as you have belongs to relationships? Yeah, they're working. I'm having no problems with those. The thing was, in my first week of working on it, I was using beta 1 and the belongs to wasn't working, and I thought it was me, basically, because I didn't know any better, and that was the 5 days of bashing my head against the wall. I'm on beta 3 as well. I'm using a sync as many relationships, and if I'm adding something to that as many, it's not updating the belongs to. That's a known bug. As I say, I think where I'm lucky with is this application. It's, as I said, mainly read and not write, so actually I don't think I'm editing any how many relationships on it. I'm editing belongs to, but I don't think I'm editing any how many. Also, you've got a public-facing app on the website. So how are you doing with SEO and server-produced rendered web pages? Yeah, that's not something I've looked at yet. It's one of those things, because I've read quite a lot, particularly the articles that appeared in Ember Watch and those kind of things. It's interesting. That website's not going to be indexed by Google, for instance, repetitively anyway. I've got the advantage that every dance school will provide a link to my website so that people can go and book tickets. So it's a bit less of an issue. It's not like a public website that I need indexed. There's rumors going around that Google are trying to solve the problem anyway, because they want to be able to index these things. So it's kind of whether you see it as a Google problem or a new problem. I haven't looked at it. I think it needs a little bit more stability before I burn a lot of time trying to solve it. So you were like, hash URLs, and that would be the same rather than, like, wish that URL was there, and server rendered and pulled back to the cloud side. Yeah, I think there's a number of different, people have written different solutions and things like that out there. So Comunical is starting to get, to get client-side apps into Google is basically not to do full-featured servers like rendering, but just take the data and dump it out without any formatting whatsoever. Just dump it out into your application page and then Google can index that. Just picking on structure. There's a surface, I think, to be from both. But there is, if you want this to be solved and you're going to throw some money at it, there's a surface you can use that will automatically pull your page and render them for you with, like, console.js or something. That's the easiest way, but it's not free. Yeah. Because it looks like no code whatsoever. Yeah. Cool. Is that all right? Yes. Yeah, that's all right.