Adding release toggles to an Angular app

17 April 2019 by Appknobs

Let's add a release toggle

This tutorial is adapted from our previous React post.

React developer? Check out our adding release flags to React guide!

When you're doing trunk-based development whatever is in your main branch - usually master - is pushed to production. At the same time, you might want to use short-lived feature branches, add small improvements at a time and integrate (merge) often. To prevent half-finished features appearing in production you will want to use release toggles. These toggles - also known as release flags - will allow you to deploy, demo and end-to-end test a feature under development by select users but keep it hidden from anyone else.

It is a very simple concept but comes with a few difficulties if you try to implement it from scratch. Hence we're going to use two open source NPM packages from Appknobs to get the job done super fast: @appknobs/angular for the UI and @appknobs/cli for the command line.

Create a new project (optional)

We assume you have a working Angular 7 app ready for a new release toggle. If you need a quick sandbox, generate one using

npm install -g @angular/cli
ng new my-sandbox --defaults

or with Yarn:

yarn global add @angular/cli
ng config -g cli.packageManager yarn
ng new my-sandbox --defaults

Install dependencies

In your project's folder, install @appknobs/angular, @appknobs/client and @appknobs/cli:

npm install @appknobs/angular @appknobs/client && npm install -D @appknobs/cli

or

yarn add @appknobs/angular @appknobs/client && yarn add -D @appknobs/cli

Add a release toggle

@appknobs/angular comes with a declarative feature toggle component <ak-feature>. After you wrap a section of your application in <ak-feature name='...'><YourSection /></ak-feature> it becomes a managed feature and so you can toggle the release without code changes.

It's up to you to select a part of your UI to hide behind a toggle. If you're using the sandbox, open src/app/app.component.html and change it to

<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">

  <!-- Wrap your feature under development in <ak-feature> -->
  <ak-feature name="sandbox-message">
    <h1>I'm using release toggles in Angular!</h1>
  </ak-feature>
</div>

This code hides <h1>I'm using release toggles in Angular!</h1> behind a release toggle. Yes, it's a bit simplistic, but works nicely as an example. The <ak-feature> component can wrap any part of your UI hierarchy - so it's flexible and lets you cater for complex scenarios.

Please note once a feature is managed it is hidden by default. So your message won't show up just yet.

Feature flag autodiscovery

Use @appknobs/cli - the command line interface to Appknobs - to let the feature management service know about your release flag. With Yarn you can simply run yarn knobs to invoke it, otherwise, add a line to your package.json...

  "scripts": {
    "knobs": "knobs"
  }

… and run npm run knobs. Installing @appknobs/cli as a global package or running npx @appknobs/cli also works. For the examples below we assume it's a global package.

To make your life easier, Appknobs can look at your codebase, find & register all feature flags automatically. No need to manually copy-paste.

Invoke knobs parse src/ from the top level of your project and the tool will guide you through the process:

$ knobs parse src

You need to log in before you can upload feature flags from your project

? Would you like to log in or register now? …
  Log in
❯ Register
  Quit

Basically, you need to select Register, enter your email and a password, press enter:

App name: my-sandbox
App ID: DfXPWwujs4YxZc2~Ay8~9
Framework: auto-guessing

Found the following feature flags:
👉 sandbox-message

👍 sandbox-message saved

That's it 👏

Your release toggles are discovered and recorded in the Appknobs service automagically.

Get your App ID

Please note your App ID as you'll need it soon. To find it later, run the following command:

$ knobs app-info

✔ App name: my-app-xxx
✔ appID: TfXPkjh3ysHYxZc2~Ay8~9

Get your API key

You will need an API key to access Appknobs services from your app.

CLI is at your service again:

$ knobs apikey

✔ Your API key is: 62zYKyP8f8sAqxpPoYAcm and is valid until Mon May 13 2019

💡TIP: You can always go to our web console at https://console.appknobs.io/ to find this information.

Connect to Appknobs service

To ensure each feature toggle "flips" when needed, we provide a service that propagates changes to all <ak-feature> automatically.

In the service configuration, you inject the service client that will fetch the available feature toggles of your app at runtime. You will need your appId and the apiKey from before.

Finally, you send the runtime context - e.g. username, hostname, cookie values, etc. - to the service to make the decision on the state of the app feature flags. The content of the context payload is 100% up to you. The following example is quite trivial but works for now and allows you to keep experimenting. Find out more about the payload and conditions in our previous blog post.

💡TIP: Check out the @appknobs/angular and @appknobs/client documentation to learn about advanced topics or take a look at our code examples in the appknobs/appknobs-examples repo.

For the sandbox example, the src/app/app.module.ts needs to be changed like this:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

// Import the Appknobs modules
import { newBrowserClient } from '@appknobs/client';
import { AppknobsModule} from '@appknobs/angular';

// Configure the client
const appknobsClient = newBrowserClient({
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_API_KEY'
});

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    // Inject the client
    AppknobsModule.forRoot({client: appknobsClient})
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Fetching the feature list

You can fetch the list of enabled features any time. A quick & simple solution is to do it once at startup, but of course, this can be repeated anytime during the application lifecycle.

Inject AppknobsService into app.component.ts and make the call:

import { Component, OnInit } from '@angular/core';

import {AppknobsService} from '@appknobs/angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-sandbox';

  private appknobs = null;

  constructor(appknobs: AppknobsService) {
    this.appknobs = appknobs;
  }

  ngOnInit() {
    // A quick-and-easy way to toggle features by deployment target:
    this.appknobs.evaluate({hostname: document.location.hostname});
  }
}

Start your app with

ng serve

Your code is ready

As mentioned before, the thinking behind release toggles is that you can change the visibility of a feature without code changes. Since the "sandbox-message" feature is now managed, let's head over to the web console at https://console.appknobs.io/ and set the conditions.

💡TIP: knobs console will open the web UI

There is a detailed guide to the web console which you can refer to if needed. The steps are quite simple:

  • Visit https://console.appknobs.io/
  • Log in with your username and password
  • Under your app - "my-sandbox" in our example - click Edit features
  • Under the feature you've defined - "sandbox-message" in our example - click Edit conditions

In the condition form, let's add:

  • hostname as property
  • Equal to as predicate
  • localhost as argument

— and save.

Done

Reload your app and enjoy your amazing message! 🥇

feature visible

Try setting the context payload in app.component.ts to something else, e.g. {hostname: 'example.com'} and see what happens.

Note: evaluation is cached for 1 minute by the payload, so changes made on the Console might take a few seconds to be visible in the app.

Hopefully, this guide allows you to get started on a more productive, trunk based development journey using release toggles. Please share if you liked it or let us know if we missed something!

Appknobs is feature flags without the work
Read our blog, Twitter and newsletter for tips, updates, tutorials and articles.