Angular: Bad Practices/Patterns: Using Too Many Services

Ryan Mackey-Paulsen
4 min readFeb 25, 2020

--

Services are great for sharing data between multiple components. They are great for storing some state, some config settings, and even consolidating api calls. They sure can do a lot. Why not use them for everything?

I’ve mentioned in other posts that services are not so great for running the core of your application. In an Angular app, you essentially have a component tree and those components can rely on services. Not the other way around. Remember that on the web, the presentation is in your templates. Yes, they get turned into javascript instructions, but you should be building with components and templates. Let me explain…

A Scenario

Let’s say you have to design an interface that has the possibility of displaying one of two custom buttons. One button does one thing, the other does something else, but they both look the same.

In a peer review, I have seen this example done the following way. First add the button to your template, then create a factory service and inject it into your component class. The factory service will then have two other services in its dependency list, one for each of the proposed functionality features that need to implement a common interface and supply a method to call to do the work. Your component then calls the factory to ‘resolve’ the correct service and then calls the implemented method. So let’s add that up: 1 component, 1 factory, 2 services, and 1 interface… all for two buttons.

The Fix

Remember how I said that UI is built from components? Some components can be very similar and share templates and even can extend classes to share functionality. What I proposed was to look at this from a component perspective and not how to solve this with services.

First, we can create two separate components. The cool thing about this is that the functionality from those two separate services mentioned above can be moved to these components. Then, in your parent component template, just conditionally show the correct button using ngIf. Any common functionality can be in an abstract class that both button component classes can extend. So there you go: 3 components and maybe an abstract class.

What is better about this you might ask? Well, for starters, in this post, I mentioned that services are meant to be singletons. Now, they don’t have to always be, but the idea is that if you are going to have multiple possible instances of something, such as buttons, they should be in instances of components. The buttons in this scenario are to be on cards that appear in a list where each card will have one of the buttons based on its type.

The next point is that the factory pattern of resolving services rather than just using components adds additional layers of complexity. When you look at this from a component structure view, you can see that this is nothing more than buttons that have differing functionality on their interactions. That functionality can be self contained within their component classes which is the whole point of components to begin with.

The End?

I’m all for keeping things simple. Every time I see this long chain of unnecessary services and factories and bridge services and adapters, I start to loose my mind. Someone clearly has too much time and would rather add more lines of code than make their implementations simple for others to follow. And that is what gets me most. Even if you were the only developer looking at your code, make it easy to understand and follow. Keep it simple.

Component architecture is something that shouldn’t be too complicated. If you imagine everything as a component and build your components with other components, you eventually have an application. This idea is not just specific to Angular, either. Web components, React, Vue.js, and others are all about building complex things out of smaller, more isolated things.

Starting to build out features around services becomes problematic very easily. Services can be reused, but not the same way a component can. Think of components as a rubber stamp and every time you need a new instance, you stamp a new one. Services are more like the washers and dryers at a laundromat. You can’t build something with them and everyone gets to use them. So, don’t use them for everything and learn to rely on your templates and components.

--

--

Ryan Mackey-Paulsen

Web App Developer, Web Component Enthusiast, Musician, Human