One of the end goals is to use a primitive instead of a union type. The whole app makes more sense if you are dealing with a primitive, instead of dealing with cases or passing values as arguments. If you don’t have that value is because the app it’s not ready.
Right now we have an inner app with primitives and an outer app that deals with fetching and union types. It works for us, but I don’t think that is idiomatic and also more complex.
The first seems fine to me, the second seems less safe than doing it within Elm.
Note that if you are passing in the flags data as Json.Value, I think you are still inside a Result , unless you Debug.crash on a decode failure (which won’t be allowed in production apps in the future).
We are doing something like this. We treat the flags parameter passed into the init function as a Value type then apply a custom decoder to it using decodeValue to produce a “configuration” record with several fields containing primitives.
In the event that the decoding fails, we set an error value in the model that notifies the user that the app could not be initialized correctly (and display some debug information produced by the Err result). This approach works very well for data that must be generated from your back end and is required to intersection initialize the app.
We do this all over the place at work. Our flag type is always Json.Decode.Value. We run a decoder on it to decode the data from the server. If it succeeds, we have our initial Model and proceed as normal. If it fails, we render an error message to the user and send an error report to our logging service (Rollbar).
We also rely heavily on this approach. We have loads of configuration that is described in YAML, combined in various ways during the build step based on feature flags and cli parameters, translated to json, further combined with a handful of flags written to the response from the Razor page, and then finally sent to the Elm app as a Json.Decode.Value where it can be chunked out into the various feature configs. Like @rtfeldman mentions, if any decoding of a config chunk fails for a particular feature, we render an error message where appropriate and report to Rollbar.