Search code examples
javascriptjquerydjangoipad

iPad not updating page using javascript (with Django backend)


I'm writing a script on a page that checks to see if specific parts of a page should update (based on information in the page passed in from the Django view). The updating works on browsers on computers / notebooks, but fails on browsers on iPads (and, based on my reading, I expect iPhones). It even works on my Pixel phone. So, it looks like this is a problem limited to iPads (and phones?).

At the moment, I am running on Django's dev server, if that has any bearing on the problem. From what I can see on the putty terminal, the iPad is making the request (there's a GET every 2 seconds), but I don't know what's happening on the iPad that nothing is updating. Both Safari and Chrome exhibit the same problem behavior. Last time I looked at this problem (with slightly different code) it was NOT a problem for Macbooks, just iPads.

---EDIT---

I'm now running on a production server. Still have the same problem. Looking at the access logs, I can see the requests coming in from the iPad, just no changes to the displayed page.


Here is the code in question:

HTML

{% block page_updates %}
<div class="container-fluid" id="last_times">
    <p style="display:none">Last action taken: <span id="actionTime">{{ update_times.action.isoformat }}</span></p>
    <p style="display:none">Last chat made: <span id="chatTime">{{ update_times.chat.isoformat }}</span></p>
</div>
<p style="display:none">Page last updated: <span id="updateTime"></span>
{% endblock %}

Javascript

<script>
function refresh_action_log(){
    var url_actions = document.URL + ' #action_log';
    var url_destiny = document.URL + ' #destiny_box';
    $('#action_log').load(url_actions);
    $('#destiny_box').load(url_destiny);
}
function refresh_chat_log() {
    var url_chat_log = document.URL + ' #chat_log';
    $('#chat_log').load(url_chat_log);
}
function check_and_update() {
    var pageUpdate = new Date(document.getElementById('updateTime').innerHTML);
    var actionUpdate = new Date($("#actionTime").text());
    var chatUpdate = new Date($("#chatTime").text());
    var now = new Date();
    if (actionUpdate > pageUpdate && chatUpdate > pageUpdate) {
        refresh_action_log();
        refresh_chat_log();
        // changing all of the .toLocaleString() to .toISOString() was the solution
        document.getElementById('updateTime').innerHTML = now.toLocaleString();  
    } else if (actionUpdate > pageUpdate) {
        refresh_action_log();
        document.getElementById('updateTime').innerHTML = now.toLocaleString();
    } else if (chatUpdate > pageUpdate) {
        refresh_chat_log();
        document.getElementById('updateTime').innerHTML = now.toLocaleString();
    };
}
function update_times() {
    var url_last_times = document.URL + ' #last_times';
    $('#last_times').load(url_last_times, function () {
        // When it loads, schedule the next request for 2s later
        setTimeout(update_times, 2000)
    });
    check_and_update();
};
$(function () {
    update_times();
    var dt = new Date();  // This line and the next were sitting in another function
    document.getElementById('updateTime').innerHTML = dt.toLocaleString();
})
</script>

Based on some other stack overflow questions, I have a hunch the problem is caching in the iPad.

Questions:

  1. Is this a caching problem?
  2. If so, how do I tell iPads to handle it?
  3. If not, what else should I be looking at?

EDIT:

Final solution: the iPad was reading the times incorrectly. I'll post an answer that goes into detail.


Solution

  • OK, riddle me this, Batman: Why do iPads not handle date strings the same way as everything else? After questioning everything (including my sanity), the problem was that, on the iPad, the Dates I was using to determine if the sections should be reloaded were invalid date types, while they worked just fine on everything else.

    So, to answer my questions:

    1. No
    2. N/A
    3. Time formatting.

    The solution was to turn all of the .toLocaleString() into .toISOString(). For reasons unbeknownst to me, the iPad wasn't able to read the updateTime back in, parse it into a Date object and compare it to the other times when the code used .toLocaleString() (even though all other devices could.)

    So, to reiterate, the iPad could not parse text from a Date object that had been put into .toLocaleString(), but it can if the text is in the ISOString format.