tags:

views:

1456

answers:

5

I'm using the following to grab some updated HTML and insert it into a div with id "content"

var updater = new Ajax.PeriodicalUpdater('content', '/Doc?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
  });

The problem is that when the server is shut down (it's running inside of an app that is modifying and server up the data), the updater then simply clears out the content div.

Is there a way to make it so that when PeriodicalUpdater times out, gets a 404, etc. it just leaves the content unchanged? I would rather that the last available data just stay there, not be erased.

A: 

you can add a onFailure option in the option list as the Ajax.PeriodicalUpdater inherits the properties of Ajax.Request (http://www.prototypejs.org/api/ajax/request)

In the opposite you may be more interested in the use of "onComplete" or any of the "Request life-cycle" in the link below

Vinze
A: 

@Vinze

According to the documentation, onFailure is "Invoked when a request completes and its status code exists but is not in the 2xy family. This is skipped if a code-specific callback is defined, and happens before onComplete."

But if the server was stopped, wouldn't it just time out and there be no status code at all? Maybe I'm understanding that wrong...

Adam Haile
should be a comment on my answer... I edited it but I really think you should look in the Prototype documentation for Request
Vinze
A: 

How about doing it all by yourself?

Start with a function that will call the update:

function requestMoreInfo(){
new Ajax.Request('url',
  {
    method:'get',
    parameters:  "someget=here",
    onSuccess: handleTheReturn
  });

}

Then create a function that will handle the answer from the server:

function handleTheReturn(reply){
    var newMessages = eval('(' + reply.responseText + ')');
    //update your element or whatever
}

And then run it every 20(or whatever) seconds with:

new PeriodicalExecuter(requestMoreInfo, 20);

Then just add a first requestMoreInfo to your onload function and your good to go... now to solve your problem, just validate the newMessages var in the handleTheReturn function and you can do anything you want(make the server send a JSON object to know is ok, or some other codes maybe, or search for the specific errors you want to avoid!

DFectuoso
Down vote? tell me why!
DFectuoso
Wrong, PeriodicalExecuter does exists : http://www.prototypejs.org/api/periodicalExecuter
Vinze
Even if you're right when you say it's probably not the easiest way to do that...
Vinze
yeah just saw that, still, Protoype provides a way to do this without extra code. Also, periodically executing asynchronous requests without checking for success or failure is problematic.
Triptych
@Triptych when you check for the error, you can stop the perodical executer o decide to change the delay.
DFectuoso
+1  A: 

Pass an object (not a string) as the first parameter to PeriodicalUpdater. The value keyed as 'success' will only be called on successful AJAX calls.

new Ajax.PeriodicalUpdater({success: 'content'}, '/Doc?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
  });

More on Ajax.Updater (from which PeriodicalUpdater inherits)

Triptych
A: 

For completeness, this is my entire code:

<html>
<head>
<title></title>
<script type="text/javascript" src="/Prototype"></script>
<script type="text/javascript">
var css;
var css_data;

function load_content()
{
  var d = new Date();

  css = document.createElement('style');
  css.setAttribute('type', 'text/css');
  if(css.styleSheet) { css.styleSheet.cssText = '';} //Because IE is evil
  else { css_data = document.createTextNode(''); css.appendChild(css_data); } //And everyone else is cool
  document.getElementsByTagName("head")[0].appendChild(css);

  var updater = new Ajax.PeriodicalUpdater({success: 'content'}, '/%doc_path%?'+d.getTime(),
  {
    method: 'post',
    frequency: 5,
    onSuccess: function(transport) {
          new Ajax.Request('/%css_path%?'+d.getTime(), {
              method: 'post',
              onSuccess: function(transport) {
                if(css.styleSheet) { css.styleSheet.cssText = transport.responseText}
                else { 
                    var new_css_data = document.createTextNode(transport.responseText);
                    css.replaceChild(new_css_data, css_data); 
                    css_data = new_css_data;
                } 
              }
          });
          new Ajax.Request('/%title_path%?'+d.getTime(), {
              method: 'post',
              onSuccess: function(transport) {
                document.title = transport.responseText;
              }
          });
    }
  });
}

</script>

</head>

<body>
<div id="content"></div>

<script type="text/javascript">
    load_content();
</script>

</body>
</html>

As you can see, I tried Triptych's solution...but still no go. It updates with blank data when the request fails still. Since I've got the whole thing here now, can anyone see any mistakes I'm making.

Note: Ignore the strings like %doc_path%... those are just control strings I use so that they can later be replaces programmatically with the proper path for each document...all stuff that's done on the server and really doesn't matter for this.

Adam Haile