miguelgrinberg / turbo-flask

Integration of Hotwire's Turbo library with Flask.
MIT License
301 stars 35 forks source link

Flask not serving, as soon as turbo is added. Page never loads #27

Closed reghardtp closed 2 years ago

reghardtp commented 2 years ago

Hi,

So the basic example on the blog post works in full. Updates come through.

I have tried to update this example to replace a list of data, instead of three variables. The template works and renders perfectly. However, as soon as I try to update the list of data, the page never loads.

I have tried a bunch of different ways of getting this done, but none are working.

@app.context_processor
def update_data():
    with app.app_context():
        readings_data.append({'ts': '2021-01-01', 'rms_1': 124.12, 'rms_2': 14.124})
        while True:
            time.sleep(5)
            turbo.push(turbo.replace(render_template('loadavg.html', reading_data=tuple(readings_data)), target='reading_data_id'))

template:

<div id="reading_data_id" class="load">
  <table>
    <tr><th>ts</th><th>RMS1</th><th>RMS2</th></tr>
    {% for reading in reading_data %}
    <tr><th>{{ reading.ts }}</th><td>{{ reading.rms_1 }}</td><td>{{ reading.rms_2 }}</td></tr>
    {% endfor %}
    <!-- {{ reading_data }} -->
  </table>
</div>

Remove this function, and the template renders first time.

any help would be great, thanks!

miguelgrinberg commented 2 years ago

You are passing the data to the template in a variable called reading_data. I don't see that variable being used in the template code, you only have it in a commented section, actually.

reghardtp commented 2 years ago

Hi Miguel! Thanks for the really quick reply, appreciate it!

I friend helped me out to resolve this issue. I was decorating the update_data() function as a app.context_processor, while internal to the function I was handling the app context directly. Removing the decorator resolved the issue.

Thanks!

reghardtp commented 2 years ago

`@app.before_first_request def before_first_request(): threading.Thread(target=update_data).start()

def update_data(): with app.app_context(): while True: time.sleep(2) turbo.push(turbo.replace(render_template('loadavg.html', reading_data=readings_data), target='reading_data_id'))`

where the readings_data list is updated async in a different request.

In the loadavg.html template:

`

{% for reading in reading_data %} {% endfor %}
tsRMS1RMS2
{{ reading.ts }}{{ reading.data_1 }}{{ reading.data_2 }}

`