tomdertech
tomdertech

Reputation: 507

Testing AJAX value in-line HTML with JINJA

I have a AJAX call to my flask server which returns data, I can then dynamically display the value in my html by using the ids of the html.

The problem is that I want to extend this so that depedning on the value returned I want to change the colour of the component in html.

I have tried implementing a conditional test in jinja but it is always failing the test.

AJAX

(function poll() {
    $.ajax({
        url: "/get_data",
        type: "GET",
        success: function(data) {
            console.log("polling");
            $("#press_switch").text(data.press_sw);
        },
        dataType: "json",
        complete: setTimeout(function() {poll()}, 1000),
        timeout: 500
    })
})();

HTML

<div class="row">
    <div class="col-sm-6">
        {% if press_switch == 1 %}
           <div class="alert alert-success" role="alert">OK</div>
        {% else %}
           <div class="alert alert-warning" role="alert">FAULT</div>
        {% endif %}
    </div>
</div>

I have tried testing 'press_switchandpress_swand testing for a string i.e.'1'rather than a numeric value, but I always get thefalse` condition.

Upvotes: 0

Views: 156

Answers (1)

Oerd
Oerd

Reputation: 2313

Disclaimer: from the question it's not clear when you want to change the components color. I'm assuming it's unconditionally whenever you press a button (that triggers the jQuery call). If you update your question let me know to change this accordingly.

When you do an asynchronous call in a web page (or ajax) you should be returning only a the intended value. This is usually not an html snippet as in your Jinja2 template.

I suggest that in your route (or view function) you add a check for asynchronous request and then only return the necessary value back to the client. On the client side, you have to update the elements color setting it to the received value.

What I mean would look something like the below snippets.

On flask side:

@app.route('/get_data')
def get_data_function():
    ...
    if request.args.get('to_ajax', False):
        # actually calculate return value
        return jsonify({'result': 'red'})
    ...

On client side:

(function poll() {
    $.ajax({
        url: "/get_data?to_ajax=1",
        type: "GET",
        success: function(data) {

            console.log("polling");
            var color = data.result ? "green" : "red";
            console.log("Received: ", data.result, " set to: ", color);
            $("#press_switch").css('color', color);
        },
        dataType: "json",
        complete: setTimeout(function() {poll()}, 1000),
        timeout: 500
    })
})();

Please note that:

  1. Flask has deprecated request.is_xhr because there is no deterministic way to know it's being called asynchronously - this is why I've added a ?is_ajax=1 to the query parameters (and check for that on the backend).
  2. When you actually receive the request on the client side you have to take action on that, so on the success function you need to change your components color setting it to the received value.

Upvotes: 1

Related Questions