109 JSJ Dependency Injection in JavaScript with Vojta Jína & Misko Hevery

The panelists discuss dependency injection with Vojta Jína & Misko Hevery.

Show Notes

The panelists discuss dependency injection with Vojta Jína & Misko Hevery.
Special Guests: Miško Hevery and Vojta Jína.

Transcript

 

[This episode is sponsored by Frontend Masters. They have a terrific lineup of live courses you can attend either online or in person. Their upcoming course is JS Framework Showdown with Brian Holt from reddit. You can also get recordings of their previous shows like JavaScript the Good Parts, AngularJS, CSS3 In-Depth, and Responsive Web Design. Get it all at FrontEndMasters.com.]

[This episode is sponsored by WatchMeCode. Have you been looking for regular high-quality video screencasts on building JavaScript done by someone who really understands JavaScript? Derick Bailey’s videos cover many of the topics we talk about on JavaScript Jabber and are up on the latest tools and tricks you need to write JavaScript. He also covers language fundamentals, so there’s plenty for everybody. Looking over the catalogue, I got really excited and I can’t wait to watch them all. Go check them out at JavaScriptJabber.com/WatchMeCode.]

[This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.]

CHUCK:

  Hey everybody and welcome to episode 109 of the JavaScript Jabber Show. This week on our panel, we have AJ O’Neal.

AJ:

  Yo, yo, yo, coming at you live from what used to be a block of ice but is now a bowl of soup.

CHUCK:

  Joe Eames.

JOE:

  Hey everybody.

CHUCK:

  Jamison Dance.

JAMISON:

  Hello friends.

CHUCK:

  I’m Charles Max Wood from DevChat.TV. And we have two special guests this week, Misko Hevery…

MISKO:

  Hello.

CHUCK:

  And Vojta Jina.

VOJTA:

  Hello.

CHUCK:

  I was very careful to say those right.

VOJTA:

  Yeah, you are cool. You did it totally right.

CHUCK:

  Do you guys want to introduce yourselves really quickly?

MISKO:

  Sure. My name is Misko. I am the guy who stared Angular not knowing what it would become. I’ve been working on it ever since for about five years now. Vojta?

VOJTA:

  Yeah. My name is Vojta. I’ve been working with Misko and a bunch of other crazy guys on AngularJS. I think I joined that team a little bit over three years ago. I like testing. I like functional programming. And I like music. I play the trumpet. I think that’s about it.

JAMISON:

  That’s sweet.

AJ:

  So, here’s what I want to know. How can people be part of the Angular team three years ago, when we all know that no one had ever heard of it before two years ago?

VOJTA:

  That’s a good question.

MISKO:

  Time travel.

CHUCK:

  [Laughs]

AJ:

  So, you went back in time to work on it for another two years to get it to the state that it’s at now?

MISKO:

  Angular is so good, it warps time. [Laughter]

AJ:

  Alright. Can you just warp again and get version 2 out then?

MISKO:

  Working on it.

AJ:

  Well, couldn’t you warp back six years ago and work on it then so it’s ready now?

MISKO:

  [Chuckles]

JAMISON:

  That’s the discussion we always have when we come close to a deadline, is we could either work more on our code or we can work on a time machine and be years late and still ship on time.

CHUCK:

  Right.

JOE:

  Exactly.

JAMISON:

  Anyways. [Chuckles]

CHUCK:

  So, we brought you on today to talk about dependency injection. Now, I know Angular does not rely on dependency injection at all.

MISKO:

  Right. That’s an interesting way of putting it. 

CHUCK:

  [Chuckles]

JAMISON:

  It’s a lie.

VOJTA:

  I’m actually excited, like what are we going to be talking about, because I’m not sure if… how long is it supposed to be, this podcast?

JOE:

  Two hours.

CHUCK:

  Yeah.

JAMISON:

  Yeah. [Chuckles]

CHUCK:

  Give or take an hour and a half.

VOJTA:

  I don’t think I know that much stuff about DI to talk about it for that long.

JAMISON:

  When you talk about code examples, you just pronounce every symbol separately and that stretches it out a lot.

VOJTA:

  Okay. That might work.

JAMISON:

  [Chuckles]

CHUCK:

  So, my understanding of dependency injection is actually relatively simple. Is there more to it than passing some object in that gets stuffed onto it inside of the scope? I know there’s a better definition than that.

MISKO:

  Well, I’d characterize it differently. 

CHUCK:

  Okay.

MISKO:

  I think dependency injection at its core is simply saying that instead of looking or creating the dependencies, you simply say, you declare them in your constructor. You say, in order for me to do my job, I need help from object X and just simply ask for that object in the constructor. And it basically becomes not your problem. It becomes the problem of whoever’s constructing you to also supply all the dependencies to you.

VOJTA:

  When I explain these things, I actually always try to split it into two things. One thing is dependency injection as a pattern, which is something that Misko just described. And then something we call dependency injection container or framework, which is the framework that can do the wiring or assembling together. So, it basically takes all the little components of your app and assembles it together based on declarative notations or something.

CHUCK:

  I have to say, I like your definition for dependency injection way better than mine. [Laughter]

VOJTA:

  Okay, cool.

CHUCK:

  So, are there tradeoffs then between maybe explicitly declaring dependencies as opposed to passing them in, in a constructor?

VOJTA:

  No tradeoffs. It’s great. [Laughter]

AJ:

  That’s interesting.

VOJTA:

  Of course there are tradeoffs.

AJ:

  My code feels differently.

VOJTA:

  I think it’s again, it depends whether we are talking… I think the pattern, I think it has many advantages, especially for testing and for better code reuse and maintainability. I’m pretty sure it has some downsides too. Like for instance, I think you have to type a little bit more. And that’s basically why we use these dependency injection frameworks or containers because they help us with this problem of typing too much.

AJ:

  So, question though. I’ve heard it said several times that dependency injection makes testing easier. But I’m not really sure that I buy that, in terms of the alternate solutions. Like for example with RequireJS or with CommonJS you could just overload the require function and provide an alternate module just as well. So, are we saying that dependency injection is easier to test than using script tags? Or are we saying that it’s easier to test in relation to the other module?

MISKO:

  You’re on the right track with the Require and module system. And if you squint a little bit, Require is actually a form of dependency resolution, or form of dependency injection, the difference being that RequireJS runs exactly once at the beginning to bootstrap your application. One the classes get loaded, the RequireJS doesn’t do anything. This is in contrast to dependency injection which over time can inject a different thing. So, once you load a particular module in RequireJS, you have to restart the VM to get a different module in there, whereas with dependency injection, you’re dealing with instances rather than classes. And so you can, every time you invoke the injector, you could have a different set of dependencies. So, in a way RequireJS is dependency injection for your code, whereas dependency injection is DI for your instances, if that makes sense. 

VOJTA:

  Essentially, when you start doing testing, when you write unit tests, every unit test is basically a little app. So, in every unit test you do a little bootstrap. And so, in a static language like in Java for instance, it would be much harder. But because of the way JavaScript is very dynamic, you can monkey patch and overwrite anything. And therefore, yes you can test it with RequireJS because what you do is some kind of hack where you load module X and you override it to some mock value. And then in another test, you again monkey patch that state to something else. That works.
You can do it. But it’s, I think it brings many problems like you need to clean up after every test. 

AJ:

  Really, what my point was, is that the way that Angular does it with the, you pass in the variable names into a function, that is just one of the mechanics of the framework. You could have just as easily used a Require syntax, a syntax that looks like Require, and it still could have done all the work behind the scenes that Angular is doing. It’s just I was just trying to bring up the difference between the mechanics of the dependency injection with function names versus the mechanics of one of the other module systems. They could all have the same easy of testability if they had the bit on the backend that when the function gets called, it reinitializes or whatever.

VOJTA:

  So, I would say almost. Because if you do what you’re just describing, which means “Yeah, let’s take all DI stuff and let’s use the same [inaudible] or the syntax of RequireJS, you would… wait actually, sorry. With RequireJS it would be actually the same because yes, RequireJS you have the array of all the stuff that you want. And then you get them as argument, that would be the same. But if you did CommonJS where you do var x = require something, that would be more like a service locator pattern which is very similar, but the difference is that even in your test, you need to create this context and then pass in the context. And each of those components will look up or will request whatever they want imperatively.

JOE:

  I’d like to jump in a little bit on this as well. Because for one thing, dependency injection is just a way of getting something done and it’s very language agnostic. [Inaudible] doing Java, dependency injection in Java 10, 15 years ago. So, it’s not just about locating a service. But on top of that is a

personal note. Testing with RequireJS is not easy. It’s a huge, huge, huge pain in the butt. And Merrick and I wrote, well Merrick did all the writing of SquireJS to actually enable true testing of RequireJS. And it is so difficult.

JAMISON:

  It’s so painful. 

VOJTA:

  Yeah. I actually wanted to mention this library. Yeah, that’s a good example of the problems that you have with RequireJS because you have to monkey patch the context in order to override the services. 

JOE:

  And I think AJ’s point wasn’t necessarily that Require is or is not easy to test with. But every time I, I don’t want anybody out there to think that Require is actually easy to test with, because it’s not.

AJ:

  Well, yeah. I was just saying dependency injection in of itself isn’t any easier or more difficult to test. It’s how the management behind the mechanic is constructed. It’s the implementation. Because I implemented dependency injection and I didn’t do anything to make it easy to test. So, it would have been just as difficult to test as RequireJS.

MISKO:

  Well, so the difference between RequireJS and injector is that RequireJS is global, right? If you create exactly one injector in Angular and you make that injector global, then you are in the same situation as you are with RequireJS. 

AJ:

  Right.

CHUCK:

  Yeah, I want to point out that the reason that a lot of people like dependency injection is because it gives you this flexible way of managing your dependencies. Because it basically inverts the dependency stack because you pass them in. And so, if you want to test something, you can pass something in that just behaves in the right way, in other words it meets the contract that the rest of the function expects, and then can do things to validate your testing throughout your application or throughout your module. 

And so, for that reason, you get in and you want to test one controller with one module and another controller with another module. Or you want to test them both with the same, I don’t know, HTTP or something set up. But they’re testing different things because they use them in different ways. Then you can set up the test harness in one, one way, set up the test harness in the other the other way. And you just pass them in as dependencies and it just works. And so, you’re setup is a lot cleaner because when you’re done you can just throw it away instead of going back to the global state and saying, “Okay, now change back to what the real global state should be so that I can verify the next thing in my stack.”

VOJTA:

  Yeah, exactly.

JOE:

  Yeah. And dependency injection also, it really does inherently make testing easier depending on how you implement how you’re going to do dependency injection. But thinking of a static language like Java or C#, if you’re injecting the dependencies to a class in the constructor, then you don’t need the dependency injection framework anymore during test time. You just simply, when you instantiate the class, you pass in whatever objects you want to be those things when you construct the class. 

Or in the case of JavaScript, if your dependency injection is built around a function and your function takes in parameters and that’s your dependency injection, then when you go to test that function you could just have to pass in objects that match the interfaces of what the real objects are. And your test objects can be something entirely different. So, you can completely scrap the framework when it comes test time. It’s during runtime when you need the framework. So, dependency injection from that standpoint does really enable testing and makes it a lot easier.

CHUCK:

  Well, the other thing that I like about dependency injection is that it can take advantage of the global state in the sense that if you don’t pass, if you don’t inject the dependency, you just leave it empty, undefined or nil or whatever you want to define it as, you can just set a default in there. So, you go in and you say, “Well, if it’s not defined then define it to this,” and then it’ll just behave in a default way with the default dependency. And so, if you’re concerned about global, having this global state or being able to inject if you need to, you can do both.

JOE:

  Right. And I know with Angular, it’s a little bit different. If you’re injecting dependencies for a
controller, that’s different than when you’re injecting dependencies for a service. I don’t know.
Maybe one of you guys can speak to that.

VOJTA:

  How is it different?

JOE:

  Well, the setup in the test is different, right?

MISKO:

  That’s because we don’t have a true injection system. And when we are instantiating a controller, we’re saying injector.instantiate but when we’re instantiating a service, we say injector.get. And that’s kind of the difference you’re seeing over there. But actually, in Angular 2.0 and also in AngularDart this has been unified.

JOE:

  Oh, really? That’s interesting. Was that a very conscious effort?

MISKO:

  No. It turns out, originally Angular did not have dependency injection and it has been shoehorned in after the fact. And so, what you’re seeing here is a couple of these places where the shoehorning in was not done as good as it should have been done. 

JOE:

  Really? I actually am surprised to hear that. I thought that when you built it, DI was part of the original idea to begin with. 

MISKO:

  See how good I am at refactoring code? [Laughter]

CHUCK:

  He may have refactored your memory, too.

JOE:

  That’s right. [Laughter]

VOJTA:

  But DI has been in Angular for quite a long time. [Inaudible] at the beginning.

MISKO:

  It has been there before anybody else worked on it except me and Adam Abrons. 

JOE:

  So, Misko I know that you, before you did Angular, you were big into testing to begin with over at Google, right? So, when you built Angular, was it not as testable to begin with? Or did you just have other ways of testing that didn’t involve DI and then added it later?

MISKO:

  No, testing was always part of the code I had written. It’s just that originally, the goal of the system was slightly different. The goal was for a web designer, somebody who doesn’t necessarily know how to program, to be able to add a bunch of tags into HTML and through static HTML into a dynamic, interactive page. And for that world, you don’t necessarily need dependency injection because others are not really adding behavior to it. It’s not until later on when we turned it into a framework which was meant for web developers rather than web designers the need for dependency injection really came to be. 

JOE:

  Interesting. So, right from the beginning it was more about being the DSL for the web?

MISKO:

  Yeah. The idea was, what if you could take a static HTML page that you load out of file:// and just add a bunch of extra tags into it and all of a sudden that page could persist itself, send an email, store the form that you have filled in so when you come back later you can see the same form again. 

JOE:

  Cool. I’m just curious. At what point did it grow into something else?

MISKO:

  So, it grew into something else when I was working on a project at Google which is now called the Google Feedback. And we were building something in GWT and was getting really frustrated just how unproductive I was being, and basically told the team, “Well you know, I’m toying with this idea on the side. And I bet you many of these ideas could be reused here. And we could build the application much faster than we could build it in GWT.” So, the boss called me on it and said, “Sure. If you think you can rewrite it in a couple of weeks, give it a try.” And a few weeks later, I actually did rewrite it, a hacked up version of Angular. And ever since then, people were like, “Hmm, maybe this is worth pursuing more.” And so, this is the point where Angular stopped being a web designer tool, started being really for web developers.

JAMISON:

  So, I have a question that’s kind of going back a little bit to the dependency injection in general idea. I’ve heard the whole idea of building dependency injection into a framework, in some ways it conflicts with module systems like RequireJS or Browserify or whatever. If those module systems that existed were more friendly to testing, do you think that frameworks would need to build in their own dependency injection systems?

MISKO:

  Yes. And again, I want to point out that frameworks such as RequireJS and Browserify are concerned with loading static code into the VM. This is a very different concern from dependency injection. Dependency injection is concerned with creating instances of that code that was loaded using RequireJS. So, you can think of RequireJS as the very fancy way of inserting script tags into your application, whereas you can think of the dependency injection system as a very fancy way of calling the new operator on your application. So, the two while very similar and have the same vocabulary and in some ways deal with the same thing, are actually concerned with two very distinct things.

JAMISON:

  That makes sense.

AARON:

  That’s a great explanation.

JOE:

  Wouldn’t it be possible though for a library loading app or a system like Require to actually do both and make it friendly and make it work enough so that you wouldn’t need a separate DI?

MISKO:

  Yeah. I think Vojta can speak more to that.

VOJTA:

  Well, I think with the new DI we tried to, I wouldn’t say put it together because these are still two separate things. We have module loader, which is either ECMAScript 6 loader or RequireJS and then we have DI framework. Well, we just try to make sure you don’t have to type too much. So basically, for instance in current Angular 1.x you have to define something like DI modules so that you can load the code into the dependency injection framework. And so, if you are using RequireJS as well, then you end up with basically defining two kinds of modules for everything, DI module and RequireJS module. So, with the new DI system we try to simplify this so that in most cases you don’t have to define any modules. You just use the default RequireJS or any other module loader modules. And DI can consume those. So, it’s much simpler. But these two things are still separated.

MISKO:

  So, I want to add to that a little bit, which is if you step back from RequireJS and dependency injection system and if you realize that JavaScript is unique because code and data is one and the same thing, you can create a function and you can pass it around. A function, if you think about it, is code. This is not the case in Java. You can’t dynamically create classes and pass them around. The namespace of classes and methods is separate from the namespace of variables that you pass around. But in JavaScript, it’s one and the same, right? 

So, if you squint a little bit, you can say, “Hey, what is the difference between injecting and instance of a class or injecting data that happens to be the class,” so you can say, I can inject a foo instance or I can inject the foo type itself. And if you look at it this way, then if you say well, really what tools like RequireJS do is they load or dependency inject the types rather than the instances of those types. They have a minor deficiency which is that they load all these data into a global state rather than loading them into the modules and injectable state so that you could easily reload them if you feel that’s necessary. 

But if you could merge the two pieces together, then you could basically be in a situation where you could have an injector and say, “Give me an instance of foo,” and then the injector says, “Well okay, I have to make a new foo first.” But in order to make a new foo, I first have to get the type foo, which then recurses on itself and says, “Well, how do I get foo?” Now, there’s a little bit of a problem of asynchronicity in there because foo might not be loaded. It has to be dynamically lazy loaded, which means there are some promises or something as the result. But if you squint hard enough, you can imagine a world where loading data and loading code is really one and the same.
Does that make sense or am I gone into deep end?

JOE:

  Maybe I’m not squinting hard enough. [Laughter]

AJ:

  I think I understand what you’re saying. So, when we first started a couple of minutes ago, I did not know as much about dependency injection as I do now because I’ve been scouring Wikipedia and stuff trying to understand these things that don’t quite, that I wasn’t grasping properly. So, dependency injection actually doesn’t necessarily have anything to do with the dynamic way in which it’s done in Angular, right? The whole concept of, you’re requiring the modules by whatever they happen to be named in the function, that’s not actually the pattern of dependency injection. Dependency injection is the pattern of, you provide a mechanism by which a service makes known what it needs and an injector provides an instance of that service to the module that needs it.

MISKO:

  Well technically, the pattern of dependency injection is simply saying, “I am not going to make or look for my dependencies.” In other words, make means calling the new operator and look for them means using some global variable to find them. I’m not going to do these things. Instead I’m just going to ask for the dependency as a parameter in a constructor. That’s all the dependency injection means at its pattern level.

The second part, which is the containers, if you have this pattern that you simply say, “I’m not going to look for things. I’m going to ask for things,” then an interesting property emerges out of the system, which is that if you say, “I want to make a new foo,” then you say, “Okay. Well, how do I make a new foo?” You just call new foo. Okay, but foo has arguments. So, if you can reflect upon the arguments, and this is the part that I had through these annotations thing, if you can reflect upon the arguments, then you can say, “Oh, I see. The foo requires bar.” Therefore, in order to make foo, I first have to make bar. So, you get into this recursive pattern. Once the bar is constructed, then you can take the instance of it and put it inside of foo and then you can construct the foo. 

And so, you realize that if you follow this pattern of declaring your dependencies then you can selfassemble the application. It’s just a property that happens automatically without any kind of extra effort. And because it happens automatically then you can build a framework around it that says, “Okay. If somebody asks for a particular instance of something, then just recursively resolve the arguments of the constructor until the whole graph of objects gets constructed.”

VOJTA:

  Nice job, Misko.

MISKO:

  Thank you, Vojta.

VOJTA:

  I agree with you. [Laughter]

MISKO:

  The earlier point about squinting. So, imagine you’re in a world. You’re running an application, right? The application is already constructed. And one of the controllers says, “I need to get a hold of a user object,” which is on a database, it’s on a server, so it has to go and fetch the data somehow. And one way to think about it is saying, well instead of me writing the code that I have to go fetch a user data, what if I could just say, in my constructor, I just need the user data. Now it becomes a problem of the container rather than the problem of the code to go fetch the data. And if you can do that, then all of a sudden you’re in a world where, hey you can just name your data sources and they get injected into your codebase. And you no longer have to deal with loading the data yourself. 

And now, if you take one more step and say, wait, well what’s the difference between loading data and loading code? And it turns out in JavaScript there is no difference, then you can say, just like you can ask for an instance of foo, you can now ask for type of foo. And what you get out of it is lazy loading of code. So, until somebody actually needs to instantiate a particular class, there is no need to load that class. And so, making a request instantiate class means making the request to get a hold of the type first which might make a request to load the script tag, which then in turn recurses upon itself and says, “Okay. To make an instance of it I have to call new, which then instantiates new.” So, this is the kind of thing we’re trying to get to, is that we would like to treat, if you treat code and data the same, then you can get the lazy loading of code for free.

VOJTA:

  Yeah. I think Misko is basically trying to say that DI can also give you basically file-by-file lazy loading for free, in theory. You could make it so that every dependency, every file, is loaded lazily at the time when it’s actually requested where somebody really needs it during the runtime. 

CHUCK:

  Now, you guys keep mentioning injectors and I don’t quite follow what those are. 

VOJTA:

  Injector is basically the container. 

CHUCK:

  Okay.

VOJTA:

  Yeah, the container that keeps probably references to all the instances and the container that resolves the dependencies and instantiates things.

CHUCK:

  Okay. 

MISKO:

  So, to put it differently, normally you would say new Foo, with capital F and you would say something like var foo, with lowercase f, equals new capital Foo. You’re saying make me an instance of Foo. With the injector world you would say lowercase foo equals injector.get capital Foo. And at first you’re looking at this and you’re saying, “Wait, wait, wait, you just made me type a whole bunch of more characters. How is this an improvement over just calling the new operator?” And the difference is, and this is a very subtle difference that takes a while to grok, is that you have to do this thing exactly once, this injector.get. You have to do it exactly once on a top-level object representing your application. All other instantiations happen through recursion, whereas when you use a new operator you actually have to type the new operator every time you need something. Vojta, I love how there’s silence every time I say something. [Laughter]

VOJTA:

  Yes.

JAMISON:

  That’s the silence of agreement. 

VOJTA:

  When we are talking about all these general ideas on how DI works and why we do that, from my side I would say I did a talk at the ng-conf actually which was about the new DI system. But the first 10 minutes is I was basically trying to explain these things. So, if anybody’s interested in that, I would recommend that. I think I did a better job at that talk than I’m going to do today, because I

was actually prepared for it. 

JAMISON:

  You weren’t born ready to talk about dependency injection?

VOJTA:

  Not really.

[Chuckles]

VOJTA:

  No, but yeah I think it’s the first 10 minutes or something.

AARON:

  So Vojta, you mentioned a second ago that a good DI system will give you the ability to potentially lazily load code at the time that you need it. Are you hinting to something that’s going to be in Angular 2? 

VOJTA:

  It could be. We have something we call asynchronous injection in the new DI, which is a step in that direction. So, it is possible but I don’t think it, at least at this point, it’s not a big goal for me. Or I don’t think it’s the reason why we are making a new DI.

AARON:

  Okay.

JAMISON:

  Do you want to talk a little bit about what is new with the dependency injection in Angular 2.0?

VOJTA:

  Sure. There are many new things. I’m just thinking, what’s the most important stuff?

MISKO:

  Hierarchical injection, sir. 

VOJTA:

  Yeah, that’s probably one of the most important news, which is in Angular 1.x it is pretty hard to lazy load code. Or even as you probably know, everything is a singleton. There is only a single instance of everything. And so, in Angular 2.0 we have this feature we called hierarchical injectors, which basically mean that you have a tree of injectors. And in each of those injectors you can create a new instance of any service you want. And you can also lazy load code or lazy load other providers into an injector. 

So, for instance in a typical Angular app you might create a new child injector for each route. And that means that you can have, some services can be marked as per route. So, for instance let’s say you have a template cache, you might say that this template cache has scope or there should be a new instance per route. And then it means that for every route, you get a new instance of this template cache. And at the same time, you can load additional code again, per route, because of these hierarchical injectors.

Then I think a big change is something we already mentioned, and that is the nicer integration with module loaders. So, either RequireJS or ECMAScript 6 loader, or any loader you want to use. So, I think this integration is much nicer. You don’t have to type that much. This new DI can basically consume RequireJS modules or ECMAScript 6 modules. What else?

MISKO:

  You no longer have to use strings.

VOJTA:

  Yeah. I think that’s a big feature too. Basically, in Angular 1.x the way you would describe, the way any component declares its dependencies is done through strings. So, if your controller needs to get HTTP service you mark it with HTTP. So, string is, we call it token, which is like the ID of the interface, what you need. And this changes in Angular 2.0 where the token can be anything basically. It can be string but it can be a reference to an object or a function. 

And so, what we recommend or the way we do it, we actually use, we annotate these dependencies not with strings but with references to the default implementation. And that is kind of neat because in most of the cases where you don’t need to override anything, you don’t need to load any code in the DI and you just annotate. You have a function and it requires one argument of type foo, then you just say inject foo and you actually pass it the reference to that type, not a string. And that’s all the DI needs. You don’t need to [put] modules or any code into the injector because the injector can instantiate this service based on that token, because that token is actually a reference to the class or constructor function. 

I’m not sure if this makes any sense. I think it’s pretty hard to explain it without code examples. But if anybody is interested, you can check it out on GitHub and there are some examples. 

JAMISON:

  I was going to say, where can people go look to see the examples? Get the link in the show notes, I guess.

VOJTA:

  Yeah. I will send the link to the chat and then I guess you can post it somewhere. That’s basically,
I think the major changes or the major new features. One of the big changes is also we got rid of, I’m not sure if you know, in Angular 1.x there are these two phases. It was config phase and the run phase, which causes a lot of confusion. And so, I’m happy we got rid of it. So, there’s no run or config phase. There’s just one phase.

JOE:

  Cool.

CHUCK:

  Awesome. Well, I know we have some people that need to take off pretty quickly and I want to make sure we have time for picks. But is there anything else that we should talk about that we’ve missed with dependency injection?

JOE:

  I want to find out what the status is on DI.js.

VOJTA:

  So, DI.js is what I was just talking about. That’s the new DI system for Angular 2.0. What’s the status? The status is that we are using it for Angular 2.0 so it’s used in templating. It is still in a pretty early stage, but I think you can use it on anything you want. The basic set of features is done. And I don’t think there’s going to be any major changes into the core stuff. I’m still working on it and we are still trying to figure out better ways how to do it. There are many open questions and problems that I’m not sure how to solve properly that I would be really happy about. But I think the core stuff is not going to change.

JOE:

  Has anybody else actually utilized it that you know of?

VOJTA:

  I don’t know. I know that there are people experimenting with it, especially in project, in Node.js.

That’s one of the things that I should probably mention too, that this new DI is designed to work [inaudible] in the browser. We use it on Angular so that’s in the browser, but it’s also designed to work on Node.js. At some point I would like to refactor Karma to use this DI instead of the old custom DI that I made for Karma. But I’m not sure when that’s going to happen. But it will. I just don’t know when.

JAMISON:

  That sounds like a call for help. 

VOJTA:

  Oh yeah, totally. [Chuckles]

VOJTA:

  I will totally accept pull requests with that. [Chuckles]

VOJTA:

  There are seven open issues now. So, it’s very active. [Laughter]

VOJTA:

  No, this is actually one of the very few projects that I keep up with issues. So, I actually triage them pretty quickly. Seven open issues and 38 closed. Isn’t it awesome? [Laughter]

JAMISON:

  That sounds like a good ratio.

VOJTA:

  Yeah, that’s great. If you look on Angular, it’s going to be 7 million and 30 [inaudible] [Laughter]

JAMISON:

  The scrubs.

CHUCK:

  Awesome.

VOJTA:

  Yeah, so it’s pretty nice, a little tiny project. So, don’t create any issues. [Laughter]

JAMISON:

  But yeah, if you ask for help, that issues number is going to go up.

AARON:

  Yeah.

JAMISON:

  Cause yourself problems.

AJ:

  Yeah, seven’s a really good number. You probably should just stick with that one.

VOJTA:

  Can you freeze GitHub issues so that people can’t post issues?

JAMISON:

  I think you can turn off issues.

AJ:

  Yeah, you could turn them off. But I think what you could do is just keep number seven open.
Keep it your furthest goal. 

VOJTA:

  I see.

AJ:

  Let people open up number eight, but always fix number eight and close it immediately so no one sees it.

VOJTA:

  Okay.

AARON:

  You don’t want to encourage anyone. [Laughter]

AJ:

  Or, instead of linking to the issues, you could link to a specific issue like issue number three and be like, “If you have an issue, comment here.” [Chuckles]

CHUCK:

  Alright, let’s go ahead and do the picks. [Laughter]

CHUCK:

  Aaron, do you want to start us with picks?

AARON:

  Yeah, I’ve got a couple of picks. I got four of them. So, one of them is JSTheRightWay.org. I thought that it was a good spot for people learning JavaScript to go, just see, hey who are some of the main players I can follow? What are the main frameworks? What are some of the more popular tools, gaming engines? What is the history of it? I just thought it was an all-around good site. I like the look and feel of it. So, I want to pick JSTheRightWay.org.

And then I want to pick DevFest Family. It was a small family developer conference that was put on locally. And we had a lot of kids show up. And we had a lot of people write their first lines of code. And it was a great experience. If you guys see any DevFests in your local area, if they have anything to do with families, you should definitely take your wife and kids or whoever your family is to the event because it’s a lot of fun.

And then the last two are two books. So, one of them is ‘Ready Player One’. Have any of you guys read that?

JOE:

  Yes, loved it. Absolutely loved it.

AARON:

  So, it’s a book I could not stop listening. I binged listened to it. It’s about 80’s pop culture and video gamers. And there’s an Easter egg hidden somewhere in the biggest game ever written.

JOE:

  It’s a fictional novel.

AARON:

  Yeah. Humanity obsesses around playing the game nonstop until they can find it because the winner gets a fortune bigger than you can measure. But it’s a really cool book and I couldn’t stop listening to it. I thought it was awesome. And it’s got all of the 80’s pop culture you can handle. So, it was a lot of fun to read.

The other one, it’s called ‘Lost Boys’. It’s by Orson Scott Card. And for me, it was basically a book about someone a lot like me. So, I really identified with it. And I thought it was going to have a real cutesy type ending and then within the last chapter, there’s this programmer guy and he’s a lot like me and all of a sudden his family goes through this huge tragedy and I’m in tears. And I’m in my car driving on the freeway. It was a great read though. So, the ‘Lost Boys’ and ‘Ready Player One’ are the two books I’ll pick. 

CHUCK:

  Now, you said you listened to them?

AARON:

  I listened to them in the car. I have a 35-minute commute each way. So, I listen to books. 

CHUCK:

  Is that on Audible?

AARON:

  Yeah.

CHUCK:

  Awesome. Alright, we’ll try and get links to both Audible and Amazon.

AARON:

  Cool.

CHUCK:

  AJ, what are your picks?

AJ:

  The Wikipedia article on dependency injection, because up until just now, I’d never heard it aside from in connection with Angular. And I didn’t grasp the way that Angular does black function magic, black magic on functions, is not dependency injection. Dependency injection is what it does behind the scenes in handling those dependencies which was adequately explained today. And the Wikipedia article that shows Java examples with dependency injection helps frame your mind a little bit better around the pattern as a concept outside of the framework of Angular, which I think is important if you want to understand this.

But also, there as this article that is perhaps a little bit, it has a negative slant to it. It’s thoughtprovoking if you look at it in the right light. But it’s ‘The Unstable Future of Angular.js’. I think that AngularJS has a stable future. It just talks about some of the funny things that happen in there, which one of my videos was linked to it in there. And it hit Hacker News and it was a big deal. But it talks about the black magic problem.

VOJTA:

  Is that by the guy that used to work on Drupal?

JAMISON:

  Yeah, I think so.

VOJTA:

  That was actually good reading. I read that article. I think there were some good ideas there, or good opinions.

AJ:

  Yeah, they’re good opinions. But I just don’t want to come across, because I buffeted a little bit with you guys about the meaning of things, and I don’t want to come across as anti-Angular. I really like Angular. 

VOJTA:

  No, no. If it’s the article I’m thinking about, I think it was good thoughts. It was obvious that that guy had experience from working on a pretty successful and big project.

AJ:

  Well, I just sent a link. You tell me if it’s the same one. Anyway, and then I just came up with a little example of static versus dynamic versus automatic dependency injection that I’ll have in the show notes. I guess it’s not really a pick, just something to put in there. 

And I’ll pick rock climbing, because it’s good. I found out that you can put your thumb over top of your index finger and it gives you a better hold. I don’t do a lot of rock climbing but somebody was showing me how to scale a wall and they rock climb. And that’s what they taught me and it makes it easier if you ever want to climb a wall. 

CHUCK:

  Alright. Jamison, what are your picks?

JAMISON:

  I have two picks. One is I’m tangentially picking Hearthstone, the computer trading card game from Blizzard. I thought it was dumb every time I heard about it until I tried it. And it’s pretty great.

So, there’s a website called Liquid Hearth. It’s a community website. And it’s from this lineage of community websites around strategy games. It’s descended from some really well-known and really well done sites. So, lots of good stuff on there about how to learn to play the game better basically, if you want to learn how to waste your time more efficiently. [Chuckles]

JAMISON:

  And then the other thing is just an album I started listening to this week. It’s called Drift and it’s by this artist called Nosaj Thing, I think. But the first word is spelled weird. It’s S-A-G, or no, S-A-J. Nosaj Thing. I don’t know. But it’s chill, electronic music. It’s the same kind of music I always pick. So, if you hate that, don’t listen to it. Those are my picks.

CHUCK:

  Alright. Joe, what are your picks?

JOE:

  Alright, so I’ve got three picks. The first one is That Conference, which I’ve picked in the past. But I think it’s totally worth picking again. An awesome conference in Wisconsin in August this year. They do bacon, which is very important to me. Lots of bacon. And it’s at an indoor waterpark. So, it doesn’t get any cooler. I’m taking my entire family. And I’m actually going to be speaking there on Angular best practices. So, Vojta or Misko, if you guys want to learn anything about that, come and attend. [Chuckles]

MISKO:

  You know, I really should attend one of these best practices, because people keep asking, what’s the best practice with Angular? [Chuckles]

MISKO:

  And I have to make it up, because it turns out I haven’t built any Angular apps yet. [Laughter]

CHUCK:

  The answer is do what Joe does.

JOE:

  Yeah.

AARON:

  [inaudible] what Joe knows.

JOE:

  [Chuckles] My talk’s actually going to be based a lot on my course, my Pluralsight course of the same name, which leads me into my second pick which is my latest course released. It’s on getting started in frontend web development, with Pluralsight. And it’s actually been super popular, which is really cool to see that a lot of people want to either get into frontend web development or get better at it. And I spent a lot of time putting that course together because it was basically the course for me. When I got into frontend web development years ago, I felt like there was just so much to learn and I needed somebody to lay out the landscape. And nobody did. And so, it just took me forever to just get a lay of the land. And so, this course is really a course that I built for me years ago, of course, just updated with today’s technology. So, that’s on Pluralsight.com. It’s the number five course right now.

And then my last pick is going to be a Kickstarter project. It’s a documentary about the actors that were the characters that were wearing masks in the movie Star Wars. So, the guys who played storm troopers or the guy who played Greedo. And it’s a documentary about those actors and what it was like for them. And I don’t know totally what it is all about. I haven’t even read all the Kickstarter material. I just backed it because I’m a huge Star Wars geek. And I love that sort of stuff. So, that’s my last pick.

CHUCK:

  Awesome. I’ve got a pick or two. One of them is I’ve been looking at standing desks for a while. And I currently have the Lifehacker Ikea you get an end table and a shelf and you screw the shelf onto the end table version. It works fine. But I keep thinking I want one that adjusts. And I found one that you basically build for yourself. They use pinewood in the tabletop. But they show you how to put it together with the linear actuators to move it up and down and stuff. And overall, they spend $200 to $250 in parts and then built it themselves. And so anyway, that got me interested. So, I’m going to pick that. 

And I’m also going to pick a book. This was where I was first introduced to dependency injection. And that is ‘Practical Object-Oriented Design in Ruby’. And they give some examples in both tests and code in the specific chapters related to that. So, I’m going to pick that as well. Misko, what are your picks?

MISKO:

  Well, I’m going to be non-traditional. So, I have two kids. And I’m really into trying to figure out, into parenting, et cetera. And I read this one book a while ago that I thought was really interesting. It was called ‘How to Talk So Kids Will Listen & How to Listen So Kids Will Talk’. And it contains a lot of practical information about what to say in what situations. The reason I really like this book is because after reading this book I was like, “Yeah, I know how to talk to my kids.” And then I realized, “Wait a minute. My boss does the same exact thing to me.” [Laughter]

MISKO:

  So, it turns out that kids are people too. And all these tricks are just good empathy listening and good ideas to anybody. And it’s explained in very practical terms. And I really liked it. So, we are all kids at all ages. And I guess I’m a kid to my boss because he uses those tricks on me.

VOJTA:

  It’s a great book. 

JOE:

  Awesome.

VOJTA:

  I like it too.

CHUCK:

  You just spent some of my dollars. Actually, more specifically, you just spent some of my Audible credits. Vojta, what are your picks?

VOJTA:

  I’m going to do one pick. And that is I’m going to pick a guy. His name is Rich Hickey. And it’s the guy who wrote Clojure, which is basically a Lisp that runs on top of JVM. And I got really excited about his talks and stuff recently. I would say, in a similar way, I was excited about testing four years ago. I’m now excited again about functional programming and using immutable structures. And the way he thinks about things is just, I think it’s great. And I think we could learn a lot from that. And so, yeah I will send you a link to some of his talks. I think the most famous is probably called ‘Are We There Yet?’ I really recommend any of his talks. It’s fun. And I think that’s about it.

JOE:

  Sweet.

CHUCK:

  Alright. Well, thanks for coming. Really appreciate you guys taking the time.

AARON:

  Yeah, thanks guys. That was a lot of learning that just happened. Thank you. 

CHUCK:

  Yeah, no kidding.

MISKO:

  Thanks for having us.

VOJTA:

  Thanks for having us. Yeah, it was fun.

AJ:

  Sexy voices like yours? We’ll have them anytime.

[Chuckles]

[Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.]

[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]

[Do you wish you could be part of the discussion on JavaScript Jabber? Do you have a burning question for one of our guests? Now you can join the action at our membership forum. You can sign up at
JavaScriptJabber.com/jabber and there you can join discussions with the regular panelists and our guests.]

Album Art
109 JSJ Dependency Injection in JavaScript with Vojta Jína & Misko Hevery
0:00
46:44
Playback Speed: