Save App State in LocalStorage In Elm

I want to cache the whole app state in the browser local storage. My model is a kind of check-out page consisting of various types , Here is the Model type alias :

type alias Model =
{ showCheckoutModal : Bool
, showAddressForm : Bool
, emailAddress : String
, address : Address
, selectedAddress : Maybe Address
, addresses : List Address
, name : String
, listings : List Listing
, shop : Maybe Shop
, shop_id : String
, shippingInfo : ShippingInfo
, selectedDestination : Maybe ShippingDestination
}

I have created the outgoing port and Incoming Port

port outgoing : OutgoingMsg -> Cmd msg

port incoming : (E.Value -> msg) -> Sub msg

So , I made some research and It can be done but all examples online are of simpler models , I havent seen any for a model as complex as mine. Please I appreciate any contribution , Thanks

1 Like

I’d recommend using elm-codec.

It lets you write compatible encoder/decoders at the same time. A codec for your Model would look like this:

codecModel : Codec Model
codecModel =
    Codec.object Model
        |> Codec.field "showCheckoutModal" .showCheckoutModal Codec.bool
        |> Codec.field "showAddressForm" .showAddressForm Codec.bool
        |> Codec.field "emailAddress" .emailAddress Codec.string
        |> Codec.field "address" .address codecAddress
        |> Codec.optionalField "selectedAddress" .selectedAddress codecAddress
        |> Codec.field "addresses" .addresses (Codec.list codecAddress)
        |> Codec.field "name" .name Codec.string
        |> Codec.field "listings" .listings (Codec.list codecListing)
        |> Codec.optionalField "shop" .shop codecShop
        |> Codec.field "shop_id" .shop_id Codec.string
        |> Codec.field "shippingInfo" .shippingInfo codecShippingInfo
        |> Codec.optionalField "selectedDestination" .selectedDestination codecShippingDestination
        |> Codec.buildObject

You still need to build codecAddress, codecShop, codecListing, etc. (I didn’t know what types those are).

You can see how to write encoders in elm-codec’s examples. It doesn’t only work for records, it also works for custom types.

As for getting that into the browser’s local storage: You create a port:

port saveModelLocalStorage : Encode.Value -> Cmd msg

And on the javascript side you can subscribe to that port. More info about that in the elm guide.

If you want to load the Model on page load out of local storage, I don’t recommend ports, I recommend flags. I think you can just take an Encode.Value as a flag and parse it using elm-codec.

Ah and now that I think of it, there is a very recent js integration example about how to use local storage with elm.

3 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.