1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# NOTE: this examples does not yet fully work on pycafe # import solara import solara.lab from typing import Callable, Optional, cast counter = solara.reactive(cast(Optional[int], None)) @solara.lab.on_kernel_start def init_counter(): # issue with solara, we set cookies after we trigger the on_kernel_start print("cookies on kernel start", solara.lab.cookies.value) @solara.component_vue("cookiestore.vue") def CookieStore(key: str, value: str, on_value: Callable[[str], None] = None, debug: bool=False): ... def set_initial_value(value: str): counter.value = int(value) def increment(): counter.value += 1 def init_cookie_value(key): current = counter.peek() # peek is a non-reactive way to get the current value # Issue on py.cafe, cookies are never set if current is None and solara.lab.cookies.value is not None and key in solara.lab.cookies.value: assert solara.lab.cookies.value is not None print("setting initial value from cookie", key, solara.lab.cookies.value[key]) counter.value = int(solara.lab.cookies.value["my-counter"]) @solara.component def Page(): key = "my-counter" init_cookie_value(key) # NOTE: only on pycafe we get an initial render with counter.value None print("value on render", counter.value) CookieStore(key=key, value=str(counter.value), on_value=set_initial_value, debug=True) solara.Button(f"Clicks: {counter.value}", on_click=increment) solara.Markdown("Refresh the embedded page to see that we remember the counter value")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<template> <div> <div v-if="debug"> <div>{{key}}={{value}} </div> </div> <div v-else style="display: none"> </div> </div> </template> <script> module.exports = { created() { if(this.debug) { console.log("cookie store: created for", this.key, this.value); } const initialValue = this.readCookie() if(initialValue !== null) { if(this.debug) { console.log("found initial value for cookie store", this.key, "=", initialValue) } this.value = initialValue; } else { if(this.debug) { console.log("no initial value for cookie store", this.key) } this.writeCookie(); } }, methods: { readCookie() { const cookie = document.cookie.split('; ').find(row => row.startsWith(this.key + '=')); return cookie ? cookie.split('=')[1] : null; }, writeCookie() { if(this.debug) { if(this.value === null) { console.log("removing cookie"); } else { console.log("set cookie value to", this.value); } } let exp = new Date(new Date().setFullYear(new Date().getFullYear() + 10)).toUTCString() if(this.value === null) { // this will expire/remove the cookie exp = new Date(0).toUTCString() } document.cookie = `${this.key}=${this.value}; expires=${exp}`; if(this.cookie_written) { this.cookie_written() } } }, watch: { value(v) { this.writeCookie() } }, } </script>