0

Trying to get elm ports working to maintain the session.

In index.html, the script includes the following listener:

  window.addEventListener("load", function(event) {
    app.ports.onSessionChange.send(localStorage.session);
  }, false);

localStorage.session looks like this (and it stays there until I've logged out):

{"email":"user@fake.com","token":"eyJhbG...","user_id":1,"handle":"me"}

The definition in Ports.elm is:

port onSessionChange : (Value -> msg) -> Sub msg

This port is connected to Main.elm here (let me know if I've forgotten to include some of the definitions below):

subscriptions : Model -> Sub Msg
subscriptions model =
    Ports.onSessionChange sessionChange


sessionChange : Json.Decode.Value -> Msg
sessionChange value =
    let
        result =
            Json.Decode.decodeValue sessionDecoder value
    in
        case result of
            Ok sess ->
                SetSession (Just sess)

            Err err ->
                SetSession Nothing

    ...


type alias Session =
    { email : String
    , token : String
    , user_id : Int
    , handle : String
    }

    ...

import Json.Decode as Decode exposing (..)
import Json.Decode.Pipeline as Pipeline exposing (decode, required)

sessionDecoder : Decode.Decoder Session
sessionDecoder =
    Pipeline.decode Session
        |> Pipeline.required "email" Decode.string
        |> Pipeline.required "token" Decode.string
        |> Pipeline.required "user_id" Decode.int
        |> Pipeline.required "handle" Decode.string

    ...

type Msg
    = NoOp
    | SetSession (Maybe Session)

    ...


update msg model =
    case msg of
        SetSession session ->
            case Debug.log "session = " session of
                Just sess ->
                    ({ model | session = sess } , Cmd.none)

                Nothing ->
                    (model, Cmd.none)

Debug.log "session" displays Nothing in the console when the page loads, so JS is talking to elm, but the decoder seems to be failing. Any ideas?

Mark Karavan
  • 2,654
  • 1
  • 18
  • 38
  • 1
    Are you sure that `localStorage.session` is actually valid in javascript? This [reduction of your code](https://ellie-app.com/cMg8ZtQqMa1/0) works fine – Chad Gilbert Nov 15 '17 at 13:18
  • You nailed it, I was saving the session as a JSON string rather than JSON. It works when I use `app.ports.onSessionChange.send(JSON.parse(localStorage.session));`. If you make this an answer, I'll mark as correct. – Mark Karavan Nov 15 '17 at 17:36

1 Answers1

1

I've plugged your code into a minimal working example and everything works fine. You might want to log the value of localStorage.session from inside the javascript portion to make sure it's a valid JSON value.

Chad Gilbert
  • 36,115
  • 4
  • 89
  • 97