I'm kind of new to JavaScript, I know the basic syntax and how it works but I've been hit with this problem that I can't seem to solve...

I use the following code to call a file which gets the RSS feed from one site.

<html>
<head>
<script type="text/javascript">
function showRSS(url)
{
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("rssOutput").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","getrss.php?q="+url,true);
xmlhttp.send();
}

window.onload=showRSS("http://www.urlwithrss.com/rss");
</script>
</head>
<body>

<div id="rssOutput">RSS-feed will be listed here...</div>

/*the following line isn't in the code but is what I would like to be able to do
<div id="rssOutput2">Another RSS-feed will be listed here...</div>
*/


</body>
</html>

However I would like to pass as perimeter two separate urls, (both when the page loads) from which the information should be displayed in a different place on the page, not in the same div as above. I've tried several methods of fixing this which I think are best not to mention since my explanations can get confusing but the main problem I seem to come up with was calling the same function twice, it would only execute the last one even if I did window.onload=rssOutput; rssOutput2; where rssOutput2 was a copy of the original function and many other methods suggested online. If anyone can help me in getting this done then it would be appreciated greatly.

Recommended Answers

All 8 Replies

Asif, you have done 98% of the work and the final 2% is quite easy:

Amend showRSS to accept a second argument:

function showRSS(url, containerId)

Amend the line that inserts the ajax response into the document:

document.getElementById(containerId).innerHTML = xmlhttp.responseText;

Now call showRSS twice, with different parameters, from an anonymous onload function:

window.onload = function(){
	showRSS("http://www.urlwithrss.com/rss", "rssOutput1");
	showRSS("http://www.otherdomain.com/rss", "rssOutput2");
};

Airshow

I can't believe I didn't think of passing in two parameters. It was such an obvious solution! Thanks, that solves one problem but even using that window.onload function, only the last feed gets displayed. On rare occasions after a page has been opened for a few minutes the other feed gets displayed and I can't seem to find anything on this online either! Any ideas why?

Asif,

The simplest reason is that the second server is very slow.

There's nothing in javascript to inhibit two or more simultaneous HTTP requests but the browser or operating system may have such as limitation.

With a bit more effort you can add an "error" handler to display a message under failure conditions. The pattern is like this:

if (xmlhttp.readyState==4) {
    if (xmlhttp.status==200) {
      //handle success here
    }
    else {
      //handle errors here, eg.
      //alert('Error: url=' + url + "\nstatus = " + xmlhttp.status);
    }
  }

At least then you will know if/when one or other of the two ajax calls has failed.

It is good practice always to have an error handler so the user can be advised and/or some alternative course of action can automatically occur.

Airshow

Hmm I see what you are saying about putting in error messages but this is a big part of a project I'm doing. I need to get rss feeds from two different sources and display them on the same page. Is there anything you could recommend?

Asif,

Find two fast, reliable sources. Test them independently.

If the calls are reliable when made independently but unreliable when made together, then you can try calling them "in cascade", ie. make the second ajax call when the first has completed (successfully or not). Here's the pattern:

function showRSS(url_container_array){
  if(url_container_array.length == 0) { return; }
  var obj = url_container_array.shift();//remove the first element from the array for processing
  var url = obj.url;
  var container = obj.container;
  if(!url || !container) { return; }//in case the oblect was badly constructed
  
  ...
  //make the xmlhttp object here ...
  ...
  
  if (xmlhttp.readyState==4) {
    if (xmlhttp.status==200) {
      //handle success here
    }
    else {
      //handle errors here, eg.
      //alert('Error: url=' + url + "\nstatus = " + xmlhttp.status);
    }
    showRSS(url_container_array);//recursive call of showRSS() to fetch next RSS feed "in cascade", and so on
  }

This version needs to be called as follows:

window.onload = function(){
	showRSS([
		{ url:"http://www.urlwithrss.com/rss",  container:"rssOutput1" },
		{ url:"http://www.otherdomain.com/rss", container:"rssOutput2" }
		//etc.
	]);
};

Airshow

This should work what you have suggested since I've tried something similar before where the first one is generated onload and the second one when a certain button is clicked. There are no problems in generating it like that.

I just tried your solution and nothing seems to happen at all when the page is loaded. I think I may have implemented it wrong, can you check if the below is correct...

function showRSS(url_container_array){
  if(url_container_array.length == 0) { return; }
  var obj = url_container_array.shift();//remove the first element from the array for processing
  var url = obj.url;
  var container = obj.container;
  if(!url || !container) { return; }//in case the oblect was badly constructed
 
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
 
  if (xmlhttp.readyState==4) {
    if (xmlhttp.status==200) {
    document.getElementById(container).innerHTML = xmlhttp.responseText;
    }
	}
    else {
alert('Error: url=' + url + "\nstatus = " + xmlhttp.status);
    }
    xmlhttp.open("GET","getrss.php?q="+url,true);
    xmlhttp.send();
    showRSS(url_container_array);//recursive call of showRSS() to fetch next RSS feed "in cascade", and so on
  }

Asif,

It's my fault, I simplified things a bit too much to demonstrate the pattern.

If you check out your browser's javascript console you should find that your fleshed out version of my code throws an error. xmlhttp.onreadystatechange = function() ... is not constructed correctly. But as I say, it is my fault for not explaining properly.

Try this:

//Reusable version of XMLHttpRequest/ActiveXObject code
function getHttpRequestObj(){
	if (window.XMLHttpRequest)
	{// code for IE7+, Firefox, Chrome, Opera, Safari
		return new XMLHttpRequest();
	}
	else
	{// code for IE6, IE5
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
}

function showRSS(url_container_array){
	if(url_container_array.length == 0) { return; }
	var obj = url_container_array.shift();//remove the first element from the array for processing
	var url = obj.url;
	var container = obj.container;
	if(!url || !container) { return; }//in case the object was badly constructed
	var xmlhttp = getHttpRequestObj();
	xmlhttp.onreadystatechange = function(){
		if (xmlhttp.readyState==4) {
			if (xmlhttp.status==200) {
				document.getElementById(container).innerHTML = xmlhttp.responseText;
			}
			else {
				alert('Error: url=' + url + "\nstatus = " + xmlhttp.status);
			}
			showRSS(url_container_array);//recursive call of showRSS() to fetch next RSS feed "in cascade", and so on
		}
	}
	xmlhttp.open("GET","getrss.php?q="+url,true);
	xmlhttp.send();
}

Note: By making the XMLHttpRequest/ActiveXObject code into a separate function, it becomes reusable in other AJAX operations on the same page.

Airshow

Wow, that actually seems to work great Airshow. Thanks ever so much for the help!

+1'd =D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.