Ask your JavaScript questions! Pay money and get answers fast! (more info)

Polling for new JSON data - Ajax/Jquery JavaScript

  • SOLVED

I have created a page where I need to poll for new data every few seconds. However I am new to JS and I can't quite get this to work. In Firefox it works perfect but in Chrome/Safari the page reloads "flickers" every couple seconds. To get rid of the flickering I removed the $('#do-work').html(''); but then all the items just re-append every few seconds making the page grow and grow with the same thumbs copied. The end result I want is simply to check if the API for new thumbnails and if they exists append them to the existing list of thumbs. Thanks for the help!

function refresh() {
$.ajax({
url: '{% url search_it %}apilist/{{ den.slug }}/',
success: function(data) {
$('#do-work').html('');
var obj = JSON.parse(data);
for(var key in obj){
if (obj.hasOwnProperty(key)){
var value=obj[key];
var thumb = {{ MEDIA_URL }} + value.fields.thumbnail + '.260x260_q85_crop.jpg'

$('#do-work').append('<img src="' + thumb +'" alt=""/>' + '<br/>');

}
}
}
});
}

$(function(){
setInterval("refresh()", 3000);
});


My JSON output:
[{"pk": 1140, "model": "open_image.article", "fields": {"news_website": 1, "description": "Cow!", "title": "Cow!", "created": "2013-02-01T19:12:53.260Z", "dens": [], "checker_runtime": 1179, "search_term": "cows", "thumbnail": "cows_7ade.jpg"}}, {"pk": 1141, "model": "open_image.article", "fields": {"news_website": 1, "description": "Cow", "title": "Cow", "created": "2013-02-01T19:12:53.260Z", "dens": [], "checker_runtime": 1180, "search_term": "cows", "thumbnail": "cows_11ea.jpg"}}, {"pk": 1142, "model": "open_image.article", "fields": {"news_website": 1, "description": "Cow traffic for miles", "title": "Cow traffic for miles", "created": "2013-02-01T19:12:53.260Z", "dens": [], "checker_runtime": 1181, "search_term": "cows", "thumbnail": "cows_dfff.jpg"}}, {"pk": 1143, "model": "open_image.article", "fields": {"news_website": 1, "description": "cow", "title": "cow", "created": "2013-02-01T19:12:53.260Z", "dens": [], "checker_runtime": 1182, "search_term": "cows", "thumbnail": "cows_40a2.jpg"}}]

HTML:
<div id="do-work">Loading Images..</div>

Answers (1)

2013-02-01

Rainner Lins answers:

<blockquote>check if the API for new thumbnails and if they exists append them to the existing list of thumbs.</blockquote>

Your code is running every 3 seconds and making the same request to the API over and over again, and getting the same response over and over again.

There needs to be some kind of logic involved to check if() there are any new images available. This is typically done on the server/API end.

I would pass back to JS, somewhere in the JSON string, the ID of the last image available, then use that ID to make a new request. The API would then look at the ID and see if() there are any new IDs after that one, then repeat the process with the latest ID, etc...

For this to work you'll need to make some changes to the server code...


function refresh( lastID )
{
var div = $('#do-work');
var html = '';

// get the latest ID, or default to 0
lastID = lastID || 0;

// the URL now passes the lastID back to the server/API
$.ajax({
url: '{% url search_it %}apilist/{{ den.slug }}/?id=' + lastID,
success: function(data)
{
var obj = JSON.parse(data);

// update last id with value back from server/API
lastID = ( obj.lastID ) ? parseInt( obj.lastID ) : lastID;

for(var key in obj)
{
if (obj.hasOwnProperty(key))
{
var value = obj[key];
var thumb = {{MEDIA_URL}} + value.fields.thumbnail + '.260x260_q85_crop.jpg';
html += '<img src="' + thumb +'" alt=""/> <br/> ';
}
}

// update page, add loop
if( html.length ) div.html( html );
setTimeout( function(){ refresh( lastID ); }, 5000 );
}
});
}

$(function()
{
// start the loop
refresh();
});



platinum01 comments:

Thanks for the response. If you see in the JSON code in the OP above each element of the dict has a PK id. When new items are added to the DB they are appended to the JSON dict. So, can you associated the PK with the LastId through iteration rather than a change server side?

Thanks.


Rainner Lins comments:

Hi, sorry for the delay.
Yes, it's possible to use the IDs in the JSON object to check for last ID.
I made some changes to the code and gave it a quick run, theoretically should work..



(function( $ )
{
window.IMGS = {};
IMGS.lastID = 0;
IMGS.Url = '{% url search_it %}apilist/{{ den.slug }}/';
IMGS.Refresh = function()
{
$.getJSON( IMGS.Url, function( data )
{
var obj = {};
var id = 0;
var html = '';

$.each( data, function()
{
obj = $( this ).get( 0 );
id = parseInt( obj.pk );
html += '<img src="{{ MEDIA_URL }}' + obj.fields.thumbnail + '.260x260_q85_crop.jpg" alt="" /> <br /> ';
});

// show new images only if last ID has changed
if( IMGS.lastID != id )
{
IMGS.lastID = id;
$( '#do-work' ).html( html );
}

// check again in 5 seconds
setTimeout( IMGS.Refresh, 5000 );
});
}
})( jQuery );


$(function()
{
// start the loop
IMGS.Refresh();
});


platinum01 comments:

Thanks, this seems to work as requested. But one issue I am having is when a new image is added in Chrome or Safari the browser takes you back to the top of the page. Is that because the Id do-work is reloading every time a new image is added?

Thanks again!