In looking at the documentation for WebSharper's local storage, the SetItem item is string * string -> unit
(and GetItem is string -> string
).
This means that I'll need to convert anything I want to store into strings and do the reverse to retrieve them. Or, to put it in another way, I'll need to serialize and de-serialize them. Is there a way to use the behind-the-scenes conversion that WebSharper already does for RPC calls, or am I stuck with using a server-side library like FsPicker?
Not built in yet, I have been using this helper module to make local storage usable the same way as a ref cell:
open IntelliFactory.WebSharper
// Helper for handling localstorage, making a stored value work like a ref cell.
[<JavaScript; AutoOpen>]
module LocalStorage =
open IntelliFactory.WebSharper.Html5
let localStorage = Window.Self.LocalStorage
type IValue<'T> =
abstract Value: 'T with get, set
let [<Inline>] ( ! ) (x: IValue<_>) = x.Value
let [<Inline>] ( := ) (x: IValue<_>) v = x.Value <- v
// Redefining Ref to use IValue
type Ref<'T> (value: 'T) =
let mutable v = value
interface IValue<'T> with
member this.Value
with get() = v
and set value = v <- value
let [<Inline>] ref v = Ref v
let incr i = i := !i + 1
let decr i = i := !i - 1
type IStorageItem<'T> =
inherit IValue<'T>
abstract Save: unit -> unit
abstract Delete: unit -> unit
type JSONStorageItem<'T>(key, defaultVal) =
let mutable value = None
let getValue() =
match value with
| Some v -> v
| _ ->
let v =
match localStorage.GetItem key with
| null -> defaultVal
| s ->
Json.Parse s :?> _
value <- Some v
v
interface IStorageItem<'T> with
member this.Value
with get() = getValue()
and set v =
try localStorage.SetItem(key, Json.Stringify v)
value <- Some v
with _ -> JavaScript.Alert "Saving data to storage failed."
member this.Save() =
try localStorage.SetItem(key, Json.Stringify (getValue()))
with _ -> JavaScript.Alert "Saving data to storage failed."
member this.Delete() =
localStorage.RemoveItem key
value <- None
let [<Inline>] getJSONStorage key defaultVal = JSONStorageItem<_>(key, defaultVal) :> IStorageItem<_>
However this can currently only stringify/parse straight data objects: record, list, array, tuple and union types are ok, but no prototypes are restored.