Feature Flagging: How We Put Our Angular Features on “Pause” and Became Heroes
Ah, the eternal dance between frontend and backend — like two tango dancers, only one of them is perpetually tying their shoes.

Shamaila Mahmood
April 11, 2025

Ah, the eternal dance between frontend and backend — like two tango dancers, only one of them is perpetually tying their shoes. We frontend folks often find ourselves a couple of steps ahead, right? So, here’s how we stopped waiting for the backend to catch up and just kept dancing — with feature flagging.
The Challenge: Backend’s on a Snail Ride
So, we’re ahead, and the backend is still being brewed like some finely aged wine. We’ve got a brilliant Angular application and we’ve even built some fantastic features like a ‘Dashboard’. But how can we test and mark these “complete” when the backend is still figuring out which shoe goes on which foot?
The Slick Solution: Feature Flagging with Kubernetes ConfigMap
Why wait for someone to tie their shoes when you can just keep dancing? Introducing feature flags. With these bad boys, we can toggle the visibility of our features with the flip of a switch. For our project, we used Kubernetes ConfigMap to help us manage these toggles.
ConfigMap Shenanigans
I created a JSON file, appropriately named feature-flag.json:
{
"canViewDashboard": false
}
For our development cluster, canViewDashboard was set to true. In production, we switched that bad boy to false. This file is the wizard behind the curtain, controlled via ConfigMap in our Kubernetes setup.
The Angular Directive: The Gatekeeper
Here comes our Angular directive, has-feature.directive.ts, the bouncer at the club deciding who gets in and who doesn’t.
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appHasFeature]'
})
export class HasFeatureDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
@Input() set appHasFeature(featureName: string) {
if (featureName === 'canViewDashboard') {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
You can use it in your HTML templates like this:
<div *appHasFeature="'canViewDashboard'">
<!-- Your Dashboard component here -->
</div>
If canViewDashboard is set to true, the bouncer lets you in. Party time! 🎉 If not, you’re sent back home to tie your shoes with the backend team.
I know what you are thinking about the hardcoded “canViewDashboard” in the directive, don’t worry and keep dancing — or here reading.
Reading from ConfigMap: The Frontend’s Crystal Ball
Alright, now you’re probably asking, “Hey, how does our Angular app peek into this Kubernetes ConfigMap to read the future — ahem, I mean, the feature flags?”
Great question, my inquisitive friend! We’ve got some backstage magic to reveal.
In most setups, the ConfigMap is mounted as environment variables or as a volume in your Kubernetes pod. If it’s mounted as a volume, it appears as just another file in a specific directory. Let’s say our feature-flag.json gets mounted at /shared-assets/common-config/feature-flag.json.
Here’s a quick service snippet that reads this file:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class FeatureFlagService {
constructor(private http: HttpClient) {}
getFeatureFlags(): Observable<any> {
// Assuming the ConfigMap is accessible via an internal URL
return this.http.get('/shared-assets/common-config/feature-flag.json');
}
}
And in your directive, you’d likely inject this service to check the values:
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private featureFlagService: FeatureFlagService
) {
this.featureFlagService.getFeatureFlags().subscribe(flags => {
if (flags?.[featureName]) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
});
}
Here the expression featureFlag?.[feaureName] is the key to get rid of hardcoded flag name.
Viola! Now our Angular app can not only dance but also read minds — or at least, read ConfigMaps.
Conclusion: We Danced On
And there we have it. Now our frontend doesn’t just predict the future; it checks it through the Kubernetes crystal ball. We’re dancing, we’re reading minds, and, most importantly, we’re delivering features. When the backend finally shows up, they’ll find us not waiting but celebrating.
So, whenever you find yourself ahead of the backend — or anyone really — remember, don’t just wait up. Put a flag on it and keep dancing!