E-commerce applications can take on many forms. Whether they're retail, goods exchange, or an auction website, online commerce is becoming more common than offline. Modern front-end frameworks, such as Angular and React, provide the tools necessary for creating fast and responsive single-page e-commerce apps. In this article, we'll delve into the process of using the LaunchDarkly JavaScript SDK to introduce new functionality in an AngularJS e-commerce application.
E-commerce + real-time feature flags
With the growing demand for quicker, more reliable releases, development teams should consider having feature flags in their toolbox. The user-facing nature of web stores facilitates the perfect environment in which feature flagging promotes granular control and feature visibility. Some of the use cases include:
- Rolling out storewide discounts with minimal overhead
- Gradually rolling out new checkout and payment systems and assessing performance and revenue impact before fully rolling out
- Allowing customers to personalize their shopping experience
- Serve promotions and recommend items based on a customer's preferences and previous behavior
Having these implementations wrapped in feature flags creates a safety net for catching even the smallest discrepancies, such as outdated seasonal discounts and conflicting pricing rules.
Using feature flags in an e-commerce environment
Feature flags prove to be incredibly valuable in an online store. In such a fast-paced environment, product pricing is constantly changing, with various discounts and markdowns being put into effect. We've created an open-source Angular application (based on Code Project's ShoppingCart) demonstrating the power of feature flagging in an e-commerce application. In our app, we implement a multivariate feature flag named “store-discount” which returns a number indicating a percentage discount on all products.
Integrating LaunchDarkly with Angular
To integrate LaunchDarkly feature flags with our Angular app, we will need to begin by creating a service which will initialize the LaunchDarkly client. Using Angular's dependency allows us to return a promise which will resolve when the client has prepared its initial set of feature flags.
storeApp.factory('LaunchDarklyService', ['', '', function(, ) { var initLD = function () { var deferred = .defer(); var ldclient = LDClient.initialize( 'YOUR-ENVIRONMENT-KEY', {key:'test', anonymous:true}) ldclient.on('ready', function () { deferred.resolve(ldclient) }) return deferred.promise } return {initLD: initLD }}])
Now, our main controller can use our newly defined LaunchDarklyService to initialize the feature flag client, and save it in the application's root scope (a set of data available to any page in our app) once the client is ready.
function storeController(, , , DataService, LaunchDarklyService, ngDialog) { ... // initialize the LaunchDarkly client if (.ldclient === undefined) { LaunchDarklyService.initLD().then(ldclient => { .ldclient = ldclient .discount = .ldclient.variation('store-discount') // listen for changes in the store-discount feature flag, and update the discount accordingly .ldclient.on('change', function () { ngDialog.open({ template: 'modal.html', className: 'ngdialog-theme-default', scope: }) .discount = .ldclient.variation('store-discount') .() }) }) } else { .discount = .ldclient.variation('store-discount') } ...}
Also, the controller starts a listener within the LaunchDarkly client to change the current value of the store's universal discount whenever a flag is modified. This allows the app to dynamically render new information. In our case, prices are slashed, and a notification pops up, alerting the user of “amazing new discounts!” This is achieved by using an ngIf directive to slash through the original price, if a discount has been applied.
... {{product.price | currency}} {{product.price-product.price*discount | currency}} ...
Try it out
This demo was built on top of Code Project's ShoppingCart, and the code is available for your use on GitHub. You can checkout the JavaScript SDK functionality here.
---
Primary Contributor: Arnold Trakhtenberg, Engineering Content Consultant at LaunchDarkly