Feature Toggling in Angular with 20 Lines of Code

Datetime:2016-08-23 02:34:35          Topic: AngularJS  HTML           Share

What is feature toggling?

Feature toggling enables you to toggle features or change your application’s content quickly and without any change to the application source code.

It can be used for various applications such as A/B testing or to display time-limited content such as special offers on an application.

If you want to know more about feature toggling, I recommand this thorough article from Martin Fowler.

While I was building an Angular application, my Product Owner asked me to implement feature toggling on several features.

While there were plenty of nice directives available around, it felt a bit like using a sledgehammer to crack a nut, so I believed I could build a simpler one.

My team wasn’t in charge of the back-end of the application and they had already implemented the admin interface to set the toggles as well as the API to get them when I started.

The API was returning a JSON file that looked like this one:

{
  showSignUpLink: true
}

So my job was to get this JSON file, and use it to show or hide the link to the sign up page on the login one.

Creating a new directive

Ok, first let’s add a call to the API that will get the JSON file with the features:

app.factory('Features', function($resource) {
  $resource('/features');
});

That makes 3 lines of code, that is the minimal setup to get a resource.

Now, we want to hide this link when the ‘showSignUpLink’ attribute of our JSON file is set to false.

To do this let’s create a directive that will take the name of the JSON attribute we have to look for:

app.directive('featureToggle', function(Features) {
  return {
    restrict: 'E',
    scope: {
      featureName: '@'
    },
    template: '<span ng-transclude></span>',
    transclude: true,
    link: function(scope, element, attrs, ctrl, transclude) {
      Features.get().$promise.then(function(response) {
        scope.$parent.dataFeature = response[scope.featureName];
      });
    }
  };
});

All right, now we’re at 3 + 15 = 18 lines.

But what are we doing here?

We are creating a directive that can only be created as an element – i.e. as <feature-toggle> – which has one attribute called featureName and which template is a <span> element that implements ng-tranclude .

So basically everything that is inside the <feature-toggle> element will be inside a <span> once the DOM is rendered. As an example:

<feature-toggle>
  <marquee>I am a forgotten HTML element</marquee>
</feature-toggle>

will become:

<span ng-transclude>
  <marquee>I am a forgotten HTML element</marquee>
</span>

Then, using the link method we can update the DOM inside the directive.

Here, we simply get the ‘Features’ resource and set the ‘dataFeature’ attribute of the directive’s parent scope – i.e. the controller’s scope – to the value stored in the ‘feature-name’ key.

Using the directive in the view

Let’s see why our directive is so awesome by looking at how we will transform our link. So starting from this:

<a href="/signup">Yo sign up here</a>

We do now have that:

<feature-toggle feature-name="showSignUpLink">
  <a href="/signup">Yo sign up here</a>
<feature-toggle>

Now when the controller is loaded, ‘dataFeature’ will be whatever you decided in the controller that renders the view – if you don’t declare it, the link won’t be shown.

Once the directive gets the response from the API, it will change the value of ‘dataFeature’ and the link will appear (or not).

And that’s it! We added 2 more lines and 3 + 15 + 2 = 20 so here we are with our first feature toggle with only 20 lines of code!

Going further: Display the content of the JSON file in the DOM

All right, now let’s do something awesome with our directive.

In the same application, the second feature I was asked to make togglable was the content of the main menu.

Actually it wasn’t a toggle, but more of an admin-editable content. The API was then returning this:

{
  showSignUpLink: true,
  menu: [
    {
      stateName: 'landing',
      label: 'Home'
    },
    {
      stateName: 'posts',
      label: 'Posts'
    },
    {
      stateName: 'categories',
      label: 'Categories'
    },
    {
      stateName: 'users',
      label: 'Users'
    }
  ]
}

Let’s have a look at what the HTML for my menu was looking like before:

<ul class="navbar-nav">
  <li>
    <a>Home</a>
  </li>
  <li>
    <a>Posts</a>
  </li>
  <li>
    <a>Categories</a>
  </li>
  <li>
    <a>Users</a>
  </li>
</ul>

What’s great is that I didn’t have to make any change to my directive at all!

All is in the HTML:

<ul class="navbar-nav">
  <li>
    <a>{{ state.label }}</a>
  </li>
</ul>

Conclusion

This is how the directive of my application actually kinda looks like right now.

I like the fact that it is very simple and yet I can do a bit more than just feature toggling.

If you enjoyed this article, you may also want to check out Sammy Teillet’s one on A/B testing .

I also welcome any comment or suggestion on this article, please let me know if you believe it could be improved.

You liked this article? You'd probably be a good match for our ever-growing tech team at Theodo.

Join Us





About List