|
| 1 | +--- |
| 2 | +title: OpenFeature Angular SDK |
| 3 | +slug: angular |
| 4 | +sidebar_label: Angular |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- |
| 8 | +This content has been automatically generated from js-sdk. |
| 9 | + |
| 10 | +Edits should be made here: https://github.com/open-feature/js-sdk |
| 11 | +Once a repo has been updated, docs can be generated by running: yarn update:sdk-docs |
| 12 | + |
| 13 | +Last updated at Tue Sep 17 2024 11:56:09 GMT-0400 (Eastern Daylight Time) |
| 14 | +--> |
| 15 | + |
| 16 | +<p align="center" class="github-badges"> |
| 17 | + <a href="https://github.com/open-feature/spec/releases/tag/v0.8.0"> |
| 18 | + <img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.8.0&color=yellow&style=for-the-badge" /> |
| 19 | + </a> |
| 20 | + |
| 21 | + <a href="https://github.com/open-feature/js-sdk/releases/tag/angular-sdk-v0.0.2-experimental"> |
| 22 | + <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.0.2-experimental&color=blue&style=for-the-badge" /> |
| 23 | + </a> |
| 24 | + |
| 25 | + <br/> |
| 26 | + <a href="https://codecov.io/gh/open-feature/js-sdk"> |
| 27 | + <img alt="codecov" src="https://codecov.io/gh/open-feature/js-sdk/branch/main/graph/badge.svg?token=3DC5XOEHMY" /> |
| 28 | + </a> |
| 29 | + <a href="https://www.npmjs.com/package/@openfeature/angular-sdk"> |
| 30 | + <img alt="NPM Download" src="https://img.shields.io/npm/dm/%40openfeature%2Fangular-sdk" /> |
| 31 | + </a> |
| 32 | +</p> |
| 33 | + |
| 34 | +## Overview |
| 35 | + |
| 36 | +The OpenFeature Angular SDK adds Angular-specific functionality to |
| 37 | +the [OpenFeature Web SDK](/docs/reference/technologies/client/web). |
| 38 | + |
| 39 | +In addition to the features provided by the [web sdk](/docs/reference/technologies/client/web), capabilities include: |
| 40 | + |
| 41 | +- [Overview](#overview) |
| 42 | +- [Quick start](#quick-start) |
| 43 | + - [Requirements](#requirements) |
| 44 | + - [Install](#install) |
| 45 | + - [npm](#npm) |
| 46 | + - [yarn](#yarn) |
| 47 | + - [Required peer dependencies](#required-peer-dependencies) |
| 48 | + - [Usage](#usage) |
| 49 | + - [Module](#module) |
| 50 | + - [Minimal Example](#minimal-example) |
| 51 | + - [How to use](#how-to-use) |
| 52 | + - [Boolean Feature Flag](#boolean-feature-flag) |
| 53 | + - [Number Feature Flag](#number-feature-flag) |
| 54 | + - [String Feature Flag](#string-feature-flag) |
| 55 | + - [Object Feature Flag](#object-feature-flag) |
| 56 | + - [Opting-out of automatic re-rendering](#opting-out-of-automatic-re-rendering) |
| 57 | + - [Consuming the evaluation details](#consuming-the-evaluation-details) |
| 58 | +- [FAQ and troubleshooting](#faq-and-troubleshooting) |
| 59 | +- [Resources](#resources) |
| 60 | + |
| 61 | +## Quick start |
| 62 | + |
| 63 | +### Requirements |
| 64 | + |
| 65 | +- ES2015-compatible web browser (Chrome, Edge, Firefox, etc) |
| 66 | +- Angular version 16+ |
| 67 | + |
| 68 | +### Install |
| 69 | + |
| 70 | +#### npm |
| 71 | + |
| 72 | +```sh |
| 73 | +npm install --save @openfeature/angular-sdk |
| 74 | +``` |
| 75 | + |
| 76 | +#### yarn |
| 77 | + |
| 78 | +```sh |
| 79 | +# yarn requires manual installation of the peer dependencies (see below) |
| 80 | +yarn add @openfeature/angular-sdk @openfeature/web-sdk @openfeature/core |
| 81 | +``` |
| 82 | + |
| 83 | +#### Required peer dependencies |
| 84 | + |
| 85 | +The following list contains the peer dependencies of `@openfeature/angular-sdk`. |
| 86 | +See the [package.json](https://github.com/open-feature/js-sdk/blob/main/packages/angular/projects/angular-sdk/package.json) for the required versions. |
| 87 | + |
| 88 | +* `@openfeature/web-sdk` |
| 89 | +* `@angular/common` |
| 90 | +* `@angular/core` |
| 91 | + |
| 92 | +### Usage |
| 93 | + |
| 94 | +#### Module |
| 95 | + |
| 96 | +To include the OpenFeature Angular directives in your application, you need to import the `OpenFeatureModule` and |
| 97 | +configure it using the `forRoot` method. |
| 98 | + |
| 99 | +```typescript |
| 100 | +import { NgModule } from '@angular/core'; |
| 101 | +import { CommonModule } from '@angular/common'; |
| 102 | +import { OpenFeatureModule } from '@openfeature/angular-sdk'; |
| 103 | + |
| 104 | +@NgModule({ |
| 105 | + declarations: [ |
| 106 | + // Other components |
| 107 | + ], |
| 108 | + imports: [ |
| 109 | + CommonModule, |
| 110 | + OpenFeatureModule.forRoot({ |
| 111 | + provider: yourFeatureProvider, |
| 112 | + // domainBoundProviders are optional, mostly needed if more than one provider is needed |
| 113 | + domainBoundProviders: { |
| 114 | + domain1: new YourOpenFeatureProvider(), |
| 115 | + domain2: new YourOtherOpenFeatureProvider(), |
| 116 | + }, |
| 117 | + }) |
| 118 | + ], |
| 119 | +}) |
| 120 | +export class AppModule { |
| 121 | +} |
| 122 | +``` |
| 123 | + |
| 124 | +##### Minimal Example |
| 125 | + |
| 126 | +You don't need to provide all the templates. Here's a minimal example using a boolean feature flag: |
| 127 | + |
| 128 | +If `initializing` and `reconciling` are not given, the feature flag value that is returned by the provider will |
| 129 | +determine what will be rendered. |
| 130 | + |
| 131 | +```html |
| 132 | +<div *booleanFeatureFlag="'isFeatureEnabled'; default: true"> |
| 133 | + This is shown when the feature flag is enabled. |
| 134 | +</div> |
| 135 | +``` |
| 136 | + |
| 137 | +This example shows content when the feature flag `isFeatureEnabled` is true with a default value of true. |
| 138 | +No `else`, `initializing`, or `reconciling` templates are required in this case. |
| 139 | + |
| 140 | +#### How to use |
| 141 | + |
| 142 | +The library provides four primary directives for feature flags, `booleanFeatureFlag`, |
| 143 | +`numberFeatureFlag`, `stringFeatureFlag` and `objectFeatureFlag`. |
| 144 | + |
| 145 | +The first value given to the directive is the flag key that should be evaluated. |
| 146 | + |
| 147 | +For all directives, the default value passed to OpenFeature has to be provided by the `default` parameter. |
| 148 | + |
| 149 | +For all non-boolean directives, the value to compare the evaluation result to can be provided by the `value` parameter. |
| 150 | +This parameter is optional, if omitted, the `thenTemplate` will always be rendered. |
| 151 | + |
| 152 | +The `domain` parameter is _optional_ and will be used as domain when getting the OpenFeature provider. |
| 153 | + |
| 154 | +The `updateOnConfigurationChanged` and `updateOnContextChanged` parameter are _optional_ and used to disable the |
| 155 | +automatic re-rendering on flag value or context change. They are set to `true` by default. |
| 156 | + |
| 157 | +The template referenced in `else` will be rendered if the evaluated feature flag is `false` for the `booleanFeatureFlag` |
| 158 | +directive and if the `value` does not match evaluated flag value for all other directives. |
| 159 | +This parameter is _optional_. |
| 160 | + |
| 161 | +The template referenced in `initializing` and `reconciling` will be rendered if OpenFeature provider is in the |
| 162 | +corresponding states. |
| 163 | +This parameter is _optional_, if omitted, the `then` and `else` templates will be rendered according to the flag value. |
| 164 | + |
| 165 | +##### Boolean Feature Flag |
| 166 | + |
| 167 | +```html |
| 168 | +<div |
| 169 | + *booleanFeatureFlag="'isFeatureEnabled'; default: true; domain: 'userDomain'; else: booleanFeatureElse; initializing: booleanFeatureInitializing; reconciling: booleanFeatureReconciling"> |
| 170 | + This is shown when the feature flag is enabled. |
| 171 | +</div> |
| 172 | +<ng-template #booleanFeatureElse> |
| 173 | + This is shown when the feature flag is disabled. |
| 174 | +</ng-template> |
| 175 | +<ng-template #booleanFeatureInitializing> |
| 176 | + This is shown when the feature flag is initializing. |
| 177 | +</ng-template> |
| 178 | +<ng-template #booleanFeatureReconciling> |
| 179 | + This is shown when the feature flag is reconciling. |
| 180 | +</ng-template> |
| 181 | +``` |
| 182 | + |
| 183 | +##### Number Feature Flag |
| 184 | + |
| 185 | +```html |
| 186 | +<div |
| 187 | + *numberFeatureFlag="'discountRate'; value: 10; default: 5; domain: 'userDomain'; else: numberFeatureElse; initializing: numberFeatureInitializing; reconciling: numberFeatureReconciling"> |
| 188 | + This is shown when the feature flag matches the specified discount rate. |
| 189 | +</div> |
| 190 | +<ng-template #numberFeatureElse> |
| 191 | + This is shown when the feature flag does not match the specified discount rate. |
| 192 | +</ng-template> |
| 193 | +<ng-template #numberFeatureInitializing> |
| 194 | + This is shown when the feature flag is initializing. |
| 195 | +</ng-template> |
| 196 | +<ng-template #numberFeatureReconciling> |
| 197 | + This is shown when the feature flag is reconciling. |
| 198 | +</ng-template> |
| 199 | +``` |
| 200 | + |
| 201 | +##### String Feature Flag |
| 202 | + |
| 203 | +```html |
| 204 | +<div |
| 205 | + *stringFeatureFlag="'themeColor'; value: 'dark'; default: 'light'; domain: 'userDomain'; else: stringFeatureElse; initializing: stringFeatureInitializing; reconciling: stringFeatureReconciling"> |
| 206 | + This is shown when the feature flag matches the specified theme color. |
| 207 | +</div> |
| 208 | +<ng-template #stringFeatureElse> |
| 209 | + This is shown when the feature flag does not match the specified theme color. |
| 210 | +</ng-template> |
| 211 | +<ng-template #stringFeatureInitializing> |
| 212 | + This is shown when the feature flag is initializing. |
| 213 | +</ng-template> |
| 214 | +<ng-template #stringFeatureReconciling> |
| 215 | + This is shown when the feature flag is reconciling. |
| 216 | +</ng-template> |
| 217 | +``` |
| 218 | + |
| 219 | +##### Object Feature Flag |
| 220 | + |
| 221 | +```html |
| 222 | +<div |
| 223 | + *objectFeatureFlag="'userConfig'; value: { theme: 'dark' }; default: { theme: 'light' }; domain: 'userDomain'; else: objectFeatureElse; initializing: objectFeatureInitializing; reconciling: objectFeatureReconciling"> |
| 224 | + This is shown when the feature flag matches the specified user configuration. |
| 225 | +</div> |
| 226 | +<ng-template #objectFeatureElse> |
| 227 | + This is shown when the feature flag does not match the specified user configuration. |
| 228 | +</ng-template> |
| 229 | +<ng-template #objectFeatureInitializing> |
| 230 | + This is shown when the feature flag is initializing. |
| 231 | +</ng-template> |
| 232 | +<ng-template #objectFeatureReconciling> |
| 233 | + This is shown when the feature flag is reconciling. |
| 234 | +</ng-template> |
| 235 | +``` |
| 236 | + |
| 237 | +##### Opting-out of automatic re-rendering |
| 238 | + |
| 239 | +By default, the directive re-renders when the flag value changes or the context changes. |
| 240 | + |
| 241 | +In cases, this is not desired, re-rendering can be disabled for both events: |
| 242 | + |
| 243 | +```html |
| 244 | +<div *booleanFeatureFlag="'isFeatureEnabled'; default: true; updateOnContextChanged: false; updateOnConfigurationChanged: false;"> |
| 245 | + This is shown when the feature flag is enabled. |
| 246 | +</div> |
| 247 | +``` |
| 248 | + |
| 249 | +##### Consuming the evaluation details |
| 250 | + |
| 251 | +The `evaluation details` can be used when rendering the templates. |
| 252 | +The directives [`$implicit`](https://angular.dev/guide/directives/structural-directives#structural-directive-shorthand) |
| 253 | +value will be bound to the flag value and additionally the value `evaluationDetails` will be |
| 254 | +bound to the whole evaluation details. |
| 255 | +They can be referenced in all templates. |
| 256 | + |
| 257 | +The following example shows `value` being implicitly bound and `details` being bound to the evaluation details. |
| 258 | + |
| 259 | +```html |
| 260 | +<div |
| 261 | + *stringFeatureFlag="'themeColor'; value: 'dark'; default: 'light'; else: stringFeatureElse; let value; let details = evaluationDetails"> |
| 262 | + It was a match! |
| 263 | + The theme color is {{ value }} because of {{ details.reason }} |
| 264 | +</div> |
| 265 | +<ng-template #stringFeatureElse let-value let-details='evaluationDetails'> |
| 266 | + It was no match! |
| 267 | + The theme color is {{ value }} because of {{ details.reason }} |
| 268 | +</ng-template> |
| 269 | +``` |
| 270 | + |
| 271 | +When the expected flag value is omitted, the template will always be rendered. |
| 272 | +This can be used to just render the flag value or details without conditional rendering. |
| 273 | + |
| 274 | +```html |
| 275 | +<div *stringFeatureFlag="'themeColor'; default: 'light'; let value;"> |
| 276 | + The theme color is {{ value }}. |
| 277 | +</div> |
| 278 | +``` |
| 279 | + |
| 280 | +## FAQ and troubleshooting |
| 281 | + |
| 282 | +> I can import things form the `@openfeature/angular-sdk`, `@openfeature/web-sdk`, and `@openfeature/core`; which should I use? |
| 283 | +
|
| 284 | +The `@openfeature/angular-sdk` re-exports everything from its peers (`@openfeature/web-sdk` and `@openfeature/core`), and adds the Angular-specific features. |
| 285 | +You can import everything from the `@openfeature/angular-sdk` directly. |
| 286 | +Avoid importing anything from `@openfeature/web-sdk` or `@openfeature/core`. |
| 287 | + |
| 288 | +## Resources |
| 289 | + |
| 290 | + - [Example repo](https://github.com/open-feature/angular-test-app) |
0 commit comments