Code smells
A code smell in itself is not a mistake, but a symptom of an underlying issue in your code. Let’s take a look at one:
Some developers might state that there’s absolutely nothing wrong with the code above, and I’d agree with them. But I’d also agree with those developers who think it can be improved considerably.
The bottom line is that your code will compile either way because this snippet is not a coding error, but a coding smell, it is giving us a clue where the real problem is: TypeScript Configuration.
It turns out that TypeScript provides a configuration file (tsconfig.json) where you can define absolute paths for imports:
By adding those entries in the paths property, you will be able to switch your import statements to:
Now your codebase is easier to read and easier to refactor.
Identifying code smells and discerning the real issue behind them is not easy. We could have said that the real problem was the folder structure of the application, and while there’s some truth to that statement, it would have been unrealistic to think that import paths would have been simplified as much just by moving files and folders around. TypeScript offers an effective approach regardless of the folder structure.
Are you ready?
We will take a look at a few more code smells and we will try to understand the underlying problem, so that next time you stumble upon them, you know exactly how to deal with them!
Double equal vs triple equal
Our next code smell is strictly (pun intended) related to JavaScript. As of today, I’ve read countless tweets, articles, and opinions around the use of the double equal vs triple equal in JavaScript. We can safely say that the matter is settled, but what happens when you encounter a codebase like this:
What’s the underlying problem revealed by this piece of code? Lack of JavaScript knowledge or lack of JavaScript linters?
In reality, your team will often have members whose expertise is not high enough to know the difference – let’s say juniors. Other times you will have members who know the difference but make typos because they’re coding really fast – let’s say seniors.
Both scenarios are plausible, these things happen, and it’s ok. What’s not okay is not having the machine fix it, because machines can, through linters.
Tools like Prettier or ESLint do a terrific job when it comes to formatting JavaScript, but there are numerous options for you pick, customize and apply. The end result should look like this:
Property Binding
Property Binding is one of the most used features of Angular, it is essential to display information in the DOM, but what happens when you find something like this:
You’ll immediately notice something strange, but what is it?
If you try to run this code, it will work perfectly, yet there’s an underlying problem with it. The developer who wrote this snippet (which happens to be me) might have overlooked how Change Detection works when using Property Binding.
It turns out that when you are passing a scalar value to a property, as opposed to a variable, you don’t need Change Detection running over and over to check if the property value has changed. Why? Because it’s not a variable, but a constant (a string, a number, or a boolean directly hardcoded in the HTML).
In such cases, you can get rid of the square brackets entirely:
While the performance improvement is insignificant, on larger codebases you might notice a positive difference.
Loading Speed
Sometimes you are working on pages that look like this:
As you can see, there are plenty of components. Therefore, every time the user opens the website it takes a while to load. Where is the code smell?
Reality is that websites often have lots of components and modules, and if it is a business requirement, there’s not much you can do about it, but you DO have control over how to serve those modules and components.
A popular approach is to serve resources on-demand, as opposed to eagerly loading all of them. In Angular, this strategy is called Lazy Loading, and it allows you to serve only the modules the user needs at a given time, reducing the latency of loading the website the first time.
You won’t believe how common it is for Angular developers to forget about implementing performance strategies. I’ve reviewed many codebases over the last 2 years, and Lazy Loading one of the most skipped features. This is a visual representation of how a performance strategy would look like:
Injecting services
Services are one of the core elements of Angular, they provide structure to your application and allow you to decouple logic, making your codebase more maintainable. They are easy to use thanks to Dependency Injection.
And while injecting services in a constructor seems like a harmless thing to do, sometimes you find more complex scenarios:
Some would say that the snippet above is completely normal, and again, I’d agree with them. What I am concerned about is not the amount of services injected, but what it means. I’m concerned about the code smell.
If a given component has 10 or more services injected, chances are that it is not a small component, it is likely a large overly complex component that is doing too much.
Anyone could wrap a few services into a single service, like a facade. But it wouldn’t make the component simpler, it would at most remove a few lines of code, but the component’s responsibility would remain high, just like when you have an employee who is taking part in every decision, not sharing the knowledge and never delegating responsibilities. It becomes a liability.
In cases like this you need to review your architecture and figure out why this component is doing too much. A redesign might help you reduce the amount of services you need to inject:
Something like this is less suspicious and chances are that the component follows the single responsibility principle.
That’s it for now! Later we will share more code smells in Angular applications and how to deal with them! Thanks for reading and stay tuned!