This series is intended to provide guidance for new and experienced Angular developers on some common best practices, methodologies, and design practices that will improve the design, organization, functionality, scalability, and maintainability of Angular applications. The series assumes knowledge of the core concepts of Angular and dives into detail on more complex topics that can help take your applications to the next level.
To give some perspective on the intended audience for this series, I can start with a quick review of how this series came to be. I had an engagement with a client that wanted to move their front end development out of MVC applications and into an Angular / REST API architecture. I was to develop the initial applications in the roadmap as the development team attended an Intertech Angular training course and got up to speed on the framework. This series was born out of the time working with the developers and aims to address topics that tend to find their way into most applications that I build, but are beyond the scope of the introductory training courses. Some topics arose from individual features I used in the applications for the client, and others are more generic tools and techniques that came up in our discussions. My hope is that there is something nearly every level of Angular developer can take away from this series to improve their development in Angular.
We start this series with a conversation on architecture. The number one issue I see with new Angular developers is to equate a page of the application to a single component and include all functionality within the component. Properly identifying the purpose of a component and understanding how to interact with child components in a maintainable and testable way is something that can greatly improve the code quality of an application. In this article, we take a large component and demonstrate how to break it down into smaller and more re-usable components that better encapsulate functionality.
One of the most common patterns seen in Angular components is to subscribe to an Observable and display the resulting data in a component. When following the patterns described in the first two articles, applications can easily add some bloated boilerplate code. The async pipe is a powerful tool to keep that to a minimum and I have found not all developers get exposed to async pipe when learning the framework. Along with the general use, we dive into some extended functionality of the ngIf directive in conjunction with the async pipe to quickly and easily create effective display components.
4 – Content Projection vs. Inputs
Most tutorials and training stick with the simple approach of binding data to components through an input. This is a simple to implement and effective way to pass data to a child component. However, when real life requirements arise such as adding links, images, or other styling, this approach quickly hits limitations. This article aims to show the flexibility and power that comes from content projection opposed to (or often in conjunction with) component inputs.
Input, Output, and services are often all that is needed to communicate between components in Angular. However, there a times when using these methods do not provide the control and flexibility needed to provide component interaction. ViewChild and ContentChild provide the ability to directly communicate between components and can be extremely powerful when working with tightly related components. Usage of these tools is often so highly situational that it makes providing examples relevant to the situations you will likely face is quite challenging. Awareness of the capability as a whole is often the major hurdle needed to investigate the implementation for a specific need.
Most Angular components are created by adding a reference directly into a template, however, there are times where the type of component won’t be known ahead of time and will need to be dynamically created. Often this is seen with modal windows, application level alerts, or other event driven messages, but could also occur when multiple copies or instances of a component need to be created. In order to create these components, you will need to take some extra steps and precautions, but it can open the door to far more advanced functionality in an application.
Angular’s developers strongly encourage following the single responsibility principle when creating components and classes. When components grow too large, we should turn to services to help separate complex functionality to improve readability, complexity, and testability of an application. However, there are times when the singleton nature of services can provide unexpected results. This article focuses on the ability to control the scope of Angular providers to provide the desired functionality within an application.
To Be Published Next Week…
Forms are a critical component to most any web application. While most forms can be completed with the standard browser inputs, sometimes a more dynamic or thematic input can make the difference in a user interface. Angular provides the ControlValueAccessor interface to provide developers the tools to seamlessly insert custom built components that can function just as a standard input. But as we will see, the ControlValueAccessor can provide much more than just custom inputs – it can serve as a gateway to better form organization and reusability within an application.
Angular’s reactive forms are a great way to quickly build complex and robust forms. However, the design tends to force developers to build large components that encompass the entire form and can make it challenging to re-use or nest sub-forms efficiently. By changing the way you think about sections of forms and leveraging ControlValueAccessor, it can become easy to build customizable form sections that can easily be shared between many forms in an application. This article heavily relies upon the information in the Control Value Accessor article, so take the time to review that information first.
Angular provides a powerful built in router to emulate traditional web page navigation and display new components when accessing various URLs within the application. However, there are times that the default functionality can get in the way or cause unexpected results in the application. There are various ways to work around some of this functionality, but wouldn’t it be great if we could have some control over the router to make some simple decisions that can greatly improve the functionality of our application without overhead? Let’s look at the RouteReuseStrategy class and find out!
With all the techniques discussed in this series, they open up some challenges from a testing perspective. With some general understanding of the Angular module functionality, we can replace existing components with mock versions that can greatly simplify testing the interactions that arise using the techniques in this series.
Founded in 1991, Intertech delivers software development consulting to Fortune 500, Government, and Leading Technology institutions, along with real-world based corporate education services. Whether you are a company looking to partner with a team of technology leaders who provide solutions, mentor staff and add true business value, or a developer interested in working for a company that invests in its employees, we’d like to meet you. Learn more about us.