Skip to content

This Dot Blog

This Dot provides teams with technical leaders who bring deep knowledge of the web platform. We help teams set new standards, and deliver results predictably.

Newest First
Tags:Angular
Overview of the New Signal APIs in Angular cover image

Overview of the New Signal APIs in Angular

Google's Minko Gechev and Jeremy Elbourn announced many exciting things at NG Conf 2024. Among them is the addition of several new signal-based APIs....

Using HttpClient in Modern Angular Applications cover image

Using HttpClient in Modern Angular Applications

With all the new changes to Angular and RxJS, using HttpClient can get confusing and you can get lost in outdated tutorials. This blog post guides you through the process of creating a service that exposes http calls and using it in a component....

4 Angular Component Libraries That are Perfect for Beginners cover image

4 Angular Component Libraries That are Perfect for Beginners

For beginners starting with Angular, the journey can feel daunting, especially when it comes to setting up projects from scratch. However, there is a range of outstanding Angular component libraries that alleviate this initial hurdle: ready-made toolkits, empowering newcomers to start building Angular applications without the complexities of bootstrapping their projects. Let’s take a look! Angular Material Angular Material is a UI component library by Google for Angular applications. It provides a variety of pre-built components following the Material Design guidelines, offering customization options, responsive design, and accessibility features. It's seamlessly integrated with Angular and offers extensive documentation and community support. NG-ZORRO NG-ZORRO is an Angular UI component library based on Ant Design by Alibaba. It offers a variety of customizable components for building modern web applications. With seamless Angular integration, responsive design, and accessibility features, NG-ZORRO simplifies development while following Ant Design principles. NG Bootstrap NG Bootstrap is a library for Angular developers to easily incorporate Bootstrap components into their applications without relying on jQuery. It offers Angular-specific directives and components, ensuring compatibility and performance within Angular projects while maintaining Bootstrap's responsive design and customization options. Clarity Design System Clarity is an open-source design system by VMware that offers a set of Angular components for building enterprise-scale applications. It provides components specifically tailored for data-centric applications, dashboards, and complex user interfaces. Clarity Design System emphasizes clarity, consistency, and usability in its components. The beginner’s journey can be both exhilarating and challenging. However, with the advent of powerful component libraries like Angular Material, NG-ZORRO, NG Bootstrap, and the Clarity Design System, the path becomes significantly smoother. These libraries offer pre-built components and design systems that eliminate the need to bootstrap projects from scratch. As beginners embark on their Angular journey, these libraries provide a sturdy foundation, allowing them to dive into development with confidence. By harnessing the capabilities of these libraries, beginners can not only expedite their learning curve but also craft exceptional Angular applications with ease and efficiency....

QR Code Scanning & Generation cover image

QR Code Scanning & Generation

QR codes provide a very valuable way of sharing information with users, and many applications rely on them for various purposes....

Angular 17: Continuing the Renaissance cover image

Angular 17: Continuing the Renaissance

Dive into the Angular Renaissance with Angular 17, emphasizing standalone components, enhanced control flow syntax, and a new lazy-loading paradigm. Discover server-side rendering improvements, hydration stability, and support for view transitions....

You Don't Need NgRx To Write a Good Angular App cover image

You Don't Need NgRx To Write a Good Angular App

NgRx is a great tool that allows you to manage state and side effects in Angular applications in a Redux-like manner. It streamlines state changes with its unidirectional data flow, and offers a structured approach to handling data and side effects. Numerous posts on our blog detail its strengths and affiliated techniques. Some Angular developers even argue that incorporating NgRx is imperative once an app expands beyond two features. While NgRx can undoubtedly enhance an Angular application or library by simplifying debugging, translating business logic into code, and improving the architecture, it does present a steep learning curve. Despite the provocative title, there is some truth to the statement: your app or library may indeed not need NgRx. Surprisingly, I successfully developed a suite of enterprise Angular libraries over five years without involving NgRx. In that project, we decided to opt out of using a state management library like NgRx because of its steep learning curve. Developers with varying levels of Angular expertise were involved, and the goal was to simplify their experience. My bold assertion is that, with careful consideration of architectural patterns, it is entirely possible to develop a robust app or library using only Angular, without any third-party libraries. Employing select design patterns and leveraging Angular's built-in tools can yield a highly maintainable app, even without a dedicated state management library. Having shared my somewhat audacious opinion, let me now support it by outlining a few patterns that facilitate the development of a maintainable, stateful Angular application or library without NgRx. Services and the Singleton Pattern Services provided in root or a module yield a shared instance across the entire app or module, effectively rendering them singletons. This characteristic makes them ideal for managing and sharing state across components without requiring a dedicated state management tool like NgRx. Particularly, for small to medium-sized applications, a "state service" can be a straightforward and effective alternative to a comprehensive state management solution when implemented correctly. To accurately implement state in a singleton service, consider the following: - Restrict state data to private properties and expose them only through public methods or observables to prevent external mutations. Such a pattern safeguards the integrity of your state by averting unauthorized modifications. - Utilize BehaviorSubjects or signals to enable components to respond to state changes. Both BehaviorSubject and SettableSignal retain the current value and emit it to new subscribers immediately. Components can then subscribe to these to receive the current value and any subsequent updates. - Expose public methods in your service that manage state modifications to centralize the logic for updating the state and incorporate validation, logging, or other necessary side effects. - When modifying state, always return a new instance of the data rather than altering the original data. This ensures that references are broken and components that rely on change detection can accurately detect changes. Good Component Architecture Distinguish your UI components into stateful (containers) and stateless (presentational) components. Stateful components manage data and logic, while stateless components merely receive data via inputs and emit events without maintaining an internal state. Do not get dragged into the rabbit hole of anti-patterns such as input drilling or event bubbling while trying to make as many components presentational as possible. Instead, use a Data Service Layer to provide a clean abstraction over backend API calls and handle error management, data transformation, caching, and even state management where it makes sense. Although injecting a service into a component technically categorizes it as a "smart" component, segregating the data access logic into a separate service layer ultimately enhances modularity, maintainability, scalability, and testability. Immutability A best practice is to always treat your state as immutable. Instead of modifying an object or an array directly, you should create a new copy with the changes. Adhering to immutability ensures predictability and can help in tracking changes. Applying the ChangeDetectionStrategy.OnPush strategy to components whenever possible is also a good idea as it not only optimizes performance since Angular only evaluates the component for changes when its inputs change or when a bound event is triggered, but it also enforces immutability. Change detection is only activated when a different object instance is passed to the input. Leveraging Angular Router Angular's router is a powerful tool for managing application state. It enables navigation between different parts of an application, allowing parameters to be passed along, effectively using the URL as a single source of truth for your application state, which makes the application more predictable, bookmarkable, and capable of maintaining state across reloads. Moreover, components can subscribe to URL changes and react accordingly. You can also employ router resolvers to fetch data before navigating to a route, ensuring that the necessary state is loaded before the route is activated. However, think carefully about what state you store in the URL; it should ideally only contain the state essential for navigating to a specific view of your application. More ephemeral states, like UI state, should be managed in components or services. Conclusion Angular provides lots of built-in tools and features you can effectively leverage to develop robust, maintainable applications without third-party state management libraries like NgRx. While NgRx is undoubtedly a valuable tool for managing state and side effects in large, complex applications, it may not be necessary for all projects. By employing thoughtful design patterns, such as the Singleton Pattern, adhering to principles of immutability, and leveraging Angular's built-in tools like the Router and Services, you can build a highly maintainable and stateful Angular application or library....

A Guide to (Typed) Reactive Forms in Angular - Part III (Creating Custom Form Controls) cover image

A Guide to (Typed) Reactive Forms in Angular - Part III (Creating Custom Form Controls)

So far in the series, we have learned the basics of Angular Reactive forms and created some neat logic to construct and display dynamic forms. But our work is still not done yet. Whether we just want to make our controls look good and enhance them with some markup, or whether we need a more complex control than a simple textarea, input or checkbox, we'll either need to use a component library such as Angular Material Components or get familiar with the ControlValueAccessor interface. Angular Material, by the way, uses ControlValueAccessor in its components and I recommend looking into the source code if you want to learn some advanced use cases (I have borrowed a lot of their ideas in the past). In this post, however, we will build a basic custom control from scratch. A common requirement for a component that cannot be satisfied by using standard HTML markup I came across in many projects is having a searchable combobox. So let's build one. We will start by creating a new Angular component and we can do that with a handy ng cli command: ` Then we'll implement displaying data passed in the form of our FormField class we have defined earlier in a list and allowing for filtering and selecting the options: ` ` > Note: For the sake of brevity, we will not be implementing keyboard navigation and aria labels. I strongly suggest referring to W3C WAI patterns to get guidelines on the markup and behavior of an accessible combo box. While our component now looks and behaves like a combo box, it's not a form control yet and is not connected with the Angular forms API. That's where the aforementioned ControlValueAccessor comes into play along with the NG_VALUE_ACCESSOR provider. Let's import them first, update the @Component decorator to provide the value accessor, and declare that our component is going to implement the interface: ` Now, the component should complain about a few missing methods that we need to satisfy the ControlValueAccessor interface: - A writeValue method that is called whenever the form control value is updated from the forms API (e.g. with patchValue()). - A registerOnChange method, which registers a callback function for when the value is changed from the UI. - A registerOnTouched method that registers a callback function that marks the control when it's been interacted with by the user (typically called in a blur handler). - An optional setDisabledState method that is called when we change the form control disabled state- Our (pretty standard) implementation will look like the following: ` We don't have to update the template a lot, but we can add [disabled]="disabled" attribute on our button and input to disable the interactive UI elements if the provided form control was disabled. The rest of the work can be done in the component's TypeScript code. We'll call this.onTouched() in our closeListbox method, and create a value setter that updates our internal value and also notifies the model about the value change: ` You can check out the full implementation on StackBlitz. Conclusion In this series, we've explored the powerful features of Angular reactive forms, including creating and managing dynamic typed forms. We also demonstrated how to use the ControlValueAccessor interface to create custom form controls, such as a searchable combo box. This knowledge will enable you to design complex and dynamic forms in your Angular applications. While the examples provided here are basic, they serve as a solid foundation for building more advanced form controls and implementing validation, accessibility, and other features that are essential for a seamless user experience. By mastering Angular reactive forms and custom form controls, you'll be able to create versatile and maintainable forms in your web applications. If you want to further explore the topic and prefer a form of a video, you can check out an episode of JavaScript Marathon by my amazing colleague Chris. Happy coding!...

A Guide to (Typed) Reactive Forms in Angular - Part II (Building Dynamic Superforms) cover image

A Guide to (Typed) Reactive Forms in Angular - Part II (Building Dynamic Superforms)

In the first blog post of the series, we learned about Angular reactive forms and the data structures behind them. When developing real-world applications, however, you often need to leverage dynamic forms, as writing boilerplate for every form and its specific cases can be tedious and time-consuming. In certain situations, it may even be necessary to retrieve information from an API to construct the forms. In this post, we will go over a convenient abstraction we can create to build dynamic and adaptable forms without repeating boilerplate. The trick is to create a "view model" for our data and use a service to transform that data into a reactive form. I was first introduced to this approach by my friend and former teammate Thomas Duft, and I've been using it ever since. The approach outlined in the linked article worked great with untyped forms, but since now we can get our forms strictly typed, we'll want to upgrade it. And here is where it gets a bit tricky. Remember how I mentioned you shouldn't predeclare your form groups earlier? If you want to recursively create a form from a config, you just have to. And it's a dynamic form, so you cannot easily type it. To solve the issue, I devised a trick inspired by a "Super Form" suggested by Bobby Galli. Assuming we will have interfaces defined for our data, using this approach, we can create dynamic type-safe forms. First, we'll create types for our form config: ` And then we'll create some type mappings: ` And now we can use our types in a service that will take care of creating nested dynamic forms: ` And that's it. Now we can use our FormService to create forms. Let's say we have the following User model: ` We can create a form for this user from config in the following way: ` If we would check the type of userForm.value now, we would see that it's correctly inferred as: ` Outputting the Dynamic Forms To display the dynamic forms, we can write a simple component that takes the FormSection or FormField as an Input() along with our FormGroup and displays the form recursively. We can use a setter to assign either field or section property when the view model is passed into the component, so we can conveniently use them in our template. Our form component's TypeScript code will look something like this: ` And our template will reference a new form component for each section field in case we have passed in a FormSection and it will have a switch case to display the correct control in case a FormField has been passed in: ` That way, we can display the whole form just by referencing one component, such as ` Check out an example on StackBlitz. In the next (and last) post of the series, we will learn about building custom Form Controls....

A Guide to (Typed) Reactive Forms in Angular - Part I (The Basics) cover image

A Guide to (Typed) Reactive Forms in Angular - Part I (The Basics)

When building a simple form with Angular, such as a login form, you might choose a template-driven approach, which is defined through directives in the template and requires minimal boilerplate. A barebone login form using a template-driven approach could look like the following: ` ` However, when working on a user input-heavy application requiring complex validation, dynamic fields, or a variety of different forms, the template-driven approach may prove insufficient. This is where reactive forms come into play. Reactive forms employ a reactive approach, in which the form is defined using a set of form controls and form groups. Form data and validation logic are managed in the component class, which updates the view as the user interacts with the form fields. This approach requires more boilerplate but offers greater explicitness and flexibility. In this three-part blog series, we will dive into the reactive forms data structures, learn how to build dynamic super forms, and how to create custom form controls. In this first post, we will familiarize ourselves with the three data structures from the @angular/forms module: FormControl The FormControl class in Angular represents a single form control element, such as an input, select, or textarea. It is used to track the value, validation status, and user interactions of a single form control. To create an instance of a form control, the FormControl class has a constructor that takes an optional initial value, which sets the starting value of the form control. Additionally, the class has various methods and properties that allow you to interact with and control the form control, such as setting its value, disabling it, or subscribing to value changes. As of Angular version 14, the FormControl class has been updated to include support for typed reactive forms - a feature the Angular community has been wanting for a while. This means that it is now a generic class that allows you to specify the type of value that the form control will work with using the type parameter . By default, TValue is set to any, so if you don't specify a type, the form control will function as an untyped control. If you have ever updated your Angular project with ng cli to version 14 or above, you could have also seen an UntypedFormControl class. The reason for having a UntypedFormControl class is to support incremental migration to typed forms. It also allows you to enable types for your form controls after automatic migration. Here is an example of how you may initialize a FormControl in your component. ` Our form control, in this case, will work with string values and have a default value of "John Doe". If you want to see the full implementation of the FormControl class, you can check out the Angular docs! FormGroup A FormGroup is a class used to group several FormControl instances together. It allows you to create complex forms by organizing multiple form controls into a single object. The FormGroup class also provides a way to track the overall validation status of the group of form controls, as well as the value of the group as a whole. A FormGroup instance can be created by passing in a collection of FormControl instances as the group's controls. The group's controls can be accessed by their names, just like the controls in the group. As an example, we can rewrite the login form presented earlier to use reactive forms and group our two form controls together in a FormGroup instance: ` ` Notice we have to specify a formGroup and a formControlName to map the markup to our reactive form. You could also use a formControl directive instead of formControlName, and provide the FormControl instance directly. FormArray As the name suggests, similar to FormGroup, a FormArray is a class used to group form controls, but is used to group them in a collection rather than a group. In most cases, you will default to using a FormGroup but a FormArray may come in handy when you find yourself in a highly dynamic situation where you don't know the number of form controls and their names up front. One use case where it makes sense to resort to using FormArray is when you allow users to add to a list and define some values inside of that list. Let's take a TODO app as an example: ` In both of the examples provided, we instantiate FormGroup directly. However, some developers prefer to pre-declare the form group and assign it within the ngOnInit method. This is usually done as follows: ` If you try the above example in your IDE, you'll notice that the type of this.form.value is no longer inferred, and you won't get autocompletion for methods such as patchValue. This is because the FormGroup type defaults to FormGroup. To get the right types, you can either assign the form group directly or explicitly declare the generics like so: ` However, explicitly typing all your forms like this can be inconvenient and I would advise you to avoid pre-declaring your FormGroups if you can help it. In the next blog post, we will learn a way to construct dynamic super forms with minimal boilerplate....

A Guide to Custom Angular Attribute Directives cover image

A Guide to Custom Angular Attribute Directives

Discover the power of Angular attribute directives and learn how to create your own custom directives with this interactive guide from This Dot Labs...

How to Create Standalone Components in Angular cover image

How to Create Standalone Components in Angular

Delve into the power of Angular's component-based architecture, focusing on standalone components that facilitate modularity and reusability....

Introduction to Directives Composition API in Angular cover image

Introduction to Directives Composition API in Angular

In version 15, Angular introduced a new directives composition API that allows developers to compose existing directives into new more complex directives or components. This allows us to encapsulate behaviors into smaller directives and reuse them across the application more easily. In this article, we will explore the new API, and see how we can use it in our own components. All the examples from this article (and more) can be found on Stackblitz here. Starting point In the article, I will use two simple directives as an example * HighlightDirective - a directive borrowed from Angular's Getting started guide. This directive will change an element's background color whenever the element hovers. ` Fig. 1 * BorderDirective - a similar directive that will apply a border of a specified color to the element whenever it hovers ` Fig. 2 We can now easily apply our directives to any element we want ie. a paragraph: ` Fig. 3 However, if we wanted to apply both highlighting and border on hover we would need to add both directives explicitly: ` Fig. 4 With the new directives composition API, we can easily create another directive that composes behaviors of our 2 directives. Host Directives Angular 15 added a new property to the @Directive and @Component decorators. In this property, we can specify an array of different directives that we want our new component or directive to apply on a host element. We can do it as follows: ` As you can see in the above example, by just defining the hostDirectives property containing our highlight and border directives, we created a new directive that composes both behaviors into one directive. We can now achieve the same result as in Fig. 4 by using just a single directive: ` Fig. 5 Passing inputs and outputs Our newly composed directive works nicely already, but there is a problem. How do we pass properties to the directives that are defined in the hostDirectives array? They are not passed by default, but we can configure them to do so pretty easily by using an extended syntax: ` Fig. 6 This syntax takes exposes the "inner" directives\ color input from the HighlightAndBorderDirective`, and passes them down to both highlight and border directives. ` Fig. 7 This works, but we ended up with a border and highlight color both being blue. Luckily Angular's API allows us to easily redefine the properties' names using the : syntax. So let's remap out properties to highlightColor and borderColor so that the names don't collide with each other: ` Fig. 8 Now we can control both colors individually: ` Fig. 9 We could apply the same approach to mapping directive's outputs eg. ` Fig. 10 or ` Fig. 11 Adding host directives to a component Similarly to composing a directive out of other directives, we can apply the same approach to adding behavior to components using hostDirectives API. This way, we could, for example, create a more specialized component or just apply the behavior of the directive to a whole host element: ` Fig. 12 This component will render the paragraph, and apply both directives' behavior to the host element: ` Fig. 13 Just like we did for the directive, we can also expose and remap the directives inputs using the extended syntax. But if we would like to access and modify the directives inputs from within our component, we can also do that. This is where Angular's dependency injection comes in handy. We can inject the host directives via a constructor just like we would do for a service. After we have the directives instances available, we can modify them ie. in the ngOnInit lifecycle hook: ` Fig. 14 With this change, the code from Fig. 13 will use lightcoral as a background color and red as a border color. Performance Note While this API gives us a powerful tool-set for reusing behaviors across different components, it can impact the performance of our application if used excessively. For each instance of a given composed component Angular will create objects of the component class itself as well as an instance of each directive that it is composed of. If the component appears only a couple of times in the application. then it won't make a significant difference. However, if we create, for example, a composed checkbox component that appears hundreds of times in the app, this may have a noticeable performance impact. Please make sure you use this pattern with caution, and profile your application in order to find the right composition pattern for your application. Summary As I have shown in the above examples, the directives composition API can be a quite useful but easy-to-use tool for extracting behaviors into smaller directives and combining them into more complex behaviors. In case you have any questions, you can always tweet or DM me at @ktrz. I'm always happy to help!...