The Ultimate Guide to Implementing Feature Flags in Angular Applications

Netanel Basal
Netanel Basal
Published in
5 min readAug 6, 2019

--

After deep-diving into some of the more complex aspects of Angular and TypeScript, I thought it’s about time to dedicate a post to something a little lighter.

A Brief Overview

Feature flagging is a well-known technique that improves development speed and allows teams to test new features before they’re stable. It can be used for several reasons: A/B testing for specific features, deploying a feature to a small target audience to get feedback on it, or continuous code delivery.

In this article, we’ll learn how we can leverage various Angular features in order to prevent entering or viewing prohibited areas. Let’s get started.

Using a Feature Flag Provider

In our application, we use a commercial service for feature flag management, which exposes a GUI, where we can add or update our application feature flags. I won’t mention the service name, as advertising it isn’t the point of this article.

Our backend is responsible for the communication with the provider, and provides us with the user’s features flag values upon login. A typical response would look like this:

Preload the User’s Feature Flags

We need to preemptively fetch the user’s data from the server, and make it available to our components before we allow the user to interact with them. Luckily, Angular makes doing that it a breeze, by exposing the APP_INITIALIZER injection token.

The APP_INITIALIZER provider can take a function that returns a promise, and only when that promise is resolved, Angular will bootstrap the application.

For the purpose of our demo we’ll use Akita, although you can employ any state management solution for this purpose. Let’s quickly scaffold a UserStore:

The getValue() query method returns the current state. In our case, we need the user featureFlags in order to check if we can render the view.

Now, let’s create the UserService:

We expose a getUser method which is responsible for initializing the store with the user’s data via a server request ( in this case it’s simulated).

Now, let’s use our UserService with the APP_INITIALIZER token to load the user’s data before the app loads:

We provide the APP_INITIALIZER with the preloadUser function, which calls the service’s getUser method. This will ensure that the user’s data will be in our store before the application loads.

You can read more about this token in the following article:

Now, that we have the user’s data, we can move forward and create our structural directive.

Creating the *featureFlag Directive

Structural directives are responsible for HTML layout. They shape or reshape the DOM’s structure, typically by adding, removing, or manipulating elements, and that’s exactly what we need.

The featureFlag structural directive will be in charge of displaying a provided template, in a DRY way, based on whether the user is authorized that template. Let’s create it:

A structural directive creates an embedded view from the Angular-generated <ng-template> and inserts that view in a view container adjacent to the directive’s original host element.

We pass the provided flags from the input to the hasFlags() query method, and based on the value it returns, we can determine whether or not we should render the template. Let’s use the directive:

Notice that the directive can support an array of flags. We can even take it one step further and add support for an or condition. Here’s some quick pseudo-code for this functionality:

The can be done through the template directives. You can read more about this syntax in this great blog post.

Let’s move forward and implement the routing guards, which will prevent navigation from unauthorized users.

Implementing the Can Activate Guard

Applications often restrict access to certain areas based on the user’s identity. For that purpose, we can implement a guard which only permits access to authorized users, based on their feature flags.

In the above example we’re checking whether the user has the appropriate feature flag permissions detailed in the route data, in which case we permit the navigation; Otherwise, we redirect the user to the home page.

Implementing a Custom Preload Strategy

Many applications leverage Angular’s lazy load feature in conjunction with the preload option, in order to preload (i.e., download in advance) lazy modules, so that they’ll be available when the user navigates to them.

In our case, we don’t want to preload modules that the user isn’t authorized to view. In such cases, we can implement our own preloadStrategy that provides a way to intercept and determine whether any lazy module should be preloaded.

Let’s see how can we do this:

Similarly to the previous example, in this example, the flags in the route data again dictate whether the user can reach the route. If that’s the case, we return the provided load() function; Otherwise, we return an observable, indicating to the router that the user should be redirected instead.

Implementing the Can Load Guard

We’re not done yet. The previous case doesn’t cover situations where the user directly navigates to the protected URL. For these cases, we need to use the canLoad guard:

Now we’ve made sure that Angular will not allow the lazy loading of a module if the user doesn’t have the required feature flags. In contrast, if we only use the canActivate guard, it would download the module, but prevent navigation.

If from some reason you couldn’t use the APP_INITIALIZER functionality, you can switch to using an observable, listen to the store value, and update the view on its initial setting.

🚀 In Case You Missed It

  • Akita: One of the leading state management libraries, used in countless production environments. Whether it’s entities arriving from the server or UI state data, Akita has custom-built stores, powerful tools, and tailor-made plugins, which all help to manage the data and negate the need for massive amounts of boilerplate code.
  • Spectator: A library that runs as an additional layer on top of the Angular testing framework, that saves you from writing a ton of boilerplate. V4 just came out!
  • And of course, Transloco: The Internationalization library Angular 😀

Follow me on Medium or Twitter to read more about Angular, Akita and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.