Consuming .NET Feature Flags within an Angular Application
In a previous post Feature Flags in .NET, from simple to more advanced, we discussed some ways to implement feature flags in a .NET Core application. To give the best user experience, these should be consumed by the front-end application as well to hide unreleased features. Within this post, I will show how to consume these feature flags within an Angular application.
The initial setup of feature flags is a one-time task, but once that's done they provide a lot of flexibility and control over features that are released to your users. Feature flags allow teams to decouple feature deployment from code deployment, and enable the possibility to enable a feature to a subset of users. From a DevOps perspective, they also ease the process of rolling out features incrementally without the need for feature branches that need to be synchronized.
.NET API Endpoint link
In order for a front-end application (Angular in our case) to consume the feature flags, the flags need to be exposed through an API endpoint.
The endpoint reads all the feature flags and iterates over them to verify which ones are enabled or disabled. When a feature is enabled, it is added to a list of enabled features, which is returned to the client.
Next, the feature flags can be retrieved by the Angular application.
The FeaturesService
is just a very simple service that retrieves the feature flags from the API endpoint.
In a real-world application, you might want to turn this into a robust service with some helper methods, error handling, caching, or other features to this service (or NgRx Store).
Another implementation can just be an Injection Token wrapper around the features service.
Feature Flag Guard link
To prevent users from accessing features that are disabled, we can create a guard that checks if the feature is enabled or not. When the user tries to navigate to a route that requires a feature that isn't enabled, the guard cancels the navigation or redirects the user to a different route.
CanActivate
& CanActivateChild
link
The first option is to create a guard that adheres to the CanActivateFn
type.
This guard can be used for entirely new features that are not yet released.
The implementation of the guard checks the state of a feature using the data
property of the requested route (we'll see how this can be configured next).
Within the example below, the guard checks if the feature is enabled, if it is, the navigation is allowed, otherwise the user is redirected to the root route.
The guard can be set while defining the routes.
To use the guard for multiple routes, you can also move the guard to the canActivateChild
property of the parent route.
This way, the guard is applied to all child routes, which have the data.feature
property set.
CanMatch
link
The second option is to create a guard that adheres to the CanMatchFn
type.
I find this useful when there's already an older implementation of the feature, and you want the new implementation behind the feature flag.
Instead of preventing the user from accessing a route, or redirecting the user to a different route when the feature condition is not met (guard returns false
), the behavior of the guard skips the current navigation and continues to process the next route in the list.
If the condition is met (guard returns true
), the navigation to the new page is allowed.
The power of using this guard lies in that it can be used for routes that share the same path, but have different components based on the feature flag.
In the example below, the NewFeatureAComponent
will be loaded when the feature flag FeatureA
is enabled, otherwise the OldFeatureAComponent
is loaded.
Feature Flag Directive link
I like to keep entire pages hidden based on a feature flag, but sometimes it's necessary to hide or show elements within a page. To hide or show elements based on the feature flag, we can create a Structural Ddirective that checks if the feature is enabled or not.
To use the feature
directive, you can add it to an element in the template.
Conclusion link
Feature flags are a powerful tool to control the release of features (progressively) to your users. By exposing the feature flags through an API endpoint, the front-end application can consume these flags and hide or show features based on conditions, e.g. the user's permissions.
In this post, we've seen how to create a service to retrieve the feature flags, how to create a guard to prevent users from accessing pages that are disabled, and how to create a directive to hide or show elements based on the feature flag.
Feel free to update this blog post on GitHub, thanks in advance!
Join My Newsletter (WIP)
Join my weekly newsletter to receive my latest blog posts and bits, directly in your inbox.
Support me
I appreciate it if you would support me if have you enjoyed this post and found it useful, thank you in advance.