Creating a string flag

This section describes how to define a string flag.

Understanding string flags

String flags are flags that can have multiple values and not just true or false. When you create a string flag in your application, you define the default value and all the other values this flag can have. Like simple boolean flags, the string flag name is derived from the flag variable name.

Creating a container class and defining a feature flag

To add a string flag, you need two things:

  • A container class for your flags

  • A defined flag inside the container class

In the example below, a String flag is defined with the name titleColors. The flag name is derived from the flag variable name. The titleColors flag has a default value of White.

If you need a string flag to be more dynamic with regards to value (i.e: URL’s), you can define a String flag in the code with only one value (which is also the default value). This will result in a Free Text input field when configuring the flags through the CloudBees Feature Management dashboard.

With SDK version 5.0 or later use Rox.RoxString, examples below:

In the example below, the title color can be any one of White, Blue, Green and Yellow. By default, it will be white.

React Native JavaScript Node.js JavaScript SSR .NET Python JVM Android
const flags = {
  titleColors: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']),
};
const flags = {
  titleColors: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']),
};
const flags = {
  titleColors: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']),
};
import {RoxString} from 'rox-ssr';

const flags = {
  titleColors: new RoxString('White', ['White', 'Blue', 'Green', 'Yellow']),
};
using Io.Rollout.Rox.Server.Flags;

public class Container : IRoxContainer
{
  public RoxString TitleColorsVariant = new RoxString("White", new String[] {"White", "Blue", "Green", "Yellow"});
}
from rox.core.entities.rox_string import RoxString

class MyContainer:
  def __init__(self):
    self.title_colors = RoxString('White', ['White', 'Blue', 'Green', 'Yellow'])
import io.rollout.configuration.RoxContainer;
import io.rollout.flags.Freeze;
import io.rollout.flags.RoxString;

public static class Container implements RoxContainer {
    public final RoxString titleColors = new RoxString("Red", new String[]{ "Red", "Blue", "Green" }, Freeze.UntilLaunch);
}
import io.rollout.configuration.RoxContainer;
import io.rollout.flags.RoxString;

public static class Container implements RoxContainer {
    public final RoxString titleColors = new RoxString("Red", new String[]{ "Red", "Blue", "Green" });
}

With SDK version 4.x use Rox.RoxString, examples below:

In the example below, the title color can be any one of White, Blue, Green and Yellow. By default, it will be white.

Swift Objective-C Android React Native JavaScript Node.js JavaScript SSR JVM .NET Python Go Ruby PHP C C++
import ROX
import ROXCore

class Flags : RoxContainer {
  let titleColors = ROXVariant(withDefault: "White", options: ["White", "Blue", "Green", "Yellow"])

  // The following is the same thing but with Enum instead of String array
  let titleColorsEnum = RoxEnumVariant(Colors.White)
}

enum Colors : Int {
  case White
  case Blue
  case Green
  case Yellow
}
#import <ROXCore/ROXCore.h>

@interface Flags : ROXBaseContainer

@property (nonatomic) ROXVariant* titleColors;

@end


#import "Flags.h"

@implementation Flags

- (instancetype)init {
  self = [super init];
  if (self) {
    self.titleColors = [[ROXVariant alloc] initWithDefault:"White" options:@[@"Blue", @"Green", @"Yellow"]];
  }
  return self;
}

@end
public class Flags implements RoxContainer{
  public RoxVariant titleColors = new RoxVariant("White", new String[] {"White", "Blue", "Green", "Yellow"});

  public enum Color {
    WHITE, BLUE, GREEN, YELLOW
  }
  // The following is the same thing but with Enum instead of String array
  public RoxEnumVariant<Color> titleColorsEnum = new RoxEnumVariant<>(Color.WHITE);
const flags = {
  titleColors: new Rox.Variant('White', ['White', 'Blue', 'Green', 'Yellow']),
};
const flags = {
  titleColors: new Rox.Variant('White', ['White', 'Blue', 'Green', 'Yellow']),
};
const flags = {
  titleColors: new Rox.Variant('White', ['White', 'Blue', 'Green', 'Yellow']),
};
import {Variant} from 'rox-ssr';

const flags = {
  titleColors: new Variant('White', ['White', 'Blue', 'Green', 'Yellow']),
};
public class Flags implements RoxContainer{
  public RoxVariant titleColors = new RoxVariant("White", new String[] {"White", "Blue", "Green", "Yellow"});

  public enum Color {
    WHITE, BLUE, GREEN, YELLOW
  }
  // The following is the same thing but with Enum instead of String array
  public RoxEnumVariant<Color> titleColorsEnum = new RoxEnumVariant<>(Color.WHITE);
using Io.Rollout.Rox.Server.Flags;

public class Container : IRoxContainer
{
  public RoxVariant TitleColorsVariant = new RoxVariant("White", new String[] {"White", "Blue", "Green", "Yellow"});
}
from roxserver.flags.rox_flag import RoxFlag
from roxserver.flags.rox_variant import RoxVariant

class MyContainer:
     def __init__(self):
        self.title_colors = RoxVariant('White', ['White', 'Blue', 'Green', 'Yellow'])
import (
        "github.com/rollout/rox-go/server"
)

type Container struct {
        titleColors server.RoxVariant
}

var flags = &Container {
        titleColors: server.NewRoxVariant("White", []string{"White", "Blue", "Green", "Yellow"})}
require 'rox/server/rox_server'
require 'rox/server/flags/rox_variant'

class Container
    attr_accessor :title_colors

  def initialize
        @title_colors = Rox::Server::RoxVariant.new('White', ['White', 'Blue', 'Green', 'Yellow'])
    end
end
use Rox\Server\Rox;
use Rox\Server\Flags\RoxVariant;

class Container
{
    public $titleColors;

    public function __construct()
    {
        $this->titleColors = new RoxVariant("White", ["White", "Blue", "Green", "Yellow"]);
    }
}
RoxVariant *titleColor = rox_add_variant("titleColors", "White", ROX_LIST_COPY_STR("White", "Blue", "Green", "Yellow"));
Rox::Variant *titleColor = Rox::Variant::Create("titleColors", "White", std::vector<std::string>{"White", "Blue", "Green", "Yellow"});

Registering the container class

Once you have the container class, you need to register its instance to the CloudBees Feature Management SDK. This is done with the Rox.register SDK function.

The namespace parameter is a logical separation between containers and can be used to find flags on the dashboard.

  • A namespace can only be registered once.

Swift Objective-C Android React Native JavaScript Node.js JavaScript SSR JVM .NET Python Go Ruby PHP C C++
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

  ROX.register("<namespace>", container: Flags())
  ROX.setup(withKey: ROLLOUT_KEY)
  return true
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [ROX register:[[Flags alloc] init]];
    [ROX setupWithKey:@<ROLLOUT_KEY>];

    return YES;
}
public class App extends Application {

  @Override
  public void onCreate() {
    super.onCreate();

    Flags flags = new Flags();
    Rox.register("<namespace>", flags);
    Rox.setup(this);

    // This can also be done in the MainActivity if your app doesn't extends the Application class
  }
}
const flags = {
  // define Rox entities here
}
Rox.register('<namespace>', flags);
await Rox.setup('<ROLLOUT_KEY>');
const flags = {
  // define Rox entities here
}
Rox.register('<namespace>', flags);
Rox.setup('<ROLLOUT_KEY>');
const flags = {
  // define Rox entities here
}
Rox.register('<namespace>', flags);
await Rox.setup('<ROLLOUT_KEY>');
import {Rox} from 'rox-ssr';

const flags = {
  // define Rox entities here
}
Rox.register('<namespace>', flags);
Rox.setup('<ROLLOUT_KEY>');
Flags flags = new Flags();
Rox.register("<namespace>", flags);
Rox.setup(ROLLOUT_KEY);
Container flags = new Container();
Rox.Register("<namespace>", flags);
await Rox.Setup(<ROLLOUT_KEY>);
from rox.server.rox_server import Rox

flags = MyContainer()
Rox.register(<namespace>, flags)
cancel_event = Rox.setup('<ROLLOUT_KEY>').result()
import "github.com/rollout/rox-go/server"

type Container struct {}

var flags = &Container {}
var rox *server.Rox

func initRox() {
  options := server.NewRoxOptions(server.RoxOptionsBuilder {})
  rox = server.NewRox()
  rox.Register("<namespace>", flags)
    rox.Setup("<ROLLOUT_KEY>", options)
}
require 'rox/server/rox_server'

class Container
end

flags = Container.new
Rox::Server::RoxServer.register(<namespace>, flags)
Rox::Server::RoxServer.setup(<ROLLOUT_KEY>).join
use Rox\Server\Rox;
use Rox\Server\Flags\RoxVariant;

class Container
{
    public $titleColors;

    public function __construct()
    {
        $this->titleColors = new RoxVariant("red", ["red", "blue", "green"]);
    }
}

$flags = new Container();
Rox::register(<namespace>, $flags);
Rox::setup(<ROLLOUT_KEY>);
#include <rollout.h>

#define DEFAULT_API_KEY "ROLLOUT_KEY"

int main(int argc, char **argv) {
    RoxVariant *titleColor = rox_add_variant("titleColors", "red", ROX_LIST_COPY_STR("red", "blue", "green"));
  rox_setup(DEFAULT_API_KEY, NULL);
  rox_shutdown();
}
#include <rollout.hpp>

#define DEFAULT_API_KEY "ROLLOUT_KEY"

int main(int argc, char **argv) {
    Rox::Variant *titleColor = Rox::Variant::Create("titleColors", "red", std::vector<std::string>{"red", "blue", "green"});
  Rox::Setup(DEFAULT_API_KEY, NULL);
  Rox::Shutdown();
}

Using a string flag

Swift Objective-C Android React Native JavaScript Node.js JavaScript SSR JVM .NET Python Go Ruby PHP C C++
switch roxContainer.titleColors!.value()! {
  case "White":
    print("Title color is White")
  case "Blue":
    print("Title color is Blue")
  case "Green":
    print("Title color is Green")
  case "Yellow":
    print("Title color is Yellow")
  default:
    print("Title color is default - White")
}

switch roxContainerEnum.titleColors.value {
  case .White:
    print("Title color is White")
  case .Blue:
    print("Title color is Blue")
  case .Green:
    print("Title color is Green")
  case .Yellow:
    print("Title color is Yellow")
}
if ([roxContainer.titleColors.value isEqualToString:@"Blue"]) {
    NSLog(@"Title color is Blue");
}
else if ([roxContainer.titleColors.value isEqualToString:@"White"]) {
    NSLog(@"Title color is White");
}
else if ([roxContainer.titleColors.value isEqualToString:@"Green"]) {
    NSLog(@"Title color is Green");
}
else if ([roxContainer.titleColors.value isEqualToString:@"Yellow"]) {
    NSLog(@"Title color is Yellow");
}
if (roxContainer.titleColors.getValue() == "Blue") {
  Log.i(tag, "Title color is blue");
} else if (roxContainer.titleColors.getValue() == "Green") {
  Log.i(tag, "Title color is green");
} else if (roxContainer.titleColors.getValue() == "Yellow") {
  Log.i(tag, "Title color is yellow");
} else if (roxContainer.titleColors.getValue() == "White") {
  Log.i(tag, "Title color is white");
}

switch (roxContainer.titleColorsEnum.getValue()) {
  case BLUE:
    Log.i(tag, "Title color is blue");
    break;
  case GREEN:
    Log.i(tag, "Title color is green");
    break;
  case YELLOW:
    Log.i(tag, "Title color is yellow");
    break;
  case WHITE:
    Log.i(tag, "Title color is white");
    break;
}
if (flags.titleColors.getValue() === 'Blue') {
  console.log('Title color is blue');
} else if (flags.titleColors.getValue() === 'Green') {
  console.log('Title color is green');
} else if (flags.titleColors.getValue() === 'Yellow') {
  console.log('Title color is yellow');
} else if (flags.titleColors.getValue() === 'White') {
  console.log('Title color is white');
}
if (flags.titleColors.getValue() === 'Blue') {
  console.log('Title color is blue');
} else if (flags.titleColors.getValue() === 'Green') {
  console.log('Title color is green');
} else if (flags.titleColors.getValue() === 'Yellow') {
  console.log('Title color is yellow');
} else if (flags.titleColors.getValue() === 'White') {
  console.log('Title color is white');
}
if (flags.titleColors.getValue() === 'Blue') {
  console.log('Title color is blue');
} else if (flags.titleColors.getValue() === 'Green') {
  console.log('Title color is green');
} else if (flags.titleColors.getValue() === 'Yellow') {
  console.log('Title color is yellow');
} else if (flags.titleColors.getValue() === 'White') {
  console.log('Title color is white');
}
if (flags.titleColors.getValue() === 'Blue') {
  console.log('Title color is blue');
} else if (flags.titleColors.getValue() === 'Green') {
  console.log('Title color is green');
} else if (flags.titleColors.getValue() === 'Yellow') {
  console.log('Title color is yellow');
} else if (flags.titleColors.getValue() === 'White') {
  console.log('Title color is white');
}
if (roxContainer.titleColors.getValue() == "Blue") {
  Log.i(tag, "Title color is blue");
} else if (roxContainer.titleColors.getValue() == "Green") {
  Log.i(tag, "Title color is green");
} else if (roxContainer.titleColors.getValue() == "Yellow") {
  Log.i(tag, "Title color is yellow");
} else if (roxContainer.titleColors.getValue() == "White") {
  Log.i(tag, "Title color is white");
}

switch (roxContainer.titleColorsEnum.getValue()) {
  case BLUE:
    Log.i(tag, "Title color is blue");
    break;
  case GREEN:
    Log.i(tag, "Title color is green");
    break;
  case YELLOW:
    Log.i(tag, "Title color is yellow");
    break;
  case WHITE:
    Log.i(tag, "Title color is white");
    break;
}
if (flags.TitleColorsVariant.GetValue().Equals("Black"))
{
    // set title color to black
}
else if (flags.TitleColorsVariant.GetValue().Equals("Green"))
{
    // set title color to green
}
print('color is %s' % my_container.title_colors.get_value())
  switch flags.titleColors.GetValue(nil) {
        case "Green" :
                fmt.Println("green");
        case "White" :
                fmt.Println("white");
        case "Blue" :
                fmt.Println("blue");
  }
puts "color is #{flags.title_colors.value}"
echo "color is " . $flags->title_colors->getValue()
printf("color is: %s", rox_variant_get_value_or_default(titleColor));
printf("color is: %s", titleColor->GetValue());

Flag freeze level

Flag freeze is available on client side SDKs by default.

  • SDK version 4.x the default is set to untilForeground.

  • SDK version 5.0 or later the default is set to none .

See Understanding a flag freeze for more information.