Search code examples
javascriptpythonhtmlflaskjinja2

How can i get refreshed value of flask variable with JS and show in HTML template every 30 seconds?


This is a parking app which refresh the available parking slots every 30 seconds WITHOUT refreshing page.

This is my .py with the route and render template

@views.route('/')
def home():
    while True:
        try:
            token=getToken()
            if(token!='null' or token!=''):
                plazas=getInfo(token,parkingID)
        except:
            print('Error en la conexion')
            time.sleep(secs)      
                return render_template("home.html", plazas=plazas)

My HTML is:

  <script  src="{{ url_for('static', filename='js/main.js') }}"></script>
 <script type="text/javascript">
    myVar = setInterval(refresh,30000,{{plazas}});
  </script>
</head>
<title>Home</title>
</head>
    <body>
        <table>
            {% for parking in parkings %}
                <tr>
                    <td class="par"><img src={{parking.image}} alt="img"></td>
                    <td class="nombre">{{parking.nombre}}</td>
                    {% if plazas|int >= (totalplazas*30)/100 %}
                    <td class="num" style="color:#39FF00">
                    {{plazas}}</td>
                    {% elif plazas|int < 1%}
                    <td class="num" style="color:red"><p class="an">COMPLETO</p></td>
                    {% elif plazas|int <= (totalplazas*10)/100%}
                    <td class="num" style="color:red">
                    {{plazas}}</td>
                    {% else %}
                    <td class="num" style="color:yellow">
                    {{plazas}}</td>
                    {% endif %}
                    <td class="dir"><img src={{parking.direccion}} alt="img"></td>
                </tr>
            {% endfor %}
        </table>
    </body>
</html>

And my JS:

var elements = document.getElementsByClassName("num");
function refresh(pl){
    elements.innerHTML = pl;
}

My problem is that the {{plazas}} variable always takes the initial value and is not updated every 30 seconds even if i use while true: loop in my .py. Any help?


Solution

  • A simple solution would be to get the data by fetching it from javascript using await fetch(). You can then set up an updater by using setInterval().

    Flask

    @app.route('/refresh')
    def refresh();
      try:
        token=getToken()
        if(token!='null' or token!=''):
          plazas=getInfo(token,parkingID)
      except:
        return "Error refreshing!"
    

    Javascript

    var element = document.getElementsByClassName("num")
    
    async function reload() {
      // make a request to reload
      const promise = await fetch("/refresh")
      // get the text from the request, alternatively you can also use .json() to 
      // retrieve json
      const text = await promise.text()
      element.innerHTML = text
    }
    
    // refresh every 30 seconds
    window.onload = setInterval(reload, 30000)