So I have a task to cache everything that happens on a page in the browser local storage, I have created the outgoing port but I am finding it difficult to send the whole model through to javascript, I need to cache send the whole state of the app real-time, I used onInput function.
Be more specific. What is different about it?
Hi Victory,
Iām not too sure where youāre running into difficulty. But the general approach would be to use the Json.Encode
library to transform your appās Model
into a value of type Json.Encode.Value
.
The port should be defined as below. Actually I copied this from the āportsā page of the Elm guide, which might be worth reviewing. The example there is based around localStorage
!
port module Main exposing (..)
import Json.Encode as E
port cache : E.Value -> Cmd msg
If your Model
structure is made of simple Elm types (Int, Float, String, Bool or records/tuples/lists of them), you can send the model
to JS and write it to localstorage. You will then be able to reload it in init from flags. elm-todomvc is an example on how to do this.
If your Model
contains a custom type, you will need to create an encoder and a decoder for the Model and send Value
through the ports.
My model is like an Shopping checkout page, It contains Input fields mostly
Hi Victory,
The more specifics you provide, the easier it will be for us to help you. Code snippets/examples are helpful along with any error messages that you may be encountering.
That said, Iāll have a go based on your two posts
From what youāve said so far, Iām assuming that what you need to do is to update the cache/localStorage each time an input box is updated/changed by the user(?) so that if they should close the page halfway through, they can restore the previous state and continue from where they left off. If this is the case, you probably wonāt need to send your whole model through in one go. You can just send the individual values each time they change - the user can only fill in one field at a time, so that should be all you need to worry about.
You havenāt mentioned anything about the rest of your model, such as what types might be involved etc, so I will only address the input boxes changing through user input.
The values in the input boxes will come back to your update
function as String
s so as pdamoc already mentioned, they can be sent straight through a port to JS without having to worry about decoders.
This gives you a couple of options.
- You could set up a port for each input field, and send each one through to JS as they change. You would then need corresponding ālistenersā on the JS side to receive the data from each port, or
- You could use a single port, which is probably the better option. In this case, you would also need to send an identifier through along with the value you wish to store, so that your JS code knows which field is being cached. This way you would just need one ālistenerā on the JS side that would store the data according to the identifier you send through with the value.
So, for option 2, you could have something like this:
type alias Model =
{ field1 : String
, field2 : String
}
type Msg
= Field1Changed String
| Field2Changed String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Field1Changed val ->
( { model | field1 = val }
, cacheField {id = 1, value = val}
)
Field2Changed val ->
( { model | field2 = val }
, cacheField {id = 2, value = val}
)
port cacheField : {id : Int, value : String} -> Cmd msg
Hopefully, that points you in the right direction.
For the JS side, if you havenāt already, it might be worth having a look at: https://github.com/macmcmeans/localDataStorage which enables storing and retrieving whole objects to and from localStorage.
HTH
Exactly it contains Custom types, So now the issue is creating the encoder and decoder for the model and sending the value through the port, Once i do this, the issue is solvedā¦
I have created the incoming and outgoing port already:
port module Main exposing (ā¦)
import Browser
import Html exposing (Html, a, br, button, div, form, h1, i, img, input, label, option, section, select, small, span, strong, text)
import Html.Attributes exposing (class, disabled, for, href, id, name, placeholder, src, style, type_, value)
import Html.Events
import Http
import Json.Decode as D
import Json.Decode.Pipeline as Pipeline
import Json.Encode as E
import List.Extra
import String
port incoming : (E.Value -> msg) -> Sub msg
port outgoing : OutgoingMsg -> Cmd msg
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.