This repository has been archived by the owner. It is now read-only.

Using the reactor with `programWithFlags` #199

Closed
zacclark opened this Issue Jul 14, 2016 · 9 comments

Comments

Projects
None yet
7 participants
@zacclark
Copy link

zacclark commented Jul 14, 2016

If I have a main like the following:

type alias Config =
  { baseUrl : String }

main : Program (Config)
main =
  Html.App.programWithFlags
    { init = init
    , view = view
    , update = update
    , subscriptions = always Sub.none
    }

init : (Config) -> (Model, Cmd Msg)

And I try to access it with elm reactor, there does not appear to be a way to pass the necessary flags to the program, so it crashes on .fullscreen.

The js error is:

Uncaught Error: You are trying to initialize module `Search` with an unexpected argument.
When trying to convert it to a usable Elm value, I run into this problem:

Expecting an object with a field named `baseUrl` but instead got: undefined

I know I could switch to another workflow where I compile my elm app externally and embed it myself, but the auto-rebuild and nicely formatted errors in the browser would be annoying to lose. Is there a different pattern I should be using?

@process-bot

This comment has been minimized.

Copy link

process-bot commented Jul 14, 2016

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

@zacclark

This comment has been minimized.

Copy link

zacclark commented Jul 14, 2016

Updating with a complete example:

module ExampleReactorFlagsProblem exposing (..)

import Html exposing (div, Html)
import Html.App

type alias Config =
  { baseUrl : String }

type alias Model =
  { config : Config }

type Msg
  = Nothing

main : Program (Config)
main =
  Html.App.programWithFlags
    { init = init
    , view = view
    , update = update
    , subscriptions = always Sub.none
    }

init : Config -> (Model, Cmd Msg)
init config =
  (Model config, Cmd.none)

view : Model -> Html Msg
view _ =
  div [] []

update : Msg -> Model -> (Model, Cmd Msg)
update _ model
  = (model, Cmd.none)

Running that in the reactor will show the problem.

@evancz

This comment has been minimized.

Copy link
Contributor

evancz commented Jul 14, 2016

Unfortunately, elm-reactor can't handle that scenario well right now. A revamp of elm-reactor is on the relatively short-term roadmap, so I'll add this to the list of feature requests. That said, using programWithFlags necessarily implies that you'd like to embed it in a custom way, so I'm not sure if it totally aligned with elm-reactor's goals. We'll see when the time comes to work on it!

@evancz evancz closed this Jul 14, 2016

@evancz

This comment has been minimized.

Copy link
Contributor

evancz commented Jul 14, 2016

I think the "compile to JS endpoint" idea in #193 would cover this case, so I added this issue there.

@focusaurus

This comment has been minimized.

Copy link

focusaurus commented Dec 7, 2016

Is there any way I can code my application such that Flags is a Maybe or otherwise optional to get elm-reactor compatibility?

update

I was able to make my app work with both program and programWithFlags by defining both an initFlags (used for real deployments) and init (used with elm-reactor).

init: ( Model, Cmd Msg)
init =
  let flags = Flags Nothing Nothing
  in
    initFlags flags

I have to do a small amount of commenting out/in code to switch between the 2 modes, but it's workable.

@zacclark

This comment has been minimized.

Copy link

zacclark commented Dec 7, 2016

@focusaurus I got something working similar to your original idea (making it a Maybe). It didn't need changes between a real embed and the reactor. Unfortunately, I don't remember exactly how I did it, and its in a repo I no longer have access to. But it is 100% possible (at least in 0.17), so at least you know you're not working towards something impossible :)

Sorry I can't remember exactly how I did it.

@zeddidragon

This comment has been minimized.

Copy link

zeddidragon commented Feb 12, 2017

In the meantime, I use a workaround.

My Main.elm is located at ./src/Main.elm
I copied my index.html to ./src/debug.html

The script tag looks like so:

<script type="text/javascript" src="../_compile/src/Main.elm"></script>

The script tag that runs your program looks something like so:

  if(Elm.Main) {
    Elm.Main.fullscreen({your: "flags go here"})
  } else {
    runElmProgram()
  }

Instead of looking at localhost:8000/src/Main.elm, you look at localhost:8000/src/debug.html

@jweir

This comment has been minimized.

Copy link
Contributor

jweir commented Feb 22, 2017

What I have been doing is using a separate Reactor.elm file that initializes my model and program with static values in place of flags. This way I can develop with reactor, and and leave the production code in App.elm alone.

example https://gist.github.com/jweir/79af678adf6bce4be3bd91fec2f471fa

@radix

This comment has been minimized.

Copy link

radix commented Mar 1, 2017

It'd be really nice if elm reactor took flags on the command line.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.