Dependency Injection Made Easy for VueJS and Vuex with TypeScript
Tags: vue, typescript, dependencyinjection, vuex
Published: 2019-05-26 16:59:39

---
title: Dependency Injection Made Easy for VueJS and Vuex with TypeScript
published: true
tags: vuejs,typescript,dependency-injection,vuex
canonical_url: https://medium.com/@fernalvarez/dependency-injection-made-easy-for-vuejs-and-vuex-with-typescript-3bc738c17e05
---

![](https://cdn-images-1.medium.com/max/1024/0*38yIPuEG7RKUFi-v)<figcaption>Image by @mriverodorta</figcaption>

I have to admit it _(and this is my personal point of view)_. Dependency Injection is not popular in the VueJS Ecosystem and, dare I say, in the JS ecosystem. People want to get stuff done quickly and nicely and that is absolutely fine but I feel that most of the SOLID and OOP principles are lost in the JS ecosystem but let’s talk about that in another post 😛

---

To understand Dependency Injection and its benefits, I **absolutely** recommend you to read this post first:

[A quick intro to Dependency Injection: what it is, and when to use it](https://medium.freecodecamp.org/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f)

---

Dependency Injection **was** kind of hard to implement in a VueJS application since it required to do a couple of tweaks to the codebase. One of the DI (Dependency Injection) solutions for JS and TS out there is [InversifyJS](http://inversify.io/) which is my favorite DI container but still hard to use with VueJS. Fortunately, that is no more and one person give us, which is to me, **the solution** to implementing DI in our VueJS Apps.

In this guide/practice, I want you to learn about how to implement Dependency Injection easily into your VueJS project with TypeScript using the library [Inversify Props](https://github.com/CKGrafico/inversify-props)

[CKGrafico/inversify-props](https://github.com/CKGrafico/inversify-props)

![](https://cdn-images-1.medium.com/max/498/0*92p2JN9TLqFNWpzw)<figcaption>Game Of Thrones (HBO)</figcaption>

### Complete Example

If you want to take a look into the complete example, you can go directly to this link!

[jefer590/vuejsdepencyinjectionexample](https://github.com/jefer590/vuejsdepencyinjectionexample/tree/03/use-dependency-injection-inside-vuex-module)

### What do I need?

1. Install the latest version of [**yarn**](https://yarnpkg.com/) and[**Vue CLI**](https://cli.vuejs.org/)
2. An editor compatible with TypeScript (I love [WebStorm](https://www.jetbrains.com/webstorm/) for this)
3. Clone the base repo for the exercise.

#### What are we building?

A super simple app that:

1. First, will use a service that connects to [https://api.kanye.rest](https://api.kanye.rest/) through a component
2. Then, the same behaviour but through a Vuex Module

### Getting Ready

Clone the next repo in your machine:

[jefer590/vuejsdepencyinjectionexample](https://github.com/jefer590/vuejsdepencyinjectionexample/tree/master)

and then instal the dependencies using

```
$ yarn install
```

### Creating the Service

In the /src folder, create a new folder folder called services and inside the new folder, create a folder called impl

- The /services root will be used to expose easily the Service Interfaces
- /services/impl will be used to add the concrete implementations of our interfaces/services

In the /services folder create the file IKanyeWestService.ts with this shape:

{% gist https://gist.github.com/jefer590/9edf63e93f1e6e0c239461e503dd9354 %}

We return a promise since we will retrieve the quote from an external service.

It’s time to do the concrete implementation! Create a file called KanyeWestService.ts in the /services/impl folder. It should have this shape:

{% gist https://gist.github.com/jefer590/05a647a957551adfab6289de95b752f8 %}

In this class service, what basically does is a _wrapper_ of our axios HTTP call which will return the object data that corresponds to the quote. You might ask:

> Why didn’t you do the http request inside the required component?

The answer is easy! It’s easier to maintain. By creating a decoupled service from our codebase and injecting it in the whole codebase, let us have our code in only and only one place. If for some reason the library changes in the future (maybe they change from HTTP to Protobufs) we need to only do the change in one place and will take effect basically in every part where the dependency is injected. We will be using the abstraction over the concrete implementation.

### The Dependency Container

#### Create the Container

In the /src folder, create a file called app.container.ts which will be the file where we are going to register all of the dependencies with its abstractions. the file should look like this:

{% gist https://gist.github.com/jefer590/ef43d6af9b700b76de22983efd70a4c1 %}

#### Register Dependencies

Let’s bind our dependencies!

In the same file, import container from inversify-props and both files that we did for the KanyeWest service. Inside of the function we will use container to register our service in this way:

{% gist https://gist.github.com/jefer590/7121287b037a87318aaf4933f0967d78 %}

To this to take effect in our codebase, in the main.ts you will import the function from app.container and use it inside the loadDependencyContainer

{% gist https://gist.github.com/jefer590/5202c390337e0878c8a7dd0c1b219dde %}

### Injecting a service into a VueJS Component

Our dependency container ir ready! Now it’s time to use it inside a Vue Component.

Go to to /App.vue and start by importing the IKanyeWestService and then a decorator from inversify-props called Inject

{% gist https://gist.github.com/jefer590/187655dbdbb286b1878dec30c2df1070 %}

And to inject this service, just simply add this piece of code in your Component class:

{% gist https://gist.github.com/jefer590/40eab8bcc41f543e40530634661b82d2 %}

and… That’s it! It literally take a few lines of code to use a dependency by using DI with this library. The only things left are:

- Fetch the quote when you click the button.
- Fetch the quote when the component is loaded.

To tackle both cases, in the method getQuote use the injected dependency and set the quote text into the data which is called quote

{% gist https://gist.github.com/jefer590/9c84c4147a5417a888c9bdca522e3024 %}

and to execute this when the component is loaded, just put it in the mounted hook method. At the end, your _script_ should look like this:

{% gist https://gist.github.com/jefer590/f5ec9013567cc3c3a371f9f34796e1f6 %}

Now that we have a fully functional component with an injected dependency, we can do the same for Vuex using vuex-class and vuex-module-decorators

#### Use Vuex in App.vue

Let’s first remove the content of the method getQuote, remove the injected dependency from the class and then remove the imports associated to the injected dependency.

Now import the **Action** and **Getter** decorators from vuex-class and use Getter above the quote data to bind it to the quote getter in the store:

{% gist https://gist.github.com/jefer590/f5ec9013567cc3c3a371f9f34796e1f6 %}

For the Action, since we are binding functions, we will need to match the function type in the next way:

{% gist https://gist.github.com/jefer590/f05e82ef562ff7f83b3984f8f18cfc1e %}

And use it inside the getQuote method. The component **script** should look like this:

{% gist https://gist.github.com/jefer590/e1c5551840c1779e0f2850e7215d7b80 %}

#### DI inside a Vuex class module

The last part of this guide is doing DI in a Vuex module using vuex-module-decorators and inversify-props which is as easy as the component approach and, dare I say, the same code.

go to /store/modules/KanyeWest.ts and import the same inject and Interface service that we used in the component into this file

{% gist https://gist.github.com/jefer590/33d953dd75923df7ae1e6d98b114a241 %}

And using the same approach as the component, Inject the dependency:

{% gist https://gist.github.com/jefer590/608efa28ea3f46a719945db802d51b87 %}

and that’s pretty much it! Let’s us it in our fetchKanyeQuote action:

{% gist https://gist.github.com/jefer590/9c3bbdf8dc213703361def977ee5479b %}

And _voila!_ Our project is finished and using DI!

And that’s it for today! I hope you learned a little bit about Dependency Injection on VueJS and TypeScript. Feedback is welcomed!

[![](https://cdn-images-1.medium.com/max/170/1*bk_C8Um34KavCkO2yzMCZg.png)](https://www.buymeacoffee.com/fern)<figcaption><strong>🙌 Thanks for Reading 🙌</strong></figcaption>