[Where can you learn from designers at Amazon and Quora, developers at SoundCloud and Heroku, and entrepreneurs like Patrick Ambron from BrandYourself? You can level up your design, dev and promotion skills at Level Up Con, taking place October 8th and 9th in downtown Saratoga Springs, New York. Only two hours by train from New York City, this is the perfect place to enjoy early fall and Oktoberfest, while you mingle with industry pioneer -- in a resort town in upstate New York. Get your tickets today at levelupcon.com. Space is extremely limited for this premium conference experience. Don’t delay. Check out levelupcon.com now!]
CHUCK:
Hey everybody, and welcome to Episode 8 of Adventures in Angular. This week on our crew, we have John Papa.
JOHN:
Hey, everybody from sunny Orlando.
CHUCK:
Lukas Reubbelke.
LUKAS:
Hey there, from flooded Phoenix.
CHUCK:
I'm Charles Max Wood from devchat.tv. And this week we have a special guest, Sean Griffin.
SEAN:
Hello from dreary Colorado.
CHUCK:
Dreary, huh?
SEAN:
Oh yes, clouds and slight rain. It's not the worst we get up here.
CHUCK:
That sounds like so much fun.
SEAN:
Oh yeah, it's very sunny state.
CHUCK:
We talked to you on JavaScript Jabber about doing WebGL with JavaScript, and you mentioned that there were some challenges specifically with doing WebGL and AngularJS, so I thought it might be interesting to talk about that on this show, and see what specifically you ran into.
SEAN:
Sure. There were challenges, there were benefits. I think one of the more interesting aspects of it
is it took Angular into a direction I haven’t seen it go very often, which is when you have to have a really high level of interactivity from the user. For example, we've got interaction where on the main canvass where we render everything, you can click and drag the mouse and that rotates the camera. And we just have tons and tons of these very lower level interactions.
And it was just very interesting seeing Angular’s built in directives; how little you actually can compose them, like easily if you are trying to combine different types of DOM events, but then also just being able to isolate each of these individual interactions into a directive by itself, and having it actually be testable was very unique experience. I come from a backbone and kind of jQuery spaghetti background, so it's been interesting seeing the more complex interactions just sort of get segmented nicely like that.
CHUCK:
So you created directives for things like pan left, pan right, zoom in, kind of stuff?
SEAN:
Exactly, like we got, mouse rotation, mouse zoom, mouse panning, and then in other places, we have keyboard shortcuts bound to do the same sorts of things, and just every single one of those gets very, very isolated.
CHUCK:
That’s really interesting. So, is it much different from writing a directive… another kind of directive?
SEAN:
I guess it's not so much different, it's more that, there's just a lot of state because you have to maintain like is the mouse button down? Should we be responding to mouse move? binding and unbinding event listeners. But then also just in Angular, it seems like you almost never have to manually be binding event listeners onto DOM elements, and that is definitely something you have to drop down to when you are doing these more complex interactions.
CHUCK:
Very interesting.
SEAN:
I've got this one file. It's a slim file, so no closing tags and it's about 50 lines long, and I point to this whenever I'm introducing new people to Angular. I'm like, “If you want to see the worst case scenario for directives, go look at this file because it's 50 lines long and literally every single line is its own directive.”
CHUCK:
So do you put multiple directives on your canvass element, so it tracks all of these different events?
SEAN:
Yeah. I mean, we basically had to just because that was the target that most of these event listeners needed to work on, which was unfortunate because one of the limitations that Angular has is that you cannot have more than one isolated scope on an element. So if you wanna have multiple directives and you wanna use isolated scopes for all of them, you basically SOL, we had to take different some strategies. I think the main one that we ended up using was having a directive controller one level up, and basically trying to isolate the interfaces that they interacted with as much as possible that way.
LUKAS:
Pro tip!
CHUCK:
[Chuckles]
LUKAS:
I don’t know about you guys, but I think the best practice is basically always use isolated scopes, just so you have the explicit argument list.
SEAN:
Agreed.
JOHN:
Can you expound on that a little bit? Because I agree with you, but I'm not sure I quite get such situation, because why would you not want to use an isolated scope?
SEAN:
That’s the thing, we wanted to use an isolated scope, but it all needed to be on this canvas tag. Because for example, mouse rotation and mouse zoom are both kind of separated out on their own directives, and then one of them takes a control that handles rotation of the world basically, and then the other one has control that moves the position of the camera closer and farther. But neither of those now can be given those controls explicitly, just because they both need to live on the canvas tag. And so if you try and give them both isolated scopes, Angular is going to yell at you saying, “You can’t have more than one isolated scope on the same element.”
CHUCK:
So what you are saying is you can’t have isolated scopes if you wanna handle these situations?
SEAN:
Right. And that was only because we couldn’t break it out into multiple elements. I mean, that’s normally in a normal application. I think how you respond to that is just have the outer element wrap the other element and compose them that way, and that just wasn’t an option here.
CHUCK:
So how do you work around it?
SEAN:
Basically, being very diligent not to access properties of the scope, because now these things can access basically any property being passed around. So we have the animation player directive, which is sort of the top level composes all of the different components piece of it. And what we ended up doing was we tried to anytime we would have wanted to use an isolated scope, we instead tried to create a segregated interface on the directive controller for this parent directive, and working with it that way which had pros and drawbacks, but I did find very hard to mock out for testing. I don’t know if you guys have ever worked with that source [unintelligible] before.
LUKAS:
Could you elaborate on the testing part? This is pretty fascinating. We're getting into kind of the vows of the Angular. I mean, how did you test that such… with extensive amount of composition and sharing that shared state across the directives.
JOHN:
Yeah, and just to jump in there too, so you are talking about creating directives that don’t use isolated scopes that are effectively, coupled to the canvas then, right?
SEAN:
Yeah. And what we ended up doing to test them, was basically in the test file, creating a basically overriding the directives definition with something that have a much higher priority in terminals that that are true, so that way we could create a fake controller to use there, and then having the template that we used for testing just wrap them that way. And that kind of worked sometimes, kind of didn’t work other times. And there were few times that we just had to basically test the child directive through the parent directive, which I like to avoid, but just in a few cases wasn’t really possible, not for any specific reason other than just obscure things that I seem to not be able to mock out.
JOHN:
I think this is a really interesting point because directives are cool and wonderful. And I've seen directives almost take a similar path to me as things like [unintelligible] back in the SQL days, back in the late 1990s. And by that, I mean is when people start realizing they could use these things, they started doing everything with them. And I've seen applications that were almost like series of directives. And well that may not be bad or good, depending on the situation; the problem I run into is you end up with what I call ‘seven layers of directive hell.’ And you’ve got all those directives that work great together, but then who do you test them? How do you break them apart? Which ones do you test individually? Which ones do you test as a group? And I’d love to hear more about your testing strategy on this.
SEAN:
The first thing was we were never going to be able to do outside in TDD on this, because I mean, how the heck do you write the top level feature spec for it? And it should render things correctly in three dimensions. So we pretty much early on decided like we're just not going to have features test for the section of application. So we're just going to make sure we unit test the crap out of everything in isolation as much as possible, and then in places that we could get the somewhat integrationy feeling, for example our binary file parsing, that’s a good example, that goes through tons of classes that get tested individually.
It is nice to be able to just throw in a binary file, and then here’s the meaningless input to humans, and here’s almost the equally meaningless that’s just so large output that we expect, but just being able to test for [unintelligible] that way. So it was really just all about trying to find places where we could break apart small, segmented interfaces and services, which I found to be much, much easier to test. And then in directives, just trying to keep as little logic there as possible, trying to keep the dependencies between them to a minimum, so have something a template somewhere composed directives, rather than the directives compose themselves, if that makes sense.
JOHN:
Yeah.
SEAN:
And then mocking out directives is something that seems to be painful in some cases, and impossible in others.
JOHN:
So when you say ‘mocking out directives,’ are you talking about actually creating like inside the test, like putting the HTML that mocks the directive itself?
SEAN:
Not even that. So a directive’s template has some other directive, and you don’t actually want to worry about the behavior of the directive that it's referencing, you just wanna test like ng-if that it's got wrapping around it.
JOHN:
Got ya. So I wanna divert the discussion for a second here, you mentioned it's rather interesting to me that I've been tinkering with recently. You mentioned Slim. It's a templating engine you are using, I'm assuming.
SEAN:
Yes, Slim and haml in some places.
JOHN:
So just curious, I know it's a WebGL kind of conversation, but if you take a moment to understand why you pick Slim, maybe explain to folks who don’t know exactly what it is.
SEAN:
I picked it over Haml because it allows you to have attributes on a new line, and Haml is very, very touchy about when you can have new lines. And I'm a Rails guy, so I just like Haml, I like Slim; things that will let me skip closing tags, basically. Significant white space makes a lot of sense for templating. There was no particular reason other than just I like it.
JOHN:
Right, because you could pick Jade or njs, any of that other wonderful languages out there, or templating things out there.
SEAN:
And you have to actually go in through the Rails asset pipeline just because it's backed by a Rails API, and we want to be able to fully integration test our storefront side of it, with it hitting the real database, so we'll also just trend it more towards a lot of tools in that pipeline.
JOHN:
Very cool. Thank you, but getting back to the Angular side of things, with all the stuff you're doing with WebGL, I assume you are building applications that are gaming and animation-oriented, is that correct?
SEAN:
Yeah, the particular application that we've worked on recently at ThoughtBot was called Martial Codex, which is 3D Martial Arts Lessons from motion capture data that play in the browser.
JOHN:
Cool. Give me examples of some of those… what those tests would look like. What would they be like? It should like destroy your enemy? Is that the name of the test?
CHUCK:
[Chuckles] I love it.
SEAN:
Nothing quite that interesting.
JOHN:
Oh come on, tell us the real story. [Chuckles]
SEAN:
I'm trying to find some of the more down and dirty test, so I can see if I did have any particularly terrible descriptions. I mean, most of them are just like it updates… a lot of them just basically described the API they call, just because it's so stateful and so order dependent.
LUKAS:
So I have a question, if you don’t mind me jumping in, you mentioned APIs, and how you feel like directives should be isolated because it does provide an API, and I completely agree with that, is I think it's a nice way to encapsulate it, and that isolated scope does provide the API. Could you just elaborate on that just a little bit more? Your thoughts on that?
SEAN:
If you compare Angular to something like Backbone, right? In Backbone, you knew off the view, and you say, “Here's your element,” and you tell it to go render itself. And in Angular, we reverse it; we've got, the directives are element’s way of saying, “Hi, I'm a DOM element and this is my view.” And in a lot of ways, you can look at them almost just like functions that you embed inside of your HTML markup. And it's essentially an isolated versus non isolated scope to me, is like depending on global variables or things that happen to be there due to lexical scope, versus having a first class named function with an actual explicit argument list, which is not normally the decision that we make; we always lean towards not relying on global data. So it's sort of the same way for me with directives.
LUKAS:
Very cool. Totally makes sense. Hey, everybody Aaron, our favorite, yet weird panelist is here. Say hi, Aaron.
AARON:
How's it going, everyone.
LUKAS:
Hey, we missed you.
AARON:
Sorry for being late.
CHUCK:
That’s okay. We'll give notice next week.
AARON:
No, my bad. I was at the gym. Sorry, dude.
LUKAS:
Do you even lift, bro?
JOHN:
[unintelligible]
AARON:
You know, it's really unimpressive. The only thing impressive about me at the gym is the amount of sweat that I sweat.
CHUCK:
[Chuckles]
JOHN:
That’s awesome. On that note… [chuckles]
CHUCK:
Were you doing any martial arts?
AARON:
No, I do. That’s mainly what I do is with my Nunchucks.
CHUCK:
There you go. Do you have any Nunchucks animations, Sean?
SEAN:
Do I have any Nunchucks in the animations? No. We do have cool knives though.
CHUCK:
Oh, okay. Good deal.
SEAN:
You definitely learn a lot about all of the various tools of martial arts when you have to watch the same freakin 2 second animation for three months straight, trying to get it to render correctly.
JOHN:
So you can become a martial arts expert by watching this?
SEAN:
I've definitely not become martial arts expert, but I can probably reproduce like the two technical test animations that I was working with up until like right before we launched.
CHUCK:
Yeah, but he knows it when he sees it.
JOHN:
Oh, the Angular [unintelligible] strong with this one.
CHUCK:
[Chuckles] So, were there any other just weird things that you had to figure out between Angular and WebGL, and maybe game loop or anything else you have in there?
SEAN:
Yeah, I mean render loop is interesting in that it basically, so you are going to have the digest happen absolutely every frame because we've got things that… so a lot of our code is more focused less towards like video games, if you are thinking about 3D rendering and more like it's windows media player but for 3D animations. So we've got things like a seek bar, that were going to update as the animation progresses. So we have to be very, very careful about how many watch statements we setup. It's very easy for us to also accidentally start setting up like infinite digest cycles, because we have so many things that change so frequently, and don’t get referential equality in Angular, can be a little bit waky about that.
AARON:
That’s a few too many, infinite. That’s a few more than you want.
SEAN:
Yes. But it was interesting that our render loop did end up being mostly empty, other than we do say, “Hey, go draw to the canvas. Here's how many milliseconds have passed.” But all of the other update the world type things that you would normally have in a render loop, we just don’t have because Angular’s digest cycle just sort of handles that for us, and I thought that was really cool.
JOHN:
So for somebody trying to get into some of these Angular developer and they want to know much about WebGL and wanna get into doing all these, where do would you point them?
SEAN:
Basically, OpenGL tutorials, which tend to be more thorough than WebGL. Unfortunately, there's a big lack of resources out there, which is something I'm trying to fix at the moment. I'll put some links in the show notes though to a couple of sites that have had good articles that I worked with.
JOHN:
Do you use ThreeJS?
SEAN:
We were on ThreeJS for a while, and then we ended up having to move off of it due to some issues with it. We basically tried every library out there, and had issues with all of them. So the final engine ended up being the fourth iteration, which is just Node dependencies.
JOHN:
So you went from three to four?
SEAN:
We did go from three to four, exactly.
JOHN:
[Chuckles]
AARON:
Have you guys talked about mScript at all? And like writing OpenGL and compiling that into a browser [unintelligible]?
SEAN:
We have not.
AARON:
Did you guys try that at all?
SEAN:
We didn’t. I've heard of it, but it looks super, super familiar with it.
AARON:
So a guy I work with, who is probably one of the smartest guy I know, and in top of that, one of the nicest, genuine people I've ever met. We were working on something kind of like what you were saying, and I think he started with maybe Three, but then he wrote it just to OpenGL and C++, and then he uses inscripting to compile it for the web, but then he can also compile to run on native iOS and Android. So some of our engine for visualizations civilizations will be the same engine running on iOS, Android, and in the web written on all like a native code, that’s super performant because it compiles with like [unintelligible] with WebGL type language.
SEAN:
That’s pretty cool. I'm actually working right now on the Android version of this, and one thing that we did find that was great when we switched it just with raw WebGL is that even if we can’t directly like reuse the exact same code, the API wrappers that WebGL provides around OpenGL are so thin, that most of that code is trivially portable anyway, it's just changing some gl.glcaml case etcetera.
AARON:
That's awesome.
SEAN:
One thing that when we started on this project, they hadn’t added support yet, but there are some lower level wrappers around WebGL that been added to Elm, and I really wish that had been around when we started on this, because I thought that would be a really cool experiment is to try building something like this on top of Elm, which is just…
Have any of you guys ever used it before? It's a language that borrows a lot of its syntax from Haskell, and it's basically a language for FRP with graphics and data processing in JavaScript. And up until recently, it's mostly been limited to 2D stuff, but it's really cool for doing time varying values, and values that vary based on user input, in a very functional way.
CHUCK:
Awesome. Sounds like there are some really interesting options out there for that. Have you open sourced any of the stuff that you did in order to get those directives together?
SEAN:
We have not, but that is one of the things that we are planning on open sourcing. It just takes time to extract all of the stuff into an actual reusable library.
CHUCK:
And if people wanna learn more about it, how do they find you?
SEAN:
You can find me on Twitter at @sgrif.
CHUCK:
Awesome. Well, let’s go ahead and do some picks. Aaron, you wanna start us with picks?
AARON:
I'm going to pick if AntarcticJS. If you go to Antarcticjs.com, it might be a JavaScript conference in Antarctica, I don’t know, besides their docs are coming soon, so we'll see. Anyway, watch it. Love it. I've read a book called Lock In. I think one of you guys told me to read it. And it was okay, so I wanted to pick that, if you are looking for something [unintelligible] books, Lock In was pretty solid.
Moto 360 is my next pick. It just got here. I'm fighting to stay at work and not go home and get it, because I wanna play with it. It looks really cool. I also wanted to pick after yesterday, I wanted to pick this new Twitter handle. It's one of my favorite ones, it’s @KeynoteScarf, and if you don’t already know what I'm talking about, nevermind.
My last pick is an announcement for ng-conf.
CHUCK:
Yay!
AARON:
So, ng-conf is going to be March…
LUKAS:
Tickets go on sale right now!
AARON:
It's going to be March 5th and 6th. We are going to be at the same venue. It's going to be bigger, better than last time, which is why we picked the same venue, so we can get [unintelligible] and even better conference. Everyone’s favorite speakers should return, and we'll have a bunch of other ones. So yeah, it's going to be a lot of fun. Call for papers will be up very soon, if it's not already out.
JOHN:
Will it be pretty much the same format as last time, which I thought was pretty cool. I think it was like 20 to 25 minute sessions?
AARON:
Yeah. So we will have rapid format. We're going to have more after hour stuff, better party, cooler swag, more sponsor involvement, which is actually really cool thing, the sponsors made the last one fun [unintelligible] opening the bar, just kind of trying to make the event fun for everyone. So the sponsor will get more involvement in some of the events, and it will be really memorable for everybody. It will be a really fun conference. So get ng-conf. Get ready. Get excited. Tickets will be on sale beginning of November.
CHUCK:
Very cool.
AARON:
If you wanna stay tuned for updates, go to ng-conf.org, and sign up for announcements there.
CHUCK:
John, what are your picks?
JOHN:
Oh man, I'm so anti-climactic. That was such an awesome pick that I don’t wanna pick anything. But I can’t wait for ng-conf. it's going to rock. So I do have a couple of things I wanna pick out here.
One of them was specifically a book that I've read actually a long time ago, and I've reread it recently. And it's just one of my favorite Sci-Fi books. And I love Sci-Fi’s because we live in the computer world and I wanna like escape to a world of that's not real.
So for me, I read science fiction like Tolkien and what not, and this book by Terry Brooks is called The Elfstones of Shannara (The Sword of Shannara Book 2). It's actually a second book he wrote in the series, and it's one of my favorites. And earlier this year, there was an announcement that this actually going to become a show on MTV, which is an odd channel to put it on, but I'm pretty excited about that. And that’s Terry Brooks the author is actually behind all things, so it's supposed to stay true to what the book was, so I'm pretty excited about it.
CHUCK:
Very cool. That’s one of my favorite fantasy series, so I'm excited.
JOHN:
Yeah, it's a pretty phenomenal long series too. And they actually tie a couple of their series together. This one and then the [unintelligible] kind of all got pulled together, which is kind of interesting. He's actually announced in the show that he’s only going to write a couple more books, then he's done.
LUKAS:
Let me jump in here real quick, sorry. It's funny you bring that up because audible.com is having a huge $5 sale, and one of the Shannara series is on there, so if you are looking to get into it. I just thought I’d throw that out there.
CHUCK:
Which book? Do you know?
LUKAS:
I think it's maybe the second one in the series, but still, its $5.
CHUCK:
Cool. Lukas, what are your picks?
LUKAS:
Two picks for me. I'm a big Jack Reacher fan. I think I've read all but two of his books. He came out with a new one. Personal, I read it like the first day it came out, lot of fun. I just like Jack Reacher’s style.
And the second one is actually a really good blog post that I read by a friend of mine, Jurgen Van de Moere. And it's “The nitty-gritty of compile and link functions inside AngularJS directives.” And he just did a really good job with that, and I really like to write and do blog posts and I think he did such a good job. It just really raised the bar for me about the kind of writing that I want to do.
CHUCK:
I've got a couple of books that I'm going to pick here. The first one is called Hounded. It's the first book in The Iron Druid Chronicles.
AARON:
Oh my gosh, such a good book.
CHUCK:
Yeah, Aaron picked it on JavaScript Jabber quite a while back, and it was on sale on Audible, so I picked it up, then I'll listen to it in like a day.
AARON:
You loved it.
CHUCK:
Yeah. It was really good.
AARON:
Interesting news. In the Iron Druid Chronicles, he has these minibooks, he call “novellas,” that go in between the actual novels, and he just released another mini novella like yesterday. It goes in between the fourth and fifth book, I think. So make sure to get the novellas along the way.
CHUCK:
Okay, cool. Good to know. Anyway, the other one that I'm going to pick is called Finding Ultra: Rejecting Middle Age, Becoming One of the World’s Fittest Men, and Discovering Myself by Rich Roll. And it was recommended to me by some of the guys on the Freelancers Show. I've been into running off and on for the last little while, and this is kind of sort of an autobiography, but it's a guy who realized he had just 40, and he kind of had a health scare moment, and realized that if he didn’t change, that he wasn’t going to be around for the things that he wanted to be around for.
The thing he wanted is that I'm finding that I have one thing in common with him, and that is that I've kind of have to go a little bit extreme in order to really get myself to do what I'm supposed to do. In other words, I'm really bad at balance, so the way that he talks about the way he thinks about things, it just really resonates with me. Anyway, it's a story of how he went from totally unhealthy to participating in ultra-iron man competitions, which are like double iron mans. Anyway, really interesting. And I'm reading it first for inspiration and get some ideas, and stuff. He is vegan. I'm not sold on the idea of vegan, but just the overall of his approach to life and how he overcame some of the stuff he overcame is really good. And I'm about halfway through that book, just to put that out there. So those are my picks.
One other thing I just wanna bring up quickly, I've been thinking a lot about the podcasts and why I do them and what I wanna get out of them and things like that. And I realized that really, what I'm looking for is finding ways to empower people to find more freedom in their lives. Now, I'm not talking necessarily about going freelance, but I'm talking about solving that one big thing or helping people deal with or cope with something that’s hard that they are dealing with, so that they can find more fulfilment and freedom in what they do. I don’t have this up yet, but it will be up by the time this show goes out. If you could go to empoweringprogrammers.com, I'm going to put up just a little survey there that you can take. I would love to get your input on how we can better empower you, help you find the fulfillment and freedom in whatever else you are looking for out of your career and your life. So go over there and fill that out. I would really appreciate it.
Sean, what are your picks?
SEAN:
So I'm going to start off with a pick that I know is going to be very highly controversial and contested here, but I'm going to pick MDN. If you remember the days back when like we had no real place to go for API references, other than I guess maybe W3 Schools, it just makes such a huge difference and it's really easy to take…
AARON:
You are talking about Microsoft Developer Network?
SEAN:
Yes… No, the Mozilla Developer Network.
CHUCK:
[Chuckles]
SEAN:
So that’s my first one. My second pick is I've been playing a lot with the game called Hearthstone, which is this free to play trading card game that Blizzard made. Anyone out there that’s playing it, let’s play the game. Hit me up on Twitter.
And then lastly, I just want to throw something out there, for anyone using Rails for their backend or happens to have a Rails app in addition to their Angular app, please, please, please, try the 4.2 beta, and run your test suite against it and open an issue if you happen to find any bugs. It's very helpful.
CHUCK:
Are you contributing to Rails?
SEAN:
Yeah, I'm on the Issues Team over there.
CHUCK:
Okay. All right, I don’t think there's anything else, so thanks for coming, Sean. It was really interesting, and hopefully, we can inspire some folks to do full stuff with WebGL and AngularJS.
SEAN:
Thank you for having me.
[This episode is sponsored by Mad Glory. You’ve been building software for a long time and sometimes it gets a little overwhelming; work piles up, hiring sucks, and it's hard to get projects out the door. Check out Mad Glory. They are a small shop with experience shipping big products. They're smart, dedicated, will augment your team, and work as hard as you do. Find them online at madglory.com or on Twitter at @madglory.]
[Hosting and bandwidth provided by The Blue Box Group. Check them out at bluebox.net]
[Bandwidth for this segment is provided by Cache Fly, the world’s fastest CDN. Deliver your content fast with Cache Fly. Visit cachefly.com to learn more.]
[Do you wanna have conversations with the Adventures in Angular crew and their guests? Do you wanna support the show? Now you can. Go to adventuresinangular.com/forum and sign up today!]