Why Class/Component inheritance in your Angular app might not be good

13,285 reads

When developing your applications you inevitably come across situations where you need to create functionalities/features or even functions which are similar, but spreaded over multiple components or even modules. This means you have to find a solution for code reusability to keep your code maintainable. In Angular, and Javascript applications in general, there are many patterns and solutions to set this up. As Angular is entirely Class based, inheritance could be a solution. Here’s why that might not be the best solution.

Photo by Kalen Emsley on Unsplash

The problem with inheritance in Angular

For you who don’t know what inheritance is. Inheritance is a way to extend your code with functionalities from other code. Basically the same as parents with their children. All children inherit some characteristics from their parents and use that in their life.

Inheritance itself is not bad. As i mentioned earlier, you probably do this to increase code reusability. Code reusability is good as this also increases maintainability. Why is it a problem then? well…

Inheritance results in abstracting away implementation details

And that makes your code harder to understand. For you as the author everything might be perfectly clear, but will it still be clear after a few months? And what if another colleague, or worse, a new colleague picks up the code. I bet it will be a lot harder to see how everything works as methods could potentially be called multiple levels deep and you really have to dig in to see where everything is and how it all correlates.

In the example below we have a situation where we need to display multiple models with different unmappable datasets. This means each modal will be a separate component as the template is too different to put everything in one component.

The modal components use inheritance to encapsulate reusable modal logic. You could think of filtering, sorting, managing selections, saving etc. If you open the modal-companies.component.ts you don’t immediately see this all this logic. As the inheritance is only one level deep and this is an easy example, it’s still sort of manageable. But things become really hard when you go into multiple levels of inheritance and logic gets more complicated. While things could become quite flexible and reusable you have to go trough multiple files to get an understanding of what is actually happening.

If you would refer back to my example about the child that inherits characteristics from their parents, it works exactly the same. If you know the kid without knowing the parents you might not be able to place some characteristics. You would have to do dig in and see or meet the parents in order to understand why the kid is what it is.

With code you don’t want that. In the ideal world, you want to quickly see/scan it, understand it, fix your stuff and move on. This is why I prefer a, more declarative, what you see is what you get solution over class inheritance.

What you see is what you get

What you see is what you get could be achieved by placing your code in a Service or a utility file. You can then call the Service from your Component which does the work for you. The nice thing is that when you open your component you immediately see which Services are injected, which functions of those services are called and what is returned by those functions.

As you can see we have removed the inheritance and moved the code that was in the modal.ts class to the modal-helper.service.ts service. Now, what i really like about this approach is that when you open one of the component files, you immediately see what functionalities that component has en where you can find it.

The drawback

Just like class inheritance has a drawback, the above solution also has a drawback and that is that you have to write more code. However more code is not necessarily bad, especially in this case, as the above solution helps you to make your code easier to understand. And in my opinion, understandable code is good code.

Conclusion

While this is a somewhat opinionated post. The takeaway should be that code should be written in a way that it has the highest form of re-usability, maintainability and understandability. You almost always have to find a middle ground there. In that respect, i described a different solution which might suits your needs. Anyway, always remember:

Also check my other articles:

Tags