浏览代码

Get Local Storage (#1234)

Elijah Ahianyo 1 年之前
父节点
当前提交
3f56620870
共有 5 个文件被更改,包括 110 次插入1 次删除
  1. 17 0
      pynecone/.templates/web/utils/state.js
  2. 1 0
      pynecone/__init__.py
  3. 1 0
      pynecone/compiler/compiler.py
  4. 23 0
      pynecone/vars.py
  5. 68 1
      tests/test_var.py

+ 17 - 0
pynecone/.templates/web/utils/state.js

@@ -76,6 +76,23 @@ export const applyDelta = (state, delta) => {
   }
 };
 
+
+/**
+ * Get all local storage items in a key-value object.
+ * @returns object of items in local storage.
+ */
+export const getAllLocalStorageItems = () => {
+  var localStorageItems = {};
+
+  for (var i = 0, len = localStorage.length; i < len; i++) {
+    var key = localStorage.key(i);
+    localStorageItems[key] = localStorage.getItem(key);
+  }
+
+  return localStorageItems;
+}
+
+
 /**
  * Send an event to the server.
  * @param event The event to send.

+ 1 - 0
pynecone/__init__.py

@@ -38,3 +38,4 @@ from .style import color_mode as color_mode
 from .style import toggle_color_mode as toggle_color_mode
 from .vars import Var as Var
 from .vars import cached_var as cached_var
+from .vars import get_local_storage as get_local_storage

+ 1 - 0
pynecone/compiler/compiler.py

@@ -30,6 +30,7 @@ DEFAULT_IMPORTS: imports.ImportDict = {
         ImportVar(tag="preventDefault"),
         ImportVar(tag="refs"),
         ImportVar(tag="getRefValue"),
+        ImportVar(tag="getAllLocalStorageItems"),
     },
     "": {ImportVar(tag="focus-visible/dist/focus-visible")},
     "@chakra-ui/react": {

+ 23 - 0
pynecone/vars.py

@@ -1133,3 +1133,26 @@ class ImportVar(Base):
             The hash of the var.
         """
         return hash((self.tag, self.is_default, self.alias))
+
+
+def get_local_storage(key: Optional[Union[Var, str]] = None) -> BaseVar:
+    """Provide a base var as payload to get local storage item(s).
+
+    Args:
+        key: Key to obtain value in the local storage.
+
+    Returns:
+        A BaseVar of the local storage method/function to call.
+
+    Raises:
+        TypeError:  if the wrong key type is provided.
+    """
+    if key:
+        if not (isinstance(key, Var) and key.type_ == str) and not isinstance(key, str):
+            type_ = type(key) if not isinstance(key, Var) else key.type_
+            raise TypeError(
+                f"Local storage keys can only be of type `str` or `var` of type `str`. Got `{type_}` instead."
+            )
+        key = key.full_name if isinstance(key, Var) else format.wrap(key, "'")
+        return BaseVar(name=f"localStorage.getItem({key})", type_=str)
+    return BaseVar(name="getAllLocalStorageItems()", type_=Dict)

+ 68 - 1
tests/test_var.py

@@ -6,7 +6,15 @@ import pytest
 
 from pynecone.base import Base
 from pynecone.state import State
-from pynecone.vars import BaseVar, ComputedVar, ImportVar, PCDict, PCList, Var
+from pynecone.vars import (
+    BaseVar,
+    ComputedVar,
+    ImportVar,
+    PCDict,
+    PCList,
+    Var,
+    get_local_storage,
+)
 
 test_vars = [
     BaseVar(name="prop1", type_=int),
@@ -19,6 +27,12 @@ test_vars = [
 test_import_vars = [ImportVar(tag="DataGrid"), ImportVar(tag="DataGrid", alias="Grid")]
 
 
+class BaseState(State):
+    """A Test State."""
+
+    val: str = "key"
+
+
 @pytest.fixture
 def TestObj():
     class TestObj(Base):
@@ -394,3 +408,56 @@ def test_import_var(import_var, expected):
         expected: expected name
     """
     assert import_var.name == expected
+
+
+@pytest.mark.parametrize(
+    "key, expected",
+    [
+        ("test_key", BaseVar(name="localStorage.getItem('test_key')", type_=str)),
+        (
+            BaseVar(name="key_var", type_=str),
+            BaseVar(name="localStorage.getItem(key_var)", type_=str),
+        ),
+        (
+            BaseState.val,
+            BaseVar(name="localStorage.getItem(base_state.val)", type_=str),
+        ),
+        (None, BaseVar(name="getAllLocalStorageItems()", type_=Dict)),
+    ],
+)
+def test_get_local_storage(key, expected):
+    """Test that the right BaseVar is return when get_local_storage is called.
+
+    Args:
+        key: Local storage key.
+        expected: expected BaseVar.
+
+    """
+    local_storage = get_local_storage(key)
+    assert local_storage.name == expected.name
+    assert local_storage.type_ == expected.type_
+
+
+@pytest.mark.parametrize(
+    "key",
+    [
+        ["list", "values"],
+        {"name": "dict"},
+        10,
+        BaseVar(name="key_var", type_=List),
+        BaseVar(name="key_var", type_=Dict[str, str]),
+    ],
+)
+def test_get_local_storage_raise_error(key):
+    """Test that a type error is thrown when the wrong key type is provided.
+
+    Args:
+        key: Local storage key.
+    """
+    with pytest.raises(TypeError) as err:
+        get_local_storage(key)
+    type_ = type(key) if not isinstance(key, Var) else key.type_
+    assert (
+        err.value.args[0]
+        == f"Local storage keys can only be of type `str` or `var` of type `str`. Got `{type_}` instead."
+    )