CHUCK:
Sorry it took me a minute. I had to reboot my machine. It was going dog slow.
JOE:
[Mimics dog bark]
CHUCK:
That’s right.
[Does your team need to master AngularJS? Oasis Digital offers Angular Boot Camp, a three-day, in-person workshop class for individuals or teams. Bring us to your site or send developers to ours -AngularBootCamp.com.]
[This episode is sponsored by Wijmo 5, a brand new generation of JavaScript Controls. A pretty amazing line of HTML5 and JavaScript products for enterprise application development, Wijmo 5 leverages ECMAScript 5 and each control ships with AngularJS directives. Check out the faster, lighter and more mobile Wijmo 5.]
CHUCK:
Hey, everybody and welcome to episode 31 of the Adventures in Angular Show. This week on our panel, we have Joe Eames.
JOE:
Hey, everybody!
CHUCK:
Lukas Reubbelke.
LUKAS:
Holla at ya boy.
CHUCK:
Ward Bell.
WARD:
Yo, yo, yo!
CHUCK:
I'm Charles Max Wood from DevChat.tv this week, we're going to be talking about directives but more in-depth. I think we're going to break somebody’s brain – probably mine.
JOE:
[Chuckles]
CHUCK:
So there were some questions that we were talking about the other day when we rescheduled this.
Do you guys remember exactly what they were? I know Lukas had one that he wanted to ask.
LUKAS:
Should we save that for the last or just get right down to business?
JOE:
Well, you have three, Lukas. We can just go through your three questions and that can be like probably the whole show.
LUKAS:
All right, I'm going to say…
JOE:
Let’s go through them in like, number first, then number three, and then finally, number two last.
LUKAS:
All right, so I'm going to play the Dunst on the show today. We had an interesting conversation yesterday where Ward was talking about redefining directives and I would like for Ward to just elaborate what he actually meant when he was talking about that.
JOE:
Will you also going to, while you're talking about that, talk about storage of directives as well, right?
WARD:
Well, the whole story kind of unfolds that way. Let’s position how did I get into this mess. And it was two things: one, I read an interesting post by our previous guest, Ben Nadel, in which he discovered that you know how you sometimes accidentally replay your control definition script twice and it's no harm, no foul? But you know, it's just stupid but the second time you run the thing that defines the controller, it just redefines it and you're on with your game. But if you do that with the directive, it turns out, we discovered, [chuckles] that instead of redefining it, you end up with two directive definitions. You said, “What?” and then you looked at it, you said, “Can this be real?” and yes, it is and it's intentional. So it turns out that for any given directive like “my foo” directive, if I define one twice, I actually have two occasions for it. As many times as I add that directive or define that directive, I get a new one and I can’t remove the old one through any public API. And you're saying to yourself, “Why would that be true? Why would they do that?” and as Ben goes on to explain…
JOE:
Not only that, but what does that mean? If I have two foo directives, how does that affect my application?
WARD:
Well, if I have to, it means that when it encounters the foo attribute and it's going to run that directive twice, back to back, ba-boom! Now you can say, “Why would that even be a good idea? Why would they do that?” Because in the case I gave you, it's unintentional; I accidentally played the script, loaded the script twice. Why would they have that feature? And so he dug into it and it turns out that a number of the directives are implemented -- the base directives -- are implemented twice; among them, ngInclude which I happen to look at. And it turns out that what that allows them to do is run… you probably aren’t terribly aware of it, but you know this thing called “priority” in a directive. You can set the priority of the directive which says when that directive’s code will run relative to other directives. So a higher priority runs first and then the next ones and so on.
And it turns out, if you wanted to have conceptually a single directive that lay down there like ngInclude and you wanted some activities to take place at the top and then some to take place at the bottom after other directives hit run, would you do it? There's no way to do that within a single directive definition. You don't get to time it like that. But if you put in two directive definitions at different priority -- one high priority, one low priority -- then you could essentially book end the process. So you can run a little ngInclude at the top, do all the other directives and then wrap things up with a little ng directive [at the top?] of ngInclude. So that was the motivation to allow to have more than one. Makes sense?
JOE:
That does makes sense. That’s really interesting and something I did not know about.
WARD:
No. I don't think anybody… I don't know if it's ever been said anywhere, but Ben stumbled into it and realized its value. But that also means that… so I'm sitting there saying, “But wait a minute, usually when I'm testing things and I want to sort of get some things out of the way, I wanna fake them out,” one of the popular ways to fake them out is to redefine them away, right? I mean, we do that if we don't want some service or we wanna have some fake service or something like that, we just redefine it. And now, in the injected pipeline, we have a service. I think we've all used it. But obviously, you can’t do that with the directive because if you’ve tried to define your second sort of fake directive, it would simply add to the list other than replace than the existing, so I said, “Oh, my god, how do you test this?” The next clue was… the next thing that kind of got at me was another problem, standing problem. Now, sometimes, did any of you ever define the directive with a controller?
LUKAS:
Sure, absolutely.
JOE:
Yes.
WARD:
Absolutely. So how do you test that controller? How do you get it to test it? You know, if we do that with a regular controller like a view, view model controller. It's pretty easy. We just like inject it and… I mean we inject $controller service and then we t up all the fake stuff that we want, all of the fake dependencies we want, and we say $controller service make me up an instance of my controller x and off we go and now we can test it. But how do you test your controller if it's defined inside a directive? You know, I'm sitting around thinking about how to do that and I wonder…
JOE:
You could define it as a separate function, right? So that it's not actually inline in the object for the directive but in a separate function, then in your test, you could create a fake controller around it and utilizes that same function and so that way, that will be a lot of BandAid-y… it feels really BandAid-y.
WARD:
It does, doesn’t it? And for somebody else’s directive that wasn’t yours and they wrote it in there, what would you do? So my usual statement is, “Hey, if somebody writes one like that, its private implementation and I don't test private implementation anyway,” and blah, blah, blah. I'll just spin up the directive and I'm really interested in its public effects. But the fact of the matter is that that’s a pretty significant piece of code that’s sitting in there, and it can be hard if you spin up the directives that holds the controller to sort of create all of the conditions that might exercise that controller fully.
And your goal in testing is to try and give it not only the garden variety cases, but the deviant cases that reveal potential problems or limitations in it. So I was like, “Oh, there's got to be a better way.”
So the final clue that got me down this way, this path, was another problem which is I don't know about you guys, but I see a lot of people who write component directives and inside that are other components directives in the templates and then inside those is they have templates that have other, so it's like directive inside a directive, inside a directive, inside a directive. If I'm trying to test one of the outer ones, all of my inner directives are going to be processed in all of the nested templates all the way down. And that just is going to make things really hard because it's going to fire off and do all kinds of stuff I'm not interested in. I want that stuff out of the way. I want them to be inert, right? Does this sound familiar to you, guys, as a problem?
JOE:
Oh, yeah.
WARD:
So like, how you disable all those things? I mean, it's a shame that you have to even know they are there: the x, the y, the z and all the thing that could be in there. But if you even knew they were there, how the heck would you disable them? We just learned that you can’t just add an inner directive because all that does is add a directive -- it doesn’t replace the directive. So this all got me thinking; we’ve got a series of problems that mostly show up in testing. What do you do? So I [?] and here’s what I learned: when you define a directive, what's actually happening under the hood is it is registering your directive definition with the $compile provider which the registry of all of these things by the name of it.
So when I add a foo directive, under the hood, it goes and that gets, during the config phase, it goes and gets the $compile provider and it goes and finds if there’s already… if there's no [directive to create?] registry and puts my definition in there. It's easy the second time to say, “Oh, I already got one of these.” So actually the way it's stored is as an array of directive definitions. So it goes and looks up foo, sees the array, sees that it has an array or foos and it adds my second directive to it. And it keeps on doing that, so I get a nice big array of directive definitions for foo . And that’s all sitting there in the $compile provider. Now you won’t actually use the $compile service when you're testing your directives later, right? You'll inject $compile and you even say, “Hey, I wanna [?] this thing up.” So you know, you're used to the $compile as a service but there's actually a $compile provider of course, as well. So that's where it sits. But what happens next?
Well, actually, at the very moment that you first put that foo in there and it looks in its registry and it says, “Do I have a foo? No, I don't.” Well not only it creates a registry entry which is an array and puts your definition in it, but it also adds to a factory method. And the factory, at the same time that it adds, the factory creates, its call will be… well, if the directive’s name is foo, it will be called “foo directive”. So if you were able to -- and you're not, but if you were able -- to inspect what's coming in the $provide that’s keeping track of all the things you defined, you would find that in there for every directive -- ngInclude, ng this, ng that and my foo -- would be a ngInclude directive service or factory and so forth for each of them. Well, we all know how to fake out a [?] services or factories during a test, right? We simply ask during our test we say, “Hey, inject this thing for me.” And so if I want, I can say, “Hey, would you give me the foo directive?” and it hands me back an instance in all of that factory.
It turns out that that instance is the array that was registered in the $compile provider. It's the array of directive definitions because that’s what a directive factory does. So, now, suddenly in my hands, I have the array of all those little definitions I had. So like you take ngInclude which I had two of them and I got an array of two definitions. And given those definitions, I now have in my hand something I can manipulate in the way I want to under test. So for example, if I wanted to test that controller that was in my foo directive, well, I have the definition right there and on that definition object is a controller property and that controller property contains the very definition that I had for constructing… it's constructing constructor for the controller that will be used by the directive, which means I now have in my hot little hand something that I can test independently. I can take it and I know what gets injected to it, so I can completely fake that out, create an instance of that controller and test it to my heart’s content.
JOE:
Can you go through again how… the exact code that you’d get in order to access this. Walk through the code one more time.
WARD:
I say “inject foo directive” and inside might be “inject callback”, it says, “Here, here’s your foo directive.” What is that thing? It's an array. Now, I only defined it once, so inside that array is a single object. I say, “Okay,” so I take this thing that was injected and then I say, “give me the zero width element,” and I have in my hands that very object that I defined is foo and it tells me all the stuff that is in an object that would… you know, that I would have passed in… you know, what I defined it. So my… if I have a controller, it has that; if it has the require property, it has that; if it has a scope property, it has that; it has the link function; it has the compile function; it has all that stuff sitting there as properties for that object just as you would see it. If you looked at the documentation, it's the object that would have constructed and it's ready for you to manipulate.
JOE:
Now when you say “inject”, are you talking about calling the module function which is an injectable function and…
WARD:
Right, “angular.mock.inject” the same one that under tests… I know we're not doing testing, but you know how when you do your test setup, you use the Angular mock’s inject thing that fires up the injector…
JOE:
Right.
WARD:
Because under task, the injector is available to you for that particular test run, so it's fresh each time, right? So I mean, that gets into how do you do testing. So I'm just going to assume that you know that… that folks out there at that’s part of the process and another time we can go through it. But not only that, but because I have the array, right? I ask for the foo directive and I have the array of directive definitions that Angular itself is going to use, I'm in complete position to manipulate that array. I can take everything out of it, I can put a new directive into it, I can take one of the directive definitions out, pull the link function out, wrap it in my own little wrappers so it sits by or whatever, put it back in. And now… I do all these during setup and now my tests downstream, if they use a directive, they use my foo directive, it's all been wired up with my observers or my fakes or whatever. See how that works? Is that cool or what?
JOE:
That’s way cool.
WARD:
And so this also lead to, I don't know, and this will bring me to the conclusion of this… it also explains to me why would I… I saw somebody who had one of those… they were trying to test a directive and it had templates which had directives in it, which itself had templates with directives and all the way down, and they didn’t want all those to fire. What they did during setup is they redefined all of the directive factory methods. You know, they just did factory, factory, factory and they redefined them, you know, let’s say the a, the c, the d. They just didn’t want those to work at all, right? So they redefined those directive functions… factory functions to return an empty array. That means when Angular comes along and starts evaluating those templates and it says, “Oh, I see an A directive, I better fire up its function and get so its array of directive definitions, that array is empty and it does nothing.” Suddenly, all the nested a, b, c, d’s are inert and that is how they faked out all of the nested ones so that they could concentrate on the behavior of the top level directive that they were trying to test.
LUKAS:
Boom! Pro tip!
WARD:
Now, I can write this up, don't you think? Someday, I'll put it out there. I don't know whether this was just like too crazy to be doing on the air, but that is the story.
LUKAS:
And that’s our show. Thank you, Ward. [Laughter]
WARD:
Next question? By the way, I can’t write a directive, but now I know how to kill one -- and that’s really all I wanted to do. [Laughter]
LUKAS:
Okay, so the next question from Dunst Reubbelke.
WARD:
[Chuckles]
LUKAS:
why would you ever use the compile function in a directive? I have yet to find a good reason to do that. Joe? Ward? What are your opinions on this? What’s the verdict?
JOE:
So this is an interesting conversation for sure. So I barely finished my directives course for plural sight and I did a bunch of work and when I was teaching the compile function, I want to get a really good use case -- a real world use case -- for it so I went around and I got some pretty advanced directives that some other friends had built and people that I knew had built, went through them and noticed that, “Hey, you don't need the compile function for this directive.” So going back a step, you know, we need a little bit of explanation here, obviously, you’ve got a link function and a compile function in a directive and most of the time, we know about both of these if we've done directives a fair amount, but we mostly use the link function. And the link function has parameters which are the element and the scope and that’s where we typically do our DOM manipulations is inside of that link function. Well, there's a fifth parameter on that function.
are:
scope, the element itself than the attributes, and then the next one is if you require any controllers from another directive is the fourth attribute or the fourth parameter to that link function and the fifth one was just added in 1.2 and that is the transclude function. And that was the whole reason for… the big reason why people are using the compile function previous to 1.2 was to have access to the transclude function when doing transclusion sort of in the manual mode, where you have the controlled how and when elements got appended into the DOM -- the transcluded elements. So now that the transclude functions was in the link… the transclude parameters is in the link function, I'm going through and looking at all these example directives and all of them can be rewritten to just use just the link function, not the compile function.
And there are some pretty crazy ones like one of them was a really interesting caching directive where you put the directive on and it didn’t actually append anything into the DOM until you activated it. It was basically kind of like an ng show. So when it has some Boolean condition, when that set to “true”, it will actually, at that point, go out, do all compiling of the directive of the template and append the template in. And then if you set it back to “false” it will hide it, but it wouldn’t pull it out of the DOM the way that ng if does. So that’s part of ng if is it actually pulls it back out of the DOM and when you put it back into the DOM, it has to recompile the template. Well, with this directive, it's a way to delay compiling the templates so as in performance optimization, but once it was in, then it's just in and then it just would display none to hide or show that DOM element. It's very interesting. And they were doing this in the compile function.
I looked through and said… rewrote it with just the link function. And I even started going through all the directives in the Angular source and the only one -- I haven’t looked through every one of them, but I looked through quite a few -- and the one that was using the compile function still was the ng repeat. And I was able to go through and successfully recreate 80% of the functionality of ng repeat that most people use. I didn’t recreate every piece of functionality like some of the “track by” options and things like that, but I was able to recreate the functionality of ng repeat again without using the compile function. And ng repeat itself, the full search goes really quite long; there’s hundreds of lines of code and it's really complex.
So why the use of the compile function? Could a performance optimization I'm not 100% positive why the compile function was used in the ng repeat directive in the Angular 1.3 source code, but I couldn’t determine why it was necessary. So I started telling people, “You really don't ever want to use the compile function until you reach some theoretical point where…” I'm doing something and I've discovered that the link function really doesn’t do this but by default, you should just be trying to do everything in the link function and my guess is that for 99.9% of all directives that will ever need to be built, the link function would be fine, and the compile function would be unnecessary. And I certainly don't know of a business use case where the compile function is necessary. Now, Ward was talking about a scenario where he believes that the compile function was necessary.
WARD:
Yeah, well at least I wanna throw it at you and then you can report back. I'll give you a challenge and this is totally made up crap because I was using it at one point and I looked at my code and I
thought it was gone. The problem was that I needed to manipulate the template before… and I'm talking about that the directives template, not the content -- the transcluded content -- it's content that will be poured into it from the page that uses the directive. I'm talking about the template that the directive itself has. And I needed to manipulate that for some reason and get it all squared away and then the link… that would be the template that the link function would ultimately use. And I don't think you can do that inside the link function itself.
case:
based on your culture and your authorization, I have ten possible templates that this directive could use and based on your culture and your authorization, I want to use one of those ten before it continues on its merry way. Now there's no way to put a switch statement… to pick among ten at the high level, so your mission, Joe, should you choose and accept it is to come up with a way to do that, like we want pink one for Lukas and a blue one for Charles, you know, something like that.
LUKAS:
I think it's the other way around.
WARD:
[Chuckles] You don't wanna be Mr. Pink? Remember that movie, Reservoir Dogs? Great movie.
CHUCK:
I'm pinky, he's the brain.
WARD:
[Chuckles]
LUKAS:
There we go.
WARD:
[Chuckles] Anyway, there's the challenge for you, Joe. I don't expect you…. Unless you can just solve it right here on the air, I’d love your report back. But I think that when you need to do template manipulation or template choice somewhere in the logic, I don't know how you would do that as late as the link function. But that’s so contrived, that I think it's kind of silly. Anyway, that's my challenge. I basically agree with you. And since looking forward, it looks like the whole compile idea disappears and I think we're best without it.
JOE:
Yeah, it does seems to be, again, such an advanced case. I think certainly the advice of “forget the compile function exists” is good advice because the vast majority of people that do Angular are just not going to encounter a situation where the compile function was necessary.
WARD:
Yeah, I think that’s what we should tell people, but just ignore it.
JOE:
Yeah, but your scenario is very intriguing. And so I'm just trying to look through and see if I can see any way to do that and… I'm going to play around with that and see if I can solve your problem and report back on a future episode.
WARD:
So, I had to do template manipulation before… I had template that the link could use, so I think that was my use case. Although it seems that it’s disappeared from my code and good riddance, I say.
So, Lukas, what other stomp the chomp do you have for us?
LUKAS:
I got one more question. And this is something that I've actually heard Joe say and then Ben said it in the previous episode (or the two previous episodes whenever he was here) is to really be careful about using isolated scope; that it's not kind of the end all be all; it's not a broad brush that you use to paint over your directives. And so I want to get your opinion on when you should really use isolated scope and what that is for.
JOE:
Go ahead, Ward.
WARD:
Well, I kind of will repeat what I read in Ben’s post (and we'll put the link in the show notes.) First of all, there's a potential problem if you just throw isolated scopes at everything, which is that if you use… there can only be one isolated scope on an individual HTML element and so if you wrote one for several attributes and each of them had an isolated scope, you couldn’t put those attribute directives on the same HTML element. And that’s kind of nasty, so that’s why you don't wanna do it unless you have to.
JOE:
Right. And that now applies to inherited now as well and either a later version of 1.3 or 1.4. You can’t have any more than one scope specification on one of your directives; if you have any more than one, you get an error.
WARD:
Yeah. By the way, if you have the multiple definitions that I was talking about earlier, which almost nobody will have, that would be a problem too if they both try to have [?].
JOE:
Right.
WARD:
And it turns out that it seems to be most valuable when you’re creating a component, something that would be an element tag. So the heuristic that I saw in one of the comments to Ben’s post that I think is just generally good advice is use an isolated scope when you're doing an element directive and don't use an isolated scope when you're doing an attribute directive. In other words, if you're redefining the input tag, yeah, but if you're just adding something -- modifying attribute to something like ng show or ng hide -- then no, don't do it.
JOE:
So I will echo that but also point out the fact the vast majority of directives that people are going to write are going to be component directives. We use the phrase “element directives.” So this is something that actually will exist in Angular 2.0 and that is that there are three types of things; what we called directives in Angular 1 have been split out into three different things. There's a new thing called component, okay? And this is what we think of as element directives, or at least a wellcrafted element directive, which is I have some piece of reasonable functionality and display, and I wanna be able to write in an element somewhere in the HTML and have it just inject in all that display and all that functionality in that spot.
So a great example of that would be like a user display, it will display the name of the user and their access rights and some other business specific information about that specific user. So wherever I want, let’s say it was user panel, I can write an element that’s “user-panel”, give it an attribute that points at the data it's supposed to display and then I just stick it in HTML and there it goes. That, by far, is the vast majority of directives that people will write in Angular 1.0 and correspondingly in Angular 2.0 that’s called a component and that’s the vast majority of things that people will write. Then there’s another type of directive which is called… the Angular team coining this phrase, it's called the “decorator directive” and that would be things like ng-click, ng-show, ng-hide where you're taking an existing element and adding some new piece of functionality to it, either to…
WARD:
A behavioral directive.
JOE:
Yes.
WARD:
Changing the behavior of the interaction or changing the behavior of the widget.
JOE:
Right. And this would not have… typically without having any display, it will be really odd for it to have some display. I suppose there’s a theoretical business case where would need some display, but this would not have a template; they would just… again, event handlers are great. For example, the HTML5 video element, there's not built in Angular directives for the different events that the HTML5 video element can raise, so you'd have to write your own directives if you want to be able to listen to them and take action on them. So those are decorator directives and those are very much less common for a typical Angular project to require. Because usually the built in ones do it well enough or the additional functionality is… already belongs to an existing component directive anyway, so you kind of piece the two together, right? You might write your own HTML5 video component directive and inside of that, you would also listen to the events and raise them but handle them within or listen to the events, but handle them within the directives. So there's no reason to create a new like ng-html5-pause directive, you would just do the pause listener inside of that… your custom HTML video directive. So most people don't write these decorator directives. They do and they are less common but most people just don't write them.
Then we have a third kind of directive which the Angular Team calls a “template directive”. And I dislike that name because it's like some other things that the Angular team has done that’s like… that’s a word that's overused. We use templates and you know, ngInclude, we use them in directives themselves, so “ template directive” to me seems odd. I call it a “structural directive” but nonetheless, whatever you call it, this is the type of directive that’s going to make some major DOM manipulation and change how the DOM works and looks. So a great example of that is the ng repeat, right? I've got one node and this directive is going to turn that same node into multiple nodes. Or ng if which actually pulls an entire branch of the DOM out of the DOM and takes it away when this condition is false and then sticks it back in when the condition is true. So it's not just a matter of a little bit of functionality, this is like we're making a major structural change to the DOM. And these ones are, by far, the least common. Almost nobody writes structural directives -- or template directives -- excuse me, I'll use the Angular Team’s terminology here. Almost nobody writes template directive because the use case for them is so rare and ng-repeat already does everything for us, so if it's that kind of a thing, usually ng-repeat handles it for us and we don't need to write our own.
WARD:
I guess animations would kind of fit in that category, right? Anything that does sort of direct DOM manipulation…
JOE:
Yeah, they could fit into that. That may be. It kind of depends. It's not a clear line, you know? It's really not a clear line. So in all of those cases… these are not separate things in Angular 2.0. In Angular 2.0, the component is the building block of what we do. And I haven’t even seen examples of the other two types of things and whether you can build them your own -- I assume you can. But in Angular 2.0, you can component is the base thing. No longer is the controller the base object you're going to work with, [now?] component is. So it's worth mentioning that, yes, in Angular 1.0, you want to avoid isolated scopes when you need them on component directives but the vast majority of directives that people will write are going to be component directives. And to that matter, in Angular 2.0, this component object will have an isolated scope on it but it comes with it by default. It has an isolated scope.
WARD:
That makes sense. And that’s kind of pushing people just to drive it home, and it's like if you're creating your own widgets which are sort of semantic, like my menu, you'd like to have an HTML tag called “my menu” and “my header” and “my footer”. And if you wanted your HTML to look like that, that would be the kind of component directive that you're describing and it would be an element tag.
JOE:
Right.
WARD:
Yeah, so that’s kind of where they are leaning in terms of their notion of design. Whereas when we do the standard things today and we tend to sort of ng-includes which are an attribute, which says “go get this view and then the view model” and then it wipes itself out. So that’s different. And they are trying to say, “No, that style, this isn’t the style of the future. The style of the future is to have semantic tags to create widgets that represent concepts in your application’s views.” Is that the way you read it?
JOE:
Yeah, definitely.
WARD:
And so yeah, they would need their own scope whereas the other things which are just sort of like “adjectives” if you will, in your structure are just… they don't need their own scope, they need to talk. They need to modify behavior.
JOE:
Right.
WARD:
That makes good sense.
JOE:
Yeah. So I think that Ben’s advice, “don't blindly isolate all those things” is good advice other than the fact that your default could be to choose an isolated scope because your default is going to be that element type directive, that component type directive, right?
WARD:
Well, he was underlining the word “blindly”. [Chuckles]
JOE:
Yes.
WARD:
So, yeah. I guess again it boils down to if you're creating a component, you're going to have them isolated. If you're not, you're probably not.
JOE:
Right.
LUKAS:
Pro tip!
JOE:
[Chuckles] Yeah, just to plug my own course here, all of this is covered, other than what Ward talked about with [?] of directives, all of this is covered in my directives course. So if you are bored and want to learn more and solidify this and see concrete examples, there's a bunch of concrete examples of all these things in my directives course.
LUKAS:
Whoa, whoa, whoa, you're underselling it!
JOE:
[Chuckles]
LUKAS:
Let me plug Joe’s course. If you want to learn and you want to learn from good content, go check out Joe’s course. He’s amazing. I heart him. He’s great. There.
JOE:
Thank you, Lukas and Ward. This has actually been a really fun episode for me because like I was just head down immersed in all of this sort of stuff writing this course, so it was really fun to talk about this stuff.
LUKAS:
Well, you are certainly expert, sir.
JOE:
Well, I'm just impressed with Ward and how you dug into that… like digging through it. That’s pretty funny.
WARD:
Well, my Angular is quite different. I couldn’t write a directive to save my life but I do wanna kill them under tests. Because I've been focusing on testing and I've been doing a Pluralsight course on testing techniques for Angular that kind of takes off where… you know, you sort of lay down the basics for people about how to do it, and so I get to assume the kinds of things that you taught them and then I take them on a trip of how to handle what happens in your application, so that’s where that came up.
JOE:
That’s awesome. And that’s knowledge that really needs to be out there. There is just not enough of that.
WARD:
Love fest!
LUKAS:
And hug.
JOE:
And hug.
CHUCK:
Awesome. Well, are we about at a place where we should get to picks?
JOE:
I think so. This has been a really cool episode. I really enjoyed this one.
LUKAS:
Way fun.
JOE:
I hope that the audience enjoyed this as much as I did or without too many people going, “Ugh! Quit talking about things that I don't care about!”
WARD:
Well, as they say, if the audience enjoyed it half as much as we did, then we enjoyed it twice as much as they did.
LUKAS:
[Laughs]
JOE:
Very true.
LUKAS:
I don't understand what you just said.
JOE:
[Chuckles]
CHUCK:
“Math is hard.”
JOE:
[Chuckles]
CHUCK:
All right, let’s do picks. Joe, do you have a pick and a tip for us?
JOE:
I'm going to pick a series of books by Glen Cook who used to be my favorite author until Brandon Sanderson… and Glen, on the off chance you hear this podcast, I'm really sorry. I still love you.
CHUCK:
[Chuckles]
JOE:
But he has a series of books called Instrumentalities of the Night Book which I absolutely love. And the latest book came out recently, a few months ago. It's like a four-book series now, I believe. Super enjoyable. I've vastly enjoyed it. I'm reading through it the third time to kind of… just because I like the series books so much. So that's going to be my pick is the Instrumentalities of the Night by Glen Cook. And for a tip, my tip is going to be watch Ward’s course when it comes out.
WARD:
Oh!
JOE:
Everybody needs to test. There's not enough testing in the world.
WARD:
Well, my goal would be to make it feel like not so daunting. I mean, most people just say, “Oh, it's going to be too hard,” and all that stuff or “it's going to be too brittle,” and so my goal is to try to say, “Hey, you know what, it doesn’t have to be that way. It could be fun.” At least it would be funny.
CHUCK:
All right. Ward, what are your picks?
WARD:
My pick is a video that I watched last night when I guess just a couple of days ago, there was a showed down at Google where they showed off what they're calling alpha in Angular 2.0 and they showed the Todo app and stuff like that. And I have to say, it was both exciting and confounding. And I felt like, like it's a little bit like this. They are calling it Angular 2.0 right? So it's a little bit like this, hey, Lukas, you played poker, right? You're used to playing poker. I've got poker version 2.0 and it is so much faster and cleaner and less complicated. Do you wanna play? And Lukas, you say?
LUKAS:
Yes!
WARD:
All right. See? It's just like one: we deal our five cards each, right? And you ask me, now that we've got our cards in our hand, go ahead and ask me if I have a particular card, like six of diamonds or something like that. Go ahead, ask me.
LUKAS:
Do you have a six of diamonds – or this is a trap?
WARD:
Go fish! [Laughter]
WARD:
Isn’t this Poker 2.0 great? I mean, it's faster, it's not as complex, we'll be able to run it on mobile.
It's great! And it's just like Poker 1.0 because you’ve got cards and suits and numbers. It's just the same. And I'm sitting there I'm saying, “Wow, man! You call it Angular and I get it, but it's just… it doesn’t feel like Angular 2.0. It feels like something else.” It feels like Go Fish to me. Anyway, it may be great. And Poker 2.0 may be better than Poker 1.0, but it's really interesting to see where that goes. So I'm looking forward to it. I'm looking forward to hearing more about it at ng-conf. But if you wanna get a sort of insight about where they are now and what it could be like, go check out that video.
CHUCK:
All right. Lukas, pick and a tip.
LUKAS:
So my pick is the book Hooked: How to Build Habit-Forming Products. I read that last week. It is chock-full of just excellent things you can do to build a product that is habit forming as well. Nir Eyal actually introduced what he calls the “hook framework” so you can actually summarize the book in kind of this very easy to digest framework for building products that people are going to get hooked and enjoy using. And then my tip is I’ve been really digging into the Ionic framework. I gave a presentation on it last week in San Francisco at a hackathon and if you want to be an Ionic expert and you know AngularJS, you're pretty much there. And so building a mobile hybrid apps and really easy. If you go to my blog onehungrymind.com, I kind of put out some pro tips as well as a quick screen cast to show just how easy that is because it's awesome and I'm lazy.
JOE:
Sweet!
CHUCK:
All right. For a pick and a tip, I've been pretty buried with JS Remote Conf this week. I did finish a book called American Sniper and it's the book that the movie is based on, if you’ve seen the movie. It's really interesting to kind of get an eye into the war in Iraq. Lots of political stuff around it, obviously, but he, more or less, just explains going in and doing his job. And he does have some opinions on some of the stuff that went down. Anyway, it was really interesting to kind of get an inside look at how things worked and how they went. I don't know that I had a tip this week, but yeah, I'm really excited to see that video that Ward talked about, so go check that out. And I don't think we have any announcements, so we'll go ahead and wrap up.
WARD:
Joe has an announcement.
CHUCK:
We have announcements. Joe, go for it.
JOE:
No ng-conf announcements this week. Of course, by the time this gets released we'll be darn too close to ng-conf anyway. But I do have an announcement that if you wanted to go to ng-conf and didn’t get to go to ng-conf, there is a solution for you and not just getting to watch it online because if you didn’t get the opportunity to go to ng-conf, you definitely want to watch it online and watch the whole Livestream. But we are announcing a new Angular conference that will be held in Vegas in March. So if you happen to like Angular…
LUKAS:
Check.
…and like Vegas,
LUKAS:
Meh.
[Laughter]
JOE:
…or awesome parties, then…
WARD:
And if you don't want Lukas anywhere near you…
JOE:
[Chuckles] Right.
CHUCK:
Ng-party.
JOE:
If you like resorts, let me say that because the venue it's being held at, feels like it's a spa resort not a casino hotel, because it's not a casino hotel. So it's really awesome. Spa resort with pools and a private beach and it's on the same lake that Celine Dion has her house on. Ng-vegas is going to be officially announced next Monday, just a couple of days before this comes out, and tickets will be on sale really fairly soon and it will be several days of watching the awesome people of the community. Jeff Cross from the Angular team will be there speaking, watching them and learning about Angular. So if you want more Angular goodness and more Angular conference goodness and didn’t get to go to ng-conf and still want to go to an Angular conference, here’s your solution. And Lukas will be there. One of our featured speaker, Lukas, will be there talking about something awesome.
LUKAS:
Literally, I'm creating a library called “something awesome”. It might be called ngSomethingAwesome.
WARD:
Trademark.
LUKAS:
.com, just copyrighted it.
JOE:
That’s it.
LUKAS:
That’s it.
CHUCK:
Did you say when the conference was?
Yes. It will be May 6th through 8th. And the website is ngvegas.org or com – either one will work.
CHUCK:
Yay! More ng-conferences.
JOE:
And let me be clear, this is not specifically an ng-conf conference, but it's loosely affiliated with.
CHUCK:
All right. Well, thanks for announcing that, Joe. Hopefully you can get it all filled up. If it's anything like ng-conf, it will probably fill up pretty fast, so.
JOE:
Yeah. We're expecting to have tickets readily sold out within seconds again, just because of the high demand. This is a little bit of insider information but 13,000 people tried to get tickets to ngconf over the two seconds that tickets were for sale.
CHUCK:
Holy cow!
WARD:
That’s insane!
JOE:
Yeah. And then of course it doesn’t count all the people that didn’t think they needed to be there right at noon. Didn’t realize they had to be there right at noon to buy tickets, so.
LUKAS:
Next time, sell 13,000 tickets. We'll all be millionaires and then we'll just work out the details later.
JOE:
[Laughs]
WARD:
Just run for it.
LUKAS:
Just run for it like…
CHUCK:
There we go.
LUKAS:
I mean, we can be like the Bernie Madoff of like conferences. [Laughter]
WARD:
Oh my god, yes.
So yeah, be sure to get your boss’ approval and be ready to buy tickets when they go on sale. We'll have two rounds of ticket sales and early bird ticket sale and then a regular ticket sale later on, a couple of weeks later. So be ready for that.
WARD:
I'm sure it will be a big one and if you did run away with the money, then you can be at some place exotic.
JOE:
Like Vegas?
WARD:
[Chuckles] No, yeah, you’d say you're going to Vegas but you're going to some place like really shangri-la. Me, if I try to run a conference, I’d take all the money and I’d be able to make it to San Jose.
JOE:
[Chuckles] Awesome.
CHUCK:
All right, well, I think that’s all we got, so we'll wrap up and we'll catch everyone next week!
[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!]