Angular is an open-source, type-script-based, dynamic, full-featured framework led by google.But one of the most common problems the IT industry faces during software project development is unnecessary code duplication. It happens at all phases of development in big and small companies. And the consequences are oppressive: the process slows down, repetitive modifications, code maintenance gets harder and tedious, introduction to more and more bugs as it is difficult to figure out the places where the code is duplicated.
The reasons are many but we have significant ways to solve them.
In this blog, you’ll come across the problems that occur in developing an angular-based application and seamless solutions to them.
Common causes for code duplication
- At the same time several programmers working on various parts of the same program
- Different pieces of code appear to perform different things, but all do the same job. This type of duplication is difficult to locate and fix.
- Manier times inexperienced programmers would succumb to the urge of copying and pasting the relevant code
Have a Project Idea?
Want to convert your idea into a successful app or website? Schedule your free call with our expert now.
Measures to avoid Code Duplication with Angular Techniques
The angular application consists of multiple agnostic components with customizable HTML mainly dropdowns. This enables the programmers to transfer ng-templates to inputs and customize execution.
Including agnostic components is an alternative method to minimize code duplication and escalate the flexibility of components. When the project gets near to completion, it might have per se 2 million lines of code, In that case, there are numerous dialogues where ng-templates would be required with the same content, duplicated in every parent component which consumed them.
After evaluating those code duplications, they had several traits in common:
- Each ng-template was often tasked with rendering a particular type of object (e.g. it renders an entity of type Country),
- Each ng-template was duplicated within a confined scope
- The components were severely slowed in the application when ng-template was used.
For instance, imagine we are building a simple Angular supermarket. In figure 1, you will see three components, consider them as screens. Those screens contain forms where a user selects a country and/or a product from the dropdown components (grey boxes). The red boxes are ng-templates required for rendering product entities in the dropdowns while the blue boxes are ng-templates required to render country entities in the dropdowns. As can be seen, right away, using ng-templates to customize components is inefficient in terms of code duplication.
When our developers faced such issues, to address them we brought Radek Busa’sapproach into use. A flyweight pattern is used in such cases where performance-intensive/memory-heavy objects are shared between multiple objects that use them.
How flyweight pattern is used?
A client requests a ConcreteFlyweight from FlyweightFactory. In order to save machines resources (CPU/RAM), the FlyweightFactory determines whether to build a new concrete flyweight or reuse an existing Concrete Flyweight. In both cases, the Client gets an instance of ConcreteFlyweight and further uses it per its needs.
How to map our use case to a Flyweight pattern?
- Our business component will be the client
- A component known as template repository will extend Abstract Template Repository which contains ng-template that you want to share in a concrete file.
- Template Pool, a service provided by Flyweight Factory, will contain the Template Repository, which will include templates needed by the business component.
- Some of the templates will be used by the business components, which will transfer them to their child component through @input.
Since words like connection pool and thread pool already exist for doing essentially the same thing but in different ways, but let’s call the angular programming pattern template pool pattern.
It has a very easy usage in business components:
Let’s take a step back and look at it objectively of this approach.
We chose to use a child component containing all of the templates and then transfer the templates to dropdown inputs through a template variable.
As you can see, this is a much more straightforward approach than using Template Pools that depend on services. This approach, subsequently, has several drawbacks, including performance issues when a new child component full of templates is added to the consumer component. that child component will have its own lifecycle, which means that not only will the templates be duplicated (when that component is added to the consumer component template), but it also slightly degrades the performance of the application.
Additionally, while developing data-driven solutions that involve passing ng-templates to properties of data-driven components, this TemplateRef-based solution turns out to be clumsy because it necessitates creating a ViewChild property in a controller and initializing those data-driven solutions within some component where the Template Repository reference is present.
Create the Template Repository
Your custom template repository can, first and foremost, expand AbstractTemplateRepository.
There are few key points to remember while writing repository code:
- Since it is disconnected from Change Detection, the repository should be stateless (that means nothing other than ViewChild TemplateRefs should be in controller member variables)
- Only the ng-templates with template reference variables should be used in the repository’s HTML template.
- “template “/”template should be prefixed/suffixed to the template refs within the repository’s controller, which are annotated by the viewChild decorator. This is implemented to ensure good naming convention( Template Refs without the aforementioned prefix/suffix will not be accessible in the template).
Set the Template Pool Up for Injection
Include a module of your choosing. There’s also the option of declaring a template repository for each lazy module/injector. The forRoot/forChild module factory pattern has been introduced for such use-cases.
Use the Template Pool in Your Components
The Template pool API and initialization are both fully synchronous operations, which is awesome because it eliminates unnecessary phases.
One can even transfer ng-templates to model-driven components inside your Angular services, if desirable:
This is how you can enjoy your ng template without performance overhead.
- Reduce the number of ng-templates that are duplicated,
- A Centralized source of truth for angular components rendering of business entities,
- Template Repositories do not listen to change detection invocations from conventional views due to performance overhead.
In this blog, you came across the problem we handled of our enterprise using a simple yet effective solution we learned from this blog- This Angular Technique Will Significantly Lower Code Duplication in Big Projects.
If you think you’re facing similar issues, do try this out on your projects. If you made some technical improvements that gave tangible results, do let us know.