Trying to reload data at setInterval but failing miserably

Trying to reload data at setInterval but failing miserably

tjyoungtjyoung Posts: 24Questions: 2Answers: 0
edited July 2011 in General
I've tried a thousand combinations and I'm sure i'm missing something elementary. I'm hoping someone can throw me a bone and point out the error of my ways.

I'm simply loading a txt file into the datatable and wish to reload that same txt file every 5 seconds (it changes from time to time).

This is what I've been trying:
[code]


$(document).ready(function() {
var oTable;
oTable = $('#example').dataTable( {
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"bProcessing": false,
"sAjaxSource": 'config/incoming_calls_array.txt'
} );
setInterval(function() { oTable.fnDraw; }, 5000);
} );

[/code]

Table works fine, shows up. Just never seems to reload.
Code further down in the body looks like this (nothing unusual):

[code]




Caller
City
Province
Phone










[/code]

Any help would be very much appreciated.
thanks, tj

Replies

  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    oTable.fnDraw(), not oTable.fnDraw
    [code]
    setInterval(function() { oTable.fnDraw(); }, 5000);
    [/code]

    else it's not running your function, just returning the object representing it

    (if you left out the function() part, it would have worked because you're passing the function object to setInterval:
    [code]
    setInterval(oTable.fnDraw, 5000);
    [/code] )
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Doesn't seem to be working with either solution. Ive posted a simplified version of what I have if you can take a look:
    http://www.phonedj.ca/demo/testing.php
  • GregPGregP Posts: 487Questions: 8Answers: 0
    edited July 2011
    I'm a bit of a luddite, but I get around it by using a new jQuery object and chained functions thus:

    [code]
    setInterval('$("#myTable").dataTable().fnDraw()', 5000);
    [/code]

    setInterval is an annoying function. It really just wants a string representation of your call as the first argument. That's when it's happiest. I've tried passing it objects and functions and none of it seems to work. Pass it a string as above and it seems to work. Who am I to argue?

    The above is a 'basic' example. In our application I've actually parameterized it quite heavily. As long as you're building a string as the first argument, and then setting the interval (we use a variable for that, too), you should be fine to do more dynamic stuff.

    I don't see any reason you couldn't try something similar with what you have, though:

    [code]
    setInterval('oTable.fnDraw()', 5000);
    [/code]

    It's still a string in the first argument, but tries to use the object you've already cached. Give it a go, though... worst thing that could happen is it doesn't work and you might have to give my uglier string method a go. ;-)
  • GregPGregP Posts: 487Questions: 8Answers: 0
    Forgot to show in my example that it's also good practice to use a variable name for setInterval so that you can clear it easily.
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Hi, thanks for the suggestion but either isn't working. Sample at: http://www.phonedj.ca/demo/testing.php

    In firebug console the setInterval isn't even firing with either solution.

    If I try something crazy like:
    setInterval('oTable.dataTable().fnDraw()', 5000);

    then at least the setInterval starts to fire but I get the message oTable.dataTable() is undefined (not surprisingly)
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    I took your code and it runs on my machine. The evidence is that if I click on another page, within 5 seconds, it is redrawn and I'm back to page 1.

    did you get it fixed by this morning?
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    @fbas
    You're right!. I never tried going to page 2 and seeing it reset. I've been changing the text file and looking for it to update in the grid. I'm guessing I now have a cache issue as I don't see any change in the data unless I reload the page.

    Any idea how to keep the text file from caching?
    Thanks!
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    1) do you run the server? you could specify cache settings for that file

    2) as a content author, you could just rename the file to some other extension that the server doesn't cache. TXT files are usually assumed to be static

    3) if you write your file as php, you can include headers that tell it not to cache:
    [code]
    <?php
    header("Cache-Control: no-cache");
    header("Expires: -1");
    ?>
    { "aaData": [
    ["Trident","Internet Explorer 4.0","Win 95+","4","X"],
    ["Trident","Internet Explorer 5.0","Win 95+","5","C"],
    ["Trident","Internet Explorer 5.5","Win 95+","5.5","A"],
    ["Trident","Internet Explorer 6","Win 98+","6","A"],
    ["Trident","Internet Explorer 7","Win XP SP2+","7","A"],
    ["Trident","AOL browser (AOL desktop)","Win XP","6","A"],
    // ... etc
    [/code]
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    and regarding the pagination change, you might want to use fnStandingRedraw to maintain the user's position

    http://datatables.net/plug-ins/api
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Brilliant. Many thanks!
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    edited July 2011
    Well, I thought I was out of the woods but guess not. The refresh is fine. I've switched the file to php and added the cache elements as above. But when the file changes, it doesn't reflect it in grid. I've even tried htaccess no cache technique to no avail.

    I'd give anything to figure this out. The updated sample is still at: http://www.phonedj.ca/demo/testing.php

    Is there any way to add a random number at the end of the file name? Would that help?
  • GregPGregP Posts: 487Questions: 8Answers: 0
    In jQuery's .ajax() method, there is another parameter that you can use:

    cache: false,

    Just plunk that in there and it will append a timestamp to each request. Cache busted!
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    edited July 2011
    Hi,
    Can you show me how to implement this based on what I have now?
    This is the sample page of where I'm currently at:

    [code]
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


    PhoneDJ



    @import "css/demo_page.css";
    @import "css/demo_table_jui.css";
    @import "css/custom-theme/jquery-ui-1.8.14.custom.css";








    $(document).ready(function() {

    var oTable = $("#example").dataTable( {
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "sAjaxSource": 'config/incoming_calls_array.php'
    } );
    var refresh = setInterval('$("#example").dataTable().fnDraw()', 5000);
    } );










    Caller
    City
    Province
    Phone











    [/code]

    and this is my php file I'm pulling in.

    [code]
    <?php
    header("Cache-Control: no-cache");
    header("Expires: -1");
    ?>

    { "aaData": [
    ["Trident","Internet Explorer 4.0","Win 95+","4","X"],
    ["Trident","Internet Explorer 5.0","Win 95+","5","C"],
    ["Trident","Internet Explorer 5.5","Win 95+","5.5","A"],
    ["Trident","Internet Explorer 6","Win 98+","6","A"],
    ["Trident","Internet Explorer 7","Win XP SP2+","7","A"],
    ["Trident","AOL browser (AOL desktop)","Win XP","6","A"],
    ["Gecko","Firefox 1.0","Win 98+ / OSX.2+","1.7","A"],
    ["Gecko","Firefox 1.5","Win 98+ / OSX.2+","1.8","A"],
    ["Gecko","Firefox 2.0","Win 98+ / OSX.2+","1.8","A"],
    ["Gecko","Firefox 3.0","Win 2k+ / OSX.3+","1.9","A"],
    ["Gecko","Camino 1.0","OSX.2+","1.8","A"],
    ["Gecko","Camino 1.5","OSX.3+","1.8","A"],
    ["Gecko","Netscape 7.2","Win 95+ / Mac OS 8.6-9.2","1.7","A"],
    ["Gecko","Netscape Browser 8","Win 98SE+","1.7","A"],
    ["Gecko","Netscape Navigator 9","Win 98+ / OSX.2+","1.8","A"],
    ["Gecko","Mozilla 1.0","Win 95+ / OSX.1+",1,"A"],
    ["Gecko","Mozilla 1.1","Win 95+ / OSX.1+",1.1,"A"],
    ["Gecko","Mozilla 1.2","Win 95+ / OSX.1+",1.2,"A"],
    ["Gecko","Mozilla 1.3","Win 95+ / OSX.1+",1.3,"A"],
    ["Gecko","Mozilla 1.4","Win 95+ / OSX.1+",1.4,"A"],
    ["Misc","PSP browser","PSP","-","C"],
    ["OtherS browsers","All others","-","-","U"]
    ] }

    [/code]
  • GregPGregP Posts: 487Questions: 8Answers: 0
    edited July 2011
    Something like this should work:

    [code]
    ...
    var oTable = $("#example").dataTable( {
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "sAjaxSource": 'config/incoming_calls_array.php',
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    $.ajax( {
    dataType: 'json',
    type: "GET",
    cache: false,
    url: sSource,
    data: aoData,
    success: fnCallback
    } )
    }
    } );
    ...
    [/code]

    The fnServerData just overrides the default .getJSON() method with the more generic .ajax, allowing you to throw in that cache parameter.

    The no-cache PHP bit becomes redundant, so you can get rid of it. Also, is that the PHP file in its entirety? Does that work? I always assumed the JSON would have to be echoed out, not just presented in-line, but I'm genuinely curious now!
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Hi,
    I've put your code in my sample page at: http://www.phonedj.ca/demo/testing.php
    I switched the php file to a simple text file since the php cache wasn't required
    Regardless, if I edit the text file and save it, it still doesn't change in the datatable.
    I have no idea why...

    ps. it was the php file in its entirety and it did load in the table just fine.
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    HI,
    Maybe I'm misunderstanding what the datatable can do: I"m trying to get it so each time the setInterval goes off it grabs a 'fresh' copy of the text file on the server. I am thinking that each time the setInterval goes off, it doesn't grab a new copy, it just loads the same one it got when the page initially loaded.

    Its not being cached since each time I reload the page manually it will reflect if any change has been made to the text file. It just doesn't reflect any changes when the setInterval is triggered.

    Is there some way of briefly clearing the table forcing it to get a fresh copy of the text file each time the setInterval is triggered?
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    you might be right. fnDraw might just redraw without grabbing content (you can confirm this by watching the debugger, seeing if it makes a network call)

    someone has written a plug-in API function fnReloadAjax()
    http://datatables.net/plug-ins/api

    [code]
    $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
    {
    if ( typeof sNewSource != 'undefined' && sNewSource != null )
    {
    oSettings.sAjaxSource = sNewSource;
    }
    this.oApi._fnProcessingDisplay( oSettings, true );
    var that = this;
    var iStart = oSettings._iDisplayStart;

    oSettings.fnServerData( oSettings.sAjaxSource, [], function(json) {
    /* Clear the old information from the table */
    that.oApi._fnClearTable( oSettings );

    /* Got the data - add it to the table */
    for ( var i=0 ; i
  • GregPGregP Posts: 487Questions: 8Answers: 0
    fnDraw should be grabbing the new data as well. But it's worth trying fbas' idea, too. What I noticed by going to the sample site is that the interval isn't being fired. But I don't see anything wrong with the setInterval code sample.

    I'll have to take it offline and run it on my server to debug. I'll let you know when I find anything.

    Cheers,
    Greg
  • allanallan Posts: 63,161Questions: 1Answers: 10,406 Site admin
    Hi all,

    Going back to the original question an the source from tj, to reload a json data source (Ajax sourced data as it is usually termed in DataTables) you want to use the fnReloadAjax plugin that fbas pointed out ( http://datatables.net/plug-ins/api#fnReloadAjax ). This is basically a wrapper function to make an Ajax call to the server to get new data, clear out the current table data and then add the newly loaded data.

    fnReloadAjax is required in thiscase as you are using client-side processing, not server-side. With client-side processing fnDraw just redraws the current data - it doesn't make an Ajax request since it doesn't need to.

    Thus once you have included your fnReloadAjax code all you need to do is this:

    [code]
    var oTable = $('#example').dataTable( { ... } );

    setInterval( function () {
    oTable.fnReloadAjax();
    }, 5000 );
    [/code]

    Regards,
    Allan
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    edited July 2011
    Oh my god... it works!
    Thanks everyone for your patience. Very much appreciated.
    Finally, can you tell me how to incorporate nStandingRedraw(); into it?
    Works great now but as mentioned above, the page skips back to page 1 every refresh.

    The code I'm using is:
    [code]
    var oTable;
    oTable = $('#example').dataTable( {
    "sPaginationType": "full_numbers",
    "bJQueryUI": true,
    "sAjaxSource": 'config/incoming_calls_array.txt',
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    /* Add some data to send to the source, and send as 'POST' */
    $.ajax( {
    "dataType": 'json',
    "type": "POST",
    "url": sSource,
    "cache": false,
    "data": aoData,
    "success": fnCallback
    } );
    }
    } );
    var newtimer = setInterval( function () {
    oTable.fnReloadAjax();
    }, 3000 );
    } );
    [/code]

    And I've included the fnReloadAjax() in an external js file.
    Promise to leave alone once I get this part done :)
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    [quote]tjyoung said: can you tell me how to incorporate nStandingRedraw(); into it?[/quote]

    [code]
    /* install an extension API function */
    $.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
    //redraw to account for filtering and sorting
    // concept here is that (for client side) there is a row got inserted at the end (for an add)
    // or when a record was modified it could be in the middle of the table
    // that is probably not supposed to be there - due to filtering / sorting
    // so we need to re process filtering and sorting
    // BUT - if it is server side - then this should be handled by the server - so skip this step
    if(oSettings.oFeatures.bServerSide === false){
    var before = oSettings._iDisplayStart;
    oSettings.oApi._fnReDraw(oSettings);
    //iDisplayStart has been reset to zero - so lets change it back
    oSettings._iDisplayStart = before;
    oSettings.oApi._fnCalculateEnd(oSettings);
    }

    //draw the 'current' page
    oSettings.oApi._fnDraw(oSettings);
    };


    $(document).ready( function () {
    var oTable;
    oTable = $('#example').dataTable( {
    "sPaginationType": "full_numbers",
    "bJQueryUI": true,
    "sAjaxSource": 'config/incoming_calls_array.txt',
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    /* Add some data to send to the source, and send as 'POST' */
    $.ajax( {
    "dataType": 'json',
    "type": "POST",
    "url": sSource,
    "cache": false, // HOORAY for cache = false!!
    "data": aoData,
    "success": fnCallback
    } );
    }
    } );
    var newtimer = setInterval( function () {
    oTable.fnStandingRedraw();
    }, 3000 );
    } );

    [/code]
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Sadly that doesn't work. It doesn't reflect any changes I make to the text file like before.
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    oh, I'm sorry. I used the wrong function. not standing redraw, ajax re whatever. totally my fault.

    here:
    [code]
    $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
    {
    if ( typeof sNewSource != 'undefined' && sNewSource != null )
    {
    oSettings.sAjaxSource = sNewSource;
    }
    this.oApi._fnProcessingDisplay( oSettings, true );
    var that = this;
    var iStart = oSettings._iDisplayStart;

    oSettings.fnServerData( oSettings.sAjaxSource, [], function(json) {
    /* Clear the old information from the table */
    that.oApi._fnClearTable( oSettings );

    /* Got the data - add it to the table */
    for ( var i=0 ; i
  • tjyoungtjyoung Posts: 24Questions: 2Answers: 0
    Hi, I guess there is already a redraw in the plugin and you simply need to set it to 'true' in order to make it work. I didn't know how to do that properly in the plugin's code so ended up reversing the conditional statement so it now reads:
    [code]
    if ( typeof bStandingRedraw == 'undefined' && bStandingRedraw != true )
    [/code]

    It works great but its not the proper way obviously. Can you tell me how you do that properly?
    tj
This discussion has been closed.