I am making JS
Ajax
call to update the contents of a page every 2 seconds. To do this I am using setInterval
method. I have noticed that my setInterval
method executed twice and as a result i get duplicate output. Check the images for reference.
My Flask backend - routes.py
@app.route('/image/<im>')
@login_required
def image(im):
image_src=[im+'/'+i for i in os.listdir(os.path.join(app.static_folder,im))]
rows=math.ceil(len(image_src)/3)
print(image_src)
return render_template('dashboard.html',title='Welcome',images=image_src,rows=rows,image_date=im)
My HTML - dashboard.html
{% extends "base.html" %}
{% block content %}
<div class="image-area">
<div class="container dash-container main-body" >
<hr>
<div class="row">
<br>
<hr >
<br>
<div class="col-md-12">
<div class="jumbotron ">
<h1 id="hdr">DASHBOARD</h1>
</div>
</div>
</div>
{% if images %}
<div class="row" id="info">
<a href="{{ url_for('dashboard') }}"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></a>
</div>
<br><br>
<div class="row">
<div class="col-md-12" id="info">
{% set ns = namespace(counter=0) %}
<table class="table table-hover table-condensed table-bordered images-table" cellspacing="5" cellpadding="5">
{% for row in range(rows) %}
<tr class="image-hover">
{% for data in range(3) %}
{% if ns.counter < images|length %}
<td style="width:10%;">
<a href="{{ url_for('display',file=images[ns.counter][10:],folder=images[ns.counter][0:10]) }}"><img src="{{ url_for('static',filename=images[ns.counter]) }}" alt="User Image" width="200" height="180"></a>
<br>
{% set ns.counter = ns.counter + 1 %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
</div>
</div>
<script type="text/javascript">
var first_time = 0;
var current_count = 0;
var total_count = 0;
function update(){
if (window.first_time == 0){
window.current_count = $('td').length;
window.total_count = window.current_count;
window.first_time = 1;
//var txt = $("<p class='notify'></p>").text("No new images");
$('body').append("<p class='notify'>No new images</p>");
}
else {
window.total_count = $('td').length;
if (window.total_count>window.current_count){
$('.notify').text(window.total_count-window.current_count + " images added !");
$('html, body').animate({scrollTop:$(document).height()}, 'slow');
//window.alert(total_count-current_count + ' images added !');
window.current_count = window.total_count;
}
}
}
setInterval(function(){ $('.image-area').load("{{ url_for('image',im=image_date) }}"); update(); }, 2000);
</script>
{% endblock %}
base.HTML
-
<!DOCTYPE html>
<html>
<head>
{{ moment.include_jquery() }}
{{ moment.include_moment() }}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/base.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/about.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/index.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/dashboard.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/display.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/feedback.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/login.css') }}">
<link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">
{% if title %}
<title>{{ title }}</title>
{% else %}
<title>Welcome_segregator</title>
{% endif %}
</head>
<body>
<nav class="navbar navbar-fixed-top navbar-custom">
<div class="container" >
<div class="navbar-header">
{% if current_user.username %}
<a class="navbar-brand nav-custom" href="{{ url_for('index') }}" ><span id="header"><span id="logo"><strong>Welcome </strong></span id="header"><strong>{{ current_user.username|striptags }} !</strong></span></a>
{% else %}
<a class="navbar-brand nav-custom" href="{{ url_for('index') }}"><span id="header"><span id="logo"><strong>Welcome </strong></span></span></a>
{% endif %}
</div>
<ul class="nav navbar-nav navbar-right " >
<li class="nav-custom"><a class="nav navbar-nav" href="{{ url_for('index') }}"><span class="glyphicon glyphicon-home "> <span id="header"><strong>Home</strong></span></a></li>
<li><a class="nav navbar-nav" href="{{ url_for('dashboard') }}"><span class="glyphicon glyphicon-dashboard"> <span id="header"><strong>Dashboard</strong></span></a></li>
<li><a class="nav navbar-nav" href="{{ url_for('about') }}"><span class="glyphicon glyphicon-user"> <span id="header"><strong>About Us</strong></span></a></li>
<li><a class="nav navbar-nav" href="{{ url_for('feedback') }}"><span class="glyphicon glyphicon-pencil"> <span id="header"><strong>Feedback</strong></span></a></li>
{% if current_user.is_anonymous %}
<li><a class="nav navbar-nav" href="{{ url_for('login') }}"><span class="glyphicon glyphicon-log-in"> <span id="header"><strong>Login</strong></span></a></li>
{% else %}
<li><a class="nav navbar-nav" href="{{ url_for('logout') }}"><span class="glyphicon glyphicon-off"> <span id="header"><strong>Logout</strong></span></a></li>
{% endif %}
</ul>
</div>
</nav>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
The setInterval
method updates the page every 2 seconds and then calls the update()
function. update function implements a custom notification at the end of the HTML file which notifies the user if there is any new item. As you can see in Image 1 and 2 , the notifications are being delivered twice on the page.
IMPORTANT :- The duplicate values are not being added immediately. For the case when there is no new image, the message "No new images" is added after 2 seconds i.e there is a gap of 2 seconds between the display of duplicate "No new images". However, when there is a new image , then instead of the duplicates arriving 2 seconds later, they get added at the same time. i.e the message "5 images added" and its duplicate version arrive at the screen at the same time.
Notice the duplicate message updated at the bottom.
Notice the duplicates at the bottom. Here 5 new images were added to the dashboard and so notification is 5 which is correct but the display is duplicated.
I want the notifications to be displayed only once. Please help.
EDIT 1: - Here is the complete rendered HTML
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
<script>
moment.locale("en");
function flask_moment_render(elem) {
$(elem).text(eval('moment("' + $(elem).data('timestamp') + '").' + $(elem).data('format') + ';'));
$(elem).removeClass('flask-moment').show();
}
function flask_moment_render_all() {
$('.flask-moment').each(function() {
flask_moment_render(this);
if ($(this).data('refresh')) {
(function(elem, interval) { setInterval(function() { flask_moment_render(elem) }, interval); })(this, $(this).data('refresh'));
}
})
}
$(document).ready(function() {
flask_moment_render_all();
});
</script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="/static/styles/base.css">
<link rel="stylesheet" type="text/css" href="/static/styles/about.css">
<link rel="stylesheet" type="text/css" href="/static/styles/index.css">
<link rel="stylesheet" type="text/css" href="/static/styles/dashboard.css">
<link rel="stylesheet" type="text/css" href="/static/styles/display.css">
<link rel="stylesheet" type="text/css" href="/static/styles/feedback.css">
<link rel="stylesheet" type="text/css" href="/static/styles/login.css">
<link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">
<title>Welcome</title>
</head>
<body>
<nav class="navbar navbar-fixed-top navbar-custom">
<div class="container" >
<div class="navbar-header">
<a class="navbar-brand nav-custom" href="/index" ><span id="header"><span id="logo"><strong>Welcome </strong></span id="header"><strong>dev !</strong></span></a>
</div>
<ul class="nav navbar-nav navbar-right " >
<li class="nav-custom"><a class="nav navbar-nav" href="/index"><span class="glyphicon glyphicon-home "> <span id="header"><strong>Home</strong></span></a></li>
<li><a class="nav navbar-nav" href="/dashboard"><span class="glyphicon glyphicon-dashboard"> <span id="header"><strong>Dashboard</strong></span></a></li>
<li><a class="nav navbar-nav" href="/about"><span class="glyphicon glyphicon-user"> <span id="header"><strong>About Us</strong></span></a></li>
<li><a class="nav navbar-nav" href="/feedback"><span class="glyphicon glyphicon-pencil"> <span id="header"><strong>Feedback</strong></span></a></li>
<li><a class="nav navbar-nav" href="/logout"><span class="glyphicon glyphicon-off"> <span id="header"><strong>Logout</strong></span></a></li>
</ul>
</div>
</nav>
<div class="image-area">
<div class="container dash-container main-body" >
<hr>
<div class="row">
<br>
<hr >
<br>
<div class="col-md-12">
<div class="jumbotron ">
<h1 id="hdr">DASHBOARD</h1>
</div>
</div>
</div>
<div class="row" id="info">
<a href="/dashboard"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></a>
</div>
<br><br>
<div class="row">
<div class="col-md-12" id="info">
<table class="table table-hover table-condensed table-bordered images-table" cellspacing="5" cellpadding="5">
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-18-39+PM_0.9997674822807312_0.0002324927772860974_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-18-39%20PM_0.9997674822807312_0.0002324927772860974_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-19-26+PM_0.0011277222074568272_0.9988722205162048_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-19-26%20PM_0.0011277222074568272_0.9988722205162048_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-19-47+PM_0.9632670283317566_0.03673300892114639_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-19-47%20PM_0.9632670283317566_0.03673300892114639_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-20-31+PM_0.7819413542747498_0.21805864572525024_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-20-31%20PM_0.7819413542747498_0.21805864572525024_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-20-53+PM_0.03425532579421997_0.96574467420578_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-20-53%20PM_0.03425532579421997_0.96574467420578_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-23-59+PM_6.910012757543882e-07_0.9999992847442627_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-23-59%20PM_6.910012757543882e-07_0.9999992847442627_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_02-24-21+PM_0.0027463394217193127_0.9972537159919739_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-24-21%20PM_0.0027463394217193127_0.9972537159919739_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_03-27-32+PM_0.8725430369377136_0.1274568885564804_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_03-27-32%20PM_0.8725430369377136_0.1274568885564804_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-23-40+PM_0.9983899593353271_0.0016100991051644087_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-23-40%20PM_0.9983899593353271_0.0016100991051644087_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-24-43+PM_0.014673426747322083_0.9853265285491943_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-24-43%20PM_0.014673426747322083_0.9853265285491943_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-25-37+PM_0.028937892988324165_0.9710620641708374_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-25-37%20PM_0.028937892988324165_0.9710620641708374_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-26-08+PM_0.10836496949195862_0.8916350603103638_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-26-08%20PM_0.10836496949195862_0.8916350603103638_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-26-56+PM_0.9980469942092896_0.0019529901910573244_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-26-56%20PM_0.9980469942092896_0.0019529901910573244_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-27-32+PM_0.0008696855511516333_0.9991303086280823_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-27-32%20PM_0.0008696855511516333_0.9991303086280823_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-28-29+PM_0.9541159868240356_0.04588397219777107_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-28-29%20PM_0.9541159868240356_0.04588397219777107_bio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
<tr class="image-hover">
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-29-03+PM_0.0024711675941944122_0.9975288510322571_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-29-03%20PM_0.0024711675941944122_0.9975288510322571_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
<td style="width:10%;">
<a href="/display?folder=07-05-2018&file=%2F07-05-18_04-29-25+PM_0.033340130001306534_0.9666599035263062_nonbio_+-+Copy+-+Copy+-+Copy+-+Copy+-+Copy+%282%29+-+Copy+-+Copy+-+Copy+-+Copy+-+Copy.jpeg"><img src="/static/07-05-2018/07-05-18_04-29-25%20PM_0.033340130001306534_0.9666599035263062_nonbio_%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20%282%29%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy.jpeg" alt="User Image" width="200" height="180"></a>
<br>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var first_time = 0;
var current_count = 0;
var total_count = 0;
function update(){
if (window.first_time == 0){
window.current_count = $('td').length;
window.total_count = window.current_count;
window.first_time = 1;
//var txt = $("<p class='notify'></p>").text("No new images");
$('body').append("<p class='notify'>No new images</p>");
}
else {
window.total_count = $('td').length;
if (window.total_count>window.current_count){
$('.notify').text(window.total_count-window.current_count + " images added !");
$('html, body').animate({scrollTop:$(document).height()}, 'slow');
//window.alert(total_count-current_count + ' images added !');
window.current_count = window.total_count;
}
}
}
setInterval(function(){ $('.image-area').load("/image/07-05-2018"); update(); }, 2000);
</script>
</body>
</html>