Forums

Generated HTML not updating on front-end

I am using Plotly and Django to write a graph to an HTML file. I then use an XHR request to get that HTML and embed it in my HTML page. The correct graph loads on the first time but does not update on the front end after running the graphing function again. If I go to the file in PythonAnywhere it has changed, but it does not update on the front end.

I use this function to write the graph to the file

fig.write_html(".../plot.html", full_html=False)
return render(request, ".../plot.html")

What do you see in your browser dev tools?

Even if I don't use the request and just go to the URL that generates the graph and returns the plot it does not work. The graph generates on the first time but then that graph is returned every time, even if I change which graph I am generating. I go to the URL to change the graph and it returns the same HTML every time, but when I go to the file on pythonanywhere it has changed like it is supposed to.

There is nothing in the console

Do you see any errors in your web app's error log? (You should read them from the bottom)

There are no errors in the error log

I can put a long delay in between plotly writing the graph to HTML and the function returning the file that gives me enough time to check the actual file before it is returned. The actual file is updated but the returned file is not.

I don't see the code where you are reading the file. If you are not reading the file every time the html is requested, then the view will always return the html that it had from a previous write.

Another possibility is that the html is being cached by your browser. Check the network tab in your browser developer tools to see if that is what is happening.

I narrowed the problem down to just the Django view function by going straight to the URL that I was requesting with XHR, which did not work. I gave the last two lines which write the graph to HTML and the Django to display the page. I disabled cache in the network tab and it still does not work. This has worked before and still works on my local machine, I have just recently noticed it is no longer working on pythonanywhere.

You need to add some logging on both sides, frontend and backend, to make make sure step by step and line by line where the state of your system diverges from what you expect.

The problem occurs between

fig.write_html(".../plot.html", full_html=False)

and

return render(request, ".../plot.html")

I added

time.sleep(45)

between those two lines to check the file on pythonanywhere. In between those lines the file updates, but the displayed HTML does not update. Since the displayed HTML updates only after I reload the site from my dashboard, is it possible that the server is caching the HTML and not displaying the updated version but the cached version?

No, the server does not cache anything. Are you sure that the response from that view is being handled correctly in the browser? Use your browser developer tools to inspect the requests (in the network tab) and the console (for what the javascript is doing) to check what is happening to the response that is being sent.

The response in the network tab has the incorrect information. I tried deleting any cached files using Chrome's advanced browsing data tool, but that did not solve the problem. When I reload my website from the dashboard the correct graph is displayed.

In the network tab there is an indicator of whether the response was read from cache. In Chrome, it's in the Size column and in Firefox, it's in the Transfered column. Does that indicate that it was read from cache?

You can also check that the render call is actually reading the new file:

rendered = render(request, ".../plot.html")
print(rendered, file=sys.stderr)
return rendered

That will print the rendered html to your error log so you can see whether that is rendering from the new file.

In the network tab, it says xMB transferred over network. The printed output is

<HttpResponse status_code=200, "text/html; charset=utf-8">

Ah! I think I see the problem. Django caches templates when it first uses them, so it's not re-reading the template that you're using from the disk. I think you're going to need to come up with a different way to do what you're trying to do that does not involve using a template that you're changing. If the file that you're using is not being processed by Django, perhaps you can just serve it as a static file.

I rewrote the writing and displaying functions to avoid this and it works. Thanks, everyone.

Glad to hear that!