DISCLAIMER: This story does not prove a pattern or anti-pattern. It just provides a different point of view.
Hello again, base functionality is an inevitable requirement. I’m going to talk about a different base component approach in the Angular. Most of the examples create a base component and inject services to it. Later, you create components from it. However, internet has many examples that could lead you to write bad code.
Let’s see a common example;
Assume that, every route have inherited from the same base component and the page content loads asynchronously.
So the page’s content must be loaded at
ngOnInit asynchronously. We are calling the base’s function to work things out. So far so good. The code seems clean and legit. Most of the examples on the internet are the same.
Angular projects could be bigger than you might think. As things could get more complex as the project evolves, so base component would require more services and data. For example, BaseComponent could require a filter service, widget service or more different services. Therefore, you must inject these services into all inherited components as well.
As a result you have code repetition, and static analysis tools will report such kind of code as a duplication.
The complex part is too much services and injections. Despite that there exists a much simpler way. You could create a base class with all common properties rather than an angular component.
Angular’s router engine has the
router-outlet component. In the course of interaction with the pages, the events would provide the activated/deactivated component cycle. Rather than requiring a lot of services in the constructor, you can manage them in the events. Let’s see the code
When a route clicked, the activate event will be fired. And, the page service will load the page’s content. By this way, we don’t need to inject the page service into each component. This one is very simple example. I would like to take things further.
However, this could change due to requirements. Assume that, we want to share a common functionality e.g. change page function, or loading indicator. We could use EventEmitter to support such functionalities.
You might want to use a wrapper function to emit the EventEmitter.
An example usage case
As I mentioned before, you might use this.changePageEmitter.emit(‘about’) instead of this.changePage(‘about’). It is just a shortcut.
To sum up, the main point of this story is decrease the code duplication and centralize base functionalities. In my opinion, injecting such common services for page base component requirement is not mandatory. You can manage it within AppComponent. However, the methodology could change with your requirement. I hope you enjoyed it.