Initializing function.

Please help me make an initializing function. I'm using the solara.use_router().search function to get a data. For example, I use this data as values in solara.Select. I have a problem that after changing the value in select and clicking the button, the value returns to the one I set during initialization. Therefore, I want to write a function that will be called only once when first launched, receive data, write it to several solara.reactive (I have a lot of them), and then not run.
8 Replies
MaartenBreddels
MaartenBreddels2mo ago
In a component you can use https://solara.dev/documentation/api/hooks/use_effect If you use it for the intial state of use_reactive, you can also consider using https://solara.dev/documentation/api/hooks/use_memo Hope this helps, otherwise please share the code. Regards,
icecream4
icecream42mo ago
Right now my code looks like this. And I don’t know how to separate initialization using data into a separate function.
import f1, а2

text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_value = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

def on_click():
c_value = f1(a_value, b_value)
...

def collect_data(query_string):
# Parsing strings and get data from database
...


@solara.component
def Page():
query_string = solara.use_router().search

data = collect_data(query_string)

text.value = f"Default text: {data["text"]}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Button(label="CLICK", on_click=on_click)
...
import f1, а2

text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_value = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

def on_click():
c_value = f1(a_value, b_value)
...

def collect_data(query_string):
# Parsing strings and get data from database
...


@solara.component
def Page():
query_string = solara.use_router().search

data = collect_data(query_string)

text.value = f"Default text: {data["text"]}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Button(label="CLICK", on_click=on_click)
...
MaartenBreddels
MaartenBreddels2mo ago
if you put all that initialization code in a function that gets called by use_effect, it will only be called once, does that make sense?
icecream4
icecream42mo ago
Yes it does, but for some reason it didn't work out for me. I made this code:
def start():
...

@solara.component
def Page():
solara.use_effect(start)
...
def start():
...

@solara.component
def Page():
solara.use_effect(start)
...
It seems that the "start" function is not called because no one reactive variable is filled.
MaartenBreddels
MaartenBreddels2mo ago
you should do use_effect(start, dependencies=[]) otherwise it will stil run on each render. I guess looking at the rest of the code you might want to do the following for correctness (although I don't think query_string can change in your case): solara.use_effect(lambda: start(query_string), dependencies=[query_string])
icecream4
icecream42mo ago
Hmm, thank you. I tried to rewrite my code here. And it turns out that my error is slightly different:
text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_values = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

res_value = solara.reactive(None)
btn = solara.reactive(False)

def on_click():
res_value.value = a_value.value + b_value.value
btn.value = True

def collect_data():
return {
"text": "aaa",
"a": {"a":"a", "b":"b", "c":"c"},
"b": {"d":"d", "e":"e", "f":"f"},
"c": "c",
"d": "d",
"e": "e",
"f": "f",
"g": "g",
}


def f2(data):
return (data["d"], data["e"], data["f"], data["g"])


def start():
data = collect_data()

text.value = f"Default text: {data['text']}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

c_values.value = {i:solara.use_reactive(False) for i in data["b"]}

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)


@solara.component
def Page():
solara.use_effect(start, dependencies=[])

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Markdown("Switch:")
toggle = [
solara.Switch(label=label, value=c_values.value[label])
for label in c_values.value]

solara.Button(label="CLICK", on_click=on_click)

if btn.value:
solara.Markdown(res_value.value)

Page()
text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_values = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

res_value = solara.reactive(None)
btn = solara.reactive(False)

def on_click():
res_value.value = a_value.value + b_value.value
btn.value = True

def collect_data():
return {
"text": "aaa",
"a": {"a":"a", "b":"b", "c":"c"},
"b": {"d":"d", "e":"e", "f":"f"},
"c": "c",
"d": "d",
"e": "e",
"f": "f",
"g": "g",
}


def f2(data):
return (data["d"], data["e"], data["f"], data["g"])


def start():
data = collect_data()

text.value = f"Default text: {data['text']}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

c_values.value = {i:solara.use_reactive(False) for i in data["b"]}

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)


@solara.component
def Page():
solara.use_effect(start, dependencies=[])

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Markdown("Switch:")
toggle = [
solara.Switch(label=label, value=c_values.value[label])
for label in c_values.value]

solara.Button(label="CLICK", on_click=on_click)

if btn.value:
solara.Markdown(res_value.value)

Page()
Can you please take a look at it, it seems like I'm trying to use the Switch incorrectly.
MaartenBreddels
MaartenBreddels2mo ago
you cannot use use_reactive in a loop like this, you should use solara.reactive(). Also use_effect executes after the function returns, so c_values.values is still empty, you could use use_memo in this case:
import solara
text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_values = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

res_value = solara.reactive(None)
btn = solara.reactive(False)

def on_click():
res_value.value = a_value.value + b_value.value
btn.value = True

def collect_data():
return {
"text": "aaa",
"a": {"a":"a", "b":"b", "c":"c"},
"b": {"d":"d", "e":"e", "f":"f"},
"c": "c",
"d": "d",
"e": "e",
"f": "f",
"g": "g",
}


def f2(data):
return (data["d"], data["e"], data["f"], data["g"])


def start():
data = collect_data()

text.value = f"Default text: {data['text']}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

c_values.value = {i:solara.reactive(False) for i in data["b"]}

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)


@solara.component
def Page():
solara.use_memo(start, dependencies=[])

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Markdown("Switch:")
toggle = [
solara.Switch(label=label, value=c_values.value[label])
for label in c_values.value]

solara.Button(label="CLICK", on_click=on_click)

if btn.value:
solara.Markdown(res_value.value)

Page()
import solara
text = solara.reactive(None)

a_values = solara.reactive(None)
a_value = solara.reactive(None)

b_values = solara.reactive(None)
b_value = solara.reactive(None)

c_values = solara.reactive(None)
d_value = solara.reactive(None)
e_value = solara.reactive(None)
f_value = solara.reactive(None)
g_value = solara.reactive(None)

res_value = solara.reactive(None)
btn = solara.reactive(False)

def on_click():
res_value.value = a_value.value + b_value.value
btn.value = True

def collect_data():
return {
"text": "aaa",
"a": {"a":"a", "b":"b", "c":"c"},
"b": {"d":"d", "e":"e", "f":"f"},
"c": "c",
"d": "d",
"e": "e",
"f": "f",
"g": "g",
}


def f2(data):
return (data["d"], data["e"], data["f"], data["g"])


def start():
data = collect_data()

text.value = f"Default text: {data['text']}"

solara.InputText(label="Text:", value=text, continuous_update=True)

a_values.value = list(data["a"].keys())
a_value.value = a_values.value[0]

b_values.value = list(data["b"].keys())
b_value.value = b_values.value[0]

c_values.value = {i:solara.reactive(False) for i in data["b"]}

(d_value.value, e_value.value, f_value.value, g_value.value) = f2(data)


@solara.component
def Page():
solara.use_memo(start, dependencies=[])

solara.Select(label="Select:", value=a_value, values=a_values.value)
solara.Select(label="Select:", value=b_value, values=b_values.value)

solara.Markdown("Switch:")
toggle = [
solara.Switch(label=label, value=c_values.value[label])
for label in c_values.value]

solara.Button(label="CLICK", on_click=on_click)

if btn.value:
solara.Markdown(res_value.value)

Page()
Run and edit this code snippet at PyCafe
icecream4
icecream42mo ago
Thank you very much. Yes, it seems to be working now, I'll go check everything 🙂