Search code examples
enumsenvironment-variablesconstantsdartdart2js

Dart: Initialize enum from JavaScript var


In my HTML file I have:

<script>
    var serverName = "dev.myapp.com:8080";
</script>

Then, in my Dart code:

import "dart:js" as js;

String SERVER_NAME = js.context["serverName"];
String SIGNIN_PLACE_URL = "http://$SERVER_NAME/signin";
String SIGNOUT_PLACE_URL = "http://$SERVER_NAME/signout";

class Place {
    static const SigninPlace = const Place._(SIGNIN_PLACE_FRAGMENT_URL);
    static const SignoutPlace = const Place._(SIGNOUT_PLACE_FRAGMENT_URL);

    static get values => [SigninPlace, SignoutPlace];

    final String fragmentURL;

    const Place._(this.fragmentURL);
}

I'm getting an error inside my "enum" in regard to both my fragmentURL arguments for both values:

Arguments of a constant creation must be constant expressions

So it looks like I need to make these fragmentURLs const, but not sure how. What's the solution here?


Solution

  • As SERVER_NAME is unknown at compile time it can't be a constant. If you want SigninPlace/SignoutPlace to be a constant SERVER_NAME must be a constant too.

    A possible workaround

    class Place {
      static String SERVER_NAME;
    
      static final SigninPlace = const Place._("signin");
      static final SignoutPlace = const Place._("signout");
    
      static get values => [SigninPlace, SignoutPlace];
    
      String get fragmentURL {
        Map places = {
                      "signin": "http://${SERVER_NAME}/signin",
                      "signout" : "http://${SERVER_NAME}/signout" };
        return places[_fragmentURL];
      }
      final String _fragmentURL;
    
      const Place._(this._fragmentURL);
    }
    
    void main(List<String> args) {
      Place.SERVER_NAME = "aServer";
      print(Place.SigninPlace.fragmentURL);
    }
    

    If you move the Strings containing the interpolation into a function (here a getter) the interpolation is deferred until the value is requested. At this time your SERVER_NAME should already be assigned.
    You could add an exception or different error handling if fragmentURL is requested before SERVER_NAME is set.