Don't change state of unchanged cards / allow "no ui-changes" serves
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 371
- Avg merge
- 26d 1h
- Merged PRs (30d)
- 1
Description
#### Wave SDK Version, OS
wave v0.17, ubuntu
#### Actual behavior
Given the following app, the textboxes get cleared even though the card is not changed after submit:
```python
@app('/')
async def serve(q: Q):
print("q.args", q.args)
if q.args.submit:
q.page['NEW_CARD'] = ui.form_card(box='1 5 4 4', items=[])
else:
q.page['example'] = ui.form_card(box='1 1 4 4', items=[
ui.textbox(name='textbox_01', label='textbox_01'),
ui.textbox(name='textbox_02', label='textbox_02'),
ui.button(name='submit', label='Submit', primary=True),
])
await q.page.save()
```
https://user-images.githubusercontent.com/6949295/132977337-59afb335-8aac-42fc-845f-7bcc23b6ad45.mp4
We also have been discussing the issue here:
https://h2oai.slack.com/archives/CPA21SSJH/p1631116412031900
#### Expected behavior
Citing @lo5 (from slack thread above)
> it shouldn't clear the textboxes. the 'example' form should continue to exist, and you should see a new form somewhere on the page.
#### Additional Context and related issues with using JS
A closely related issue appears when we use JS. Since we can't just return from the serve function without any changes to q.page (resulting in spinning wheel otherwise) dealing with JS can easily yield unintended behavior.
**Example**: Let's say we have a simple html with a `
But since we have the OP-issue that wont quite work. So we would need to check for changes between q.args and q.client|app first in order to be able to rebuild every card properly. This becomes easily a mess.
Okay, plan B: why not telling wave when the container content changes? That is, calling `wave.emit` on content change. Now this becomes a use-case for which we would like to return from **serve** without any UI changes. Something like:
```python
"""
btw is there a better way to write the following check?
Like checking q.events.container.changed_content directly is prone to run into NoneType not subscriptable,
but Expando doesn't seem to have a convenience method to scan for "2nd order" keys.
"""
if q.events.container and q.events.container.changed_content:
q.app.container_content = q.events.container.changed_content
return
```
=> spinning wheel
So I tried this hack:
```python
if q.events.container and q.events.container.changed_content:
q.app.container_content = q.events.container.content_changed
q.page['meta'].redirect = None # or ''
await q.page.save()
return
```
=> runs into OP issue, similar to this example app:
```python
from h2o_wave import main, app, Q, ui
@app('/')
async def serve(q: Q):
print("q.args", q.args)
if q.args.submit:
q.page['meta'].redirect = ""
else:
q.page['example'] = ui.form_card(box='1 1 4 4', items=[
ui.textbox(name='textbox_01', label='textbox_01'),
ui.textbox(name='textbox_02', label='textbox_02'),
ui.button(name='submit', label='Submit', primary=True),
])
await q.page.save()
```
https://user-images.githubusercontent.com/6949295/132979170-a7d8fd38-fad2-40ef-aa7c-a9fdd684cc34.mp4
> My expectation: q.args always contains the values for textbox_01 and textbox_02
Actual behavior: q.args only contains values of changed textbox values.
(also from slack thread above)
Contributor guide
Assessment
This issue has not been assessed yet.