B4J Question Browser Local Storage - save data? [SOLVED]

ilan

Expert
Licensed User
Longtime User
hi

with WebSocket object we can store data to sessions. but sessions are automatically removed when the user closes the browser (or even the tab).
how can we store data using local storage?

i could use cookies for that but too many disadvantages.

should i use JS to write/read data to local storage or is there a ws method for that?

thanx, ilan
 

ilan

Expert
Licensed User
Longtime User
EDIT: better solution on post #6 as recommended by @Erel

maybe some one will need it:

- create item to local storage
- get item from local storage
- remove item from local storage
- check if item exists in local storage
- get all items from local storage
- remove all items from local storage

B4X:
Public Sub setItemLS(ws As WebSocket, key As String, value As String)
    Dim js As String = $"localStorage.setItem("${key}", "${value}");"$
    ws.Eval(js,Null)
End Sub

Public Sub getItemLS(ws As WebSocket, key As String) As String
    Dim js As String = $"return localStorage.getItem("${key}");"$
    Dim f As Future = ws.EvalWithResult(js,Null)
    Return f.Value
End Sub

Public Sub removeItemLS(ws As WebSocket, key As String) As Boolean
    Try
        Dim js As String = $"localStorage.removeItem("${key}");"$
        ws.Eval(js,Null)
        Return True
    Catch
        Log(LastException)
        Return False
    End Try
End Sub

Public Sub itemExistsLS(ws As WebSocket, key As String) As Boolean
    Dim js As String = $"return localStorage.getItem("${key}");"$
    Dim f As Future = ws.EvalWithResult(js,Null)
    Return f.Value <> Null
End Sub

Public Sub getAllItemsLS(ws As WebSocket) As Map
    Dim js As String = $"return localStorage;"$
    Dim f As Future = ws.EvalWithResult(js,Null)
    Return f.Value
End Sub

Public Sub removeAllLS(ws As WebSocket) As Boolean
    Try
        Dim m As Map = getAllItemsLS(ws)
        For Each key As String In m.Keys
            removeItemLS(ws,key)
        Next
        Return True     
    Catch
        Log(LastException)
        Return False
    End Try
End Sub

execute example:

B4X:
setItemLS(ws,"name","ilan tal")

you can watch them on your browser under: Application -> Storage -> (relevant website) (right mouse click -> inspect)

1627550519616.png
 
Last edited:
Upvote 0

ilan

Expert
Licensed User
Longtime User
I would have returned Future from all these subs. Don't force a full round trip every call. It can take 500ms over the internet.

makes sense erel.

so what i do now, i create a class and in initialize i get all data from the local storage and work with it inside a map,
like this, it is getting the future only once and i can always call the refresh function to refresh the map again (if needed)

B4X:
Sub Class_Globals
    Private map As Map
    Private ls_ws As WebSocket
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(ws As WebSocket)
    map.Initialize
    ls_ws = ws
    refreshMap
End Sub

Public Sub refreshMap
    Dim js As String = $"return localStorage;"$
    If ls_ws.Open Then
        Dim f As Future = ls_ws.EvalWithResult(js,Null)
        map.Clear
        map = f.Value      
    End If
End Sub

Public Sub setItemLS(key As String, value As String)
    Dim js As String = $"localStorage.setItem("${key}", "${value}");"$
    If ls_ws.Open Then
        ls_ws.Eval(js,Null)
        map.Put(key,value)
    End If
End Sub

Public Sub getItemLS(key As String) As String
    Return map.Get(key)
End Sub

Public Sub removeItemLS(key As String) As Boolean
    Try
        Dim js As String = $"localStorage.removeItem("${key}");"$
        If ls_ws.Open Then
            ls_ws.Eval(js,Null)
            map.Remove(key)
            Return True      
        Else
            Return False          
        End If
    Catch
        Log(LastException)
        Return False
    End Try
End Sub

Public Sub itemExistsLS(key As String) As Boolean
    Return map.ContainsKey(key)
End Sub

Public Sub getAllItemsLS As Map
    Return map
End Sub

Public Sub removeAllLS As Boolean
    Try
        If ls_ws.Open Then
            For Each key As String In map.Keys
                removeItemLS(key)
            Next
            map.Clear
            Return True
        Else
            Return False  
        End If
    Catch
        Log(LastException)
        Return False
    End Try
End Sub

is this better?

thank you
 
Upvote 0
Top