Implementing Feature Toggles in an Angular Application
Feature toggles (also known as feature flags) are a powerful technique for enabling or disabling features in your application without deploying new code. This challenge focuses on building a simple feature toggle system within an Angular application, allowing you to dynamically control feature visibility based on a configuration. This is useful for A/B testing, gradual rollouts, and enabling/disabling features for specific user groups.
Problem Description
You need to create a service in Angular that manages feature toggles. This service should allow you to:
- Define Feature Toggles: Store a list of feature toggle names and their corresponding enabled/disabled states.
- Check Feature Toggle Status: Provide a method to check if a specific feature toggle is enabled or disabled.
- Update Feature Toggle Status: Provide a method to update the enabled/disabled state of a feature toggle.
- Persist Configuration (Optional): Ideally, the feature toggle configuration should be persisted (e.g., in local storage) so that the state is maintained across application reloads. This is a bonus, but the core functionality should work without persistence.
Key Requirements:
- The service should be injectable into Angular components.
- The
isFeatureEnabledmethod should return a boolean value indicating whether the feature is enabled. - The
setFeatureEnabledmethod should update the feature toggle state. - The service should be designed to be easily extensible to support more complex toggle logic in the future (e.g., user-based toggles).
Expected Behavior:
- When a feature toggle is initially enabled,
isFeatureEnabledshould returntrue. - When a feature toggle is disabled,
isFeatureEnabledshould returnfalse. - Changes to feature toggle states should be reflected immediately when
isFeatureEnabledis called. - If a feature toggle is not defined,
isFeatureEnabledshould returnfalseby default.
Edge Cases to Consider:
- What happens if you try to enable/disable a feature toggle that doesn't exist? (Should it be created and then updated, or should it throw an error?) For this challenge, creating the toggle if it doesn't exist is acceptable.
- How will you handle potential race conditions if multiple components try to update the same feature toggle simultaneously? (For simplicity, you don't need to implement complex locking mechanisms, but be aware of the potential issue.)
- Consider how the service might be used in a component to conditionally display or hide elements.
Examples
Example 1:
Input: featureToggles = { "new-dashboard": false, "advanced-search": true }
isFeatureEnabled("new-dashboard")
Output: false
Explanation: The "new-dashboard" feature is disabled.
Example 2:
Input: featureToggles = { "new-dashboard": false, "advanced-search": true }
setFeatureEnabled("new-dashboard", true)
isFeatureEnabled("new-dashboard")
Output: true
Explanation: The "new-dashboard" feature is now enabled.
Example 3:
Input: featureToggles = { "new-dashboard": false, "advanced-search": true }
isFeatureEnabled("experimental-feature")
Output: false
Explanation: "experimental-feature" is not defined, so it defaults to disabled.
Constraints
- The solution must be written in TypeScript and compatible with a standard Angular project setup.
- The service should be relatively lightweight and avoid unnecessary dependencies.
- The feature toggle configuration should be stored in memory initially. Local storage persistence is optional but encouraged.
- Performance is not a primary concern for this challenge, but avoid excessively inefficient operations.
Notes
- Consider using a simple object (e.g., a JavaScript object or a Map) to store the feature toggle configuration.
- Think about how you might extend this service to support more complex toggle logic in the future, such as user-based toggles or A/B testing.
- Focus on creating a clean, well-structured, and testable service. While writing unit tests is not explicitly required, consider how you would test the service's functionality.
- The goal is to demonstrate a basic understanding of feature toggles and how they can be implemented in Angular.