I have used google feed API to read a Rss feed url and display the title. When I call the function get_rss1_feeds directly It works fine. But when I call it with setTimeout or setInterval I am able to see only blank screen and the page does not stop loading!!
<script src="http://www.google.com/jsapi?key=AIzaSyA5m1Nc8ws2BbmPRwKu5gFradvD_hgq6G0" type="text/javascript"></script>
<script type="text/javascript" src="jquery-1.5.2.min.js"></script>
<script type="text/javascript" src="query.mobile-1.0a4.1.min.js"></script>
<script type="text/javascript" src="jsRss.js"></script>
<script type="text/javascript" src="notification.js"></script>
My notification.js
/** global variable **/
var Rsstitle;
/** end global variable **/
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
// Empty
}
function get_rss1_feeds() {
console.log('test'); // this is being outputted
var Rss1_title = getRss("http://yofreesamples.com/category/free-coupons/feed/?type=rss", function(entry_title) {
if(Rsstitle != entry_title)
Rsstitle = entry_title;
console.log('test1',Rsstitle); // not working
});
}
//get_rss1_feeds() works fine
setTimeout(get_rss1_feeds,5000);
My jsRss.js file
function getRss(url, callback){
console.log('test2'); // this is being outputted
if(url == null) return false;
google.load("feeds", "1");
// Our callback function, for when a feed is loaded.
function feedLoaded(result) {
if (!result.error) {
var entry = result.feed.entries[0];
var entry_title = entry.title; // need to get this value
callback && callback(entry_title);
}
}
function Load() {
// Create a feed instance that will grab feed.
var feed = new google.feeds.Feed(url);
// Calling load sends the request off. It requires a callback function.
feed.load(feedLoaded);
}
google.setOnLoadCallback(Load);
}
You need to set a breakpoint in the getRss() function and see what's going on when it's called from setTimeout(). My guess would be that something in that function has a scoping issue and isn't available from the global scope that setTimeout runs in, but is available from the normal scope you tried it in. It could be variables or it could be functions that aren't available.
This can sometimes happen if functions are declared inside another function and thus aren't actually available globally.
FYI, this block of code is very odd:
var Rsstitle;
if(Rsstitle != entry_title)
Rsstitle = entry_title;
You can replace it with this:
var Rsstitle = entry_title;
Related
I have this js piece which I use for django channels:
var chatSocketSender1 = new WebSocket(
'ws://' + window.location.host + '/ws/my_socket1/'
)
function send() {
var msg = "some message"
var receiver_id = 111
window['chatSocketSender1'].send( JSON.stringify({
'msg': msg,
'receiver_id': receiver_id
}) )
}
document.querySelector('#send_button').onclick = function() {
send();
}
The problem is that this js code only works if I put that after latest element of HTML:
<head>
...
</head>
<body>
// whole html content here
<script>
// js piece here
</script>
</body>
But if I use jquery's on load method like:
<head>
<script>
$(window).on('load', function () {
// js piece here
});
</script>
</head>
<body>
// whole html content here
</body>
Then it gives: Uncaught TypeError: window[("chatSocketSender1")] is undefined
Any suggestion please, why this not works with "onload" ?
The reason your code doesn't work is because in your first code var chatSocketSender1 creates a "global" variable (that's defined at the window level) that you later reference as window("chatSocketSender1"), but in the second code, var chatSocketSender1 is scoped to the anonymous event handler function, so is not available as window("chatSocketSender1").
Put another way:
<script>
var x = 1;
function foo() {
console.log(x)
}
</script>
works fine, but
<script>
function foo() {
var x = 1;
}
foo();
console.log(x);
</script>
will give an undefined variable error as x only exists inside foo. This isn't exactly what you've done, but is essentially the same concept.
Now, if your code was:
chatSocketSender1.send(
then it would have worked fine as your variable chatSocketSender1 is defined within the function() { onload event callback.
or instead of
var chatSocketSender1 =
you could do
window.chatSocketSender1 =
to define the variable globally, or you could:
<script>
var chatSocketSender1 = new WebSocket(...
function send() { ... }
$(window).on('load', function () {
document.querySelector('#send_button').onclick = ...
as you generally only need the event binding within the onload.
I have two js files. In the first I use this code:
var rightsRef = db.collection("users").doc(uid).collection("rights");
if(createDocumentWithoutId(rightsRef, "readGrades", "false", null, null, null, null) === true) {
window.location.href = "../public/main/main_index.html";
}
else {
}
In the second js file, I use this code:
function createDocumentWithoutId(var databaseRef, var titleValue1, var contentValue1, var titleValue2, var contentValue2, var titleValue3, var contentValue3) {
databaseRef.set({
titleValue1: contentValue1,
titleValue2: contentValue2,
titleValue3: contentValue3,
}).then(function() {
return true;
}).catch(function(error) {
console.error("Error adding document: ", error);
return false;
});
}
That I can call the function of the second js file I "import" both of them in the HTML file, by this way:
<script type="text/javascript" src="javascript1.js"></script>
<script type="text/javascript" src="../javascript2_folder/javascript2.js"></script>
But I am getting this Error:
ReferenceError: createDocumentWithoutId is not defined
You first JS file is being fully executed before the second one. That's what's causing your error - the function in the second file hasn't been loaded yet. You could reverse the order that they're define in your HTML so that the function is defined before it's called.
JS files execute when they're loaded, and in this case execution includes defining the functions. Try reversing the load order of your files, or putting some sort of check on the first code, such as this:
function amIDependentOnAnotherFile(){
if (typeof functionInAnotherFile == 'undefined')
return setTimeout(amIDependentOnAnotherFile, 5);
doSomething();
}
Solution: There appears to have been an issue in the way I was calling my queuing mechanism into window.onload.
Preamble - I'm glad to see I'm being flagged as a duplicate, where the solution is to use window.onload, which is something I'm already using here. A couple comments have indicated possible issues with the queue that I got from another stackoverflow solution, but leave me in the dark due to lack of elaboration.
Question: If I make a function call in the head, it fails. If I make a function call in the body, it succeeds. Why?
Extension: Why do the calls to the same function in global.js, which is above the failing call, succeed?
I have some javascript that creates an onload "queue" of sorts (function addLoadEvent in global.js). A call to this function adds to the queue for when onload is called.
Except, I've found that a particular script function call fails if it's located in the head vs in the body. I can't figure out why, because everything that's needed (other js functions) are loaded above the function call itself, and the actual call to the function isn't triggered until onload, ensuring that the necessary html elements exist.
Order of loading:
html file up to head
global.js - including addLoadEvent(func)
addLoadEvent x2 (succeeds)
inline script in head - includes initialFighter()
addLoadEvent (location one - fails)
html file after head
addLoadEvent (location two - succeeds)
onload triggers queued calls
For the purpose of this question, the function call that fails or succeeds based on it's location is the following.
addLoadEvent(initialFighter());
Here's the stripped down HTML, note the 2 locations flagged. If I copy paste the above function call to Location one, it fails. If I copy paste the above function call to Location two, it succeeds.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="global.js"></script>
<script type="text/javascript">
function showFighter(id) {
var pic = document.getElementById("picture");
var picPath = 'url(images/' + id + '.png)';
pic.style.backgroundImage = (picPath);
}
function initialFighter() {
var fighter = getURLParameter('fighter');
if (typeof(fighter) != "undefined" && fighter != null) {
showFighter(fighter);
} else {
showFighter('Foobar');
}
}
***** LOCATION ONE *****
</script>
</head>
<body>
<header></header>
<nav id="nav"></nav>
<section id="fighters">
<div id="picture"></div>
<div id="text"></div>
<script type="text/javascript">
***** LOCATION TWO *****
</script>
</section>
<footer id="footer"></footer>
</body>
</html>
Below is global.js, which is the very first script file loaded:
Note that there are 2 addLoadEvent(func) calls here, and they succeed (don't run until after html elements exist) despite being above practically everything else.
function addLoadEvent(func) {
var prevOnLoad = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (prevOnLoad) {
prevOnLoad();
}
func();
}
}
}
function loadFile(id, filename) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById(id).innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open('GET', filename, true);
xmlhttp.send();
}
addLoadEvent(loadFile('nav', 'nav.txt'));
addLoadEvent(loadFile('footer', 'footer.txt'));
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
The argument to addLoadEvent is supposed to be a function, which will be called during the onload callback. You're calling the function immediately, and passing its return value, so the function isn't waiting for the onload event, and you get errors because the elements aren't in the DOM yet. It should be:
addLoadEvent(function() { loadFile('nav', 'nav.txt'); });
addLoadEvent(function() { loadFile('footer', 'footer.txt'); });
addLoadEvent(initialFighter);
You don't need an anonymous wrapper function for initialFighter, since it doesn't take any arguments. You just need to leave out the (), so you pass a reference to the function, instead of calling the function immediately.
Also, instead of chaining onload event handlers by saving the old value and calling it inside the new function, you can simply use addEventListener, as these automatically add to the list of listeners instead of replacing it:
function addLoadEvent(func) {
window.addEventListener("load", func);
}
I am executing setTimeout function in a page which loads via ajax call. but if i click the link to load the page again, i afraid the last setTimeout call still continues and the number of intervals of the calls set by setTimeout executes multiple times.
tried this is the remote page:
var RefreshInterval = null;
clearTimeout(RefreshInterval);
function someFunction()
{
....
setNextRefresh();
}
function setNextRefresh() {
console.log(wifiRadarRefreshInterval);
RefreshInterval = null;
clearTimeout(RefreshInterval);
RefreshInterval = setTimeout('someFunction();', 20*1000);
}
declare var RefreshInterval = null; outside of page loaded by ajax and use this code on the page:
clearTimeout(RefreshInterval);
function someFunction()
{
....
setNextRefresh();
}
function setNextRefresh() {
console.log(wifiRadarRefreshInterval);
clearTimeout(RefreshInterval);
RefreshInterval = setTimeout('someFunction();', 20*1000);
}
if i don't want to declare it in parent page, here is the solution i found:
//Clear previously loaded calls if exists
try{ clearTimeout(wifiRadarRefreshInterval); }catch(e){}
var wifiRadarRefreshInterval = null;
function somefunction(){
....
setNextRefresh();
}
function setNextRefresh() {
try{
clearTimeout(wifiRadarRefreshInterval);
wifiRadarRefreshInterval = null;
wifiRadarRefreshInterval = setTimeout('somefunction();', 20*1000);
}
catch(e){
console.log(e.message + e.stack);
}
}
Do not use this
var RefreshInterval = null;
clearTimeout(RefreshInterval);
You are actually assigning a null and then trying to clear it. Which will not work, The timeout must be cleared by using the clearTimeout and by passing the variable which was assigned to the setTimeout. Here you will end up passing a null so the timer is never cleared.
Here is a small sample which will demonstrate a fix to your problem JS Fiddle
So insted of setting the variable to null and then trying to clear it, Just check if the variable is not defined and if it is defined clear it, else move on. Use the code below, Also you must remove the top two lines as mentioned
function setNextRefresh() {
console.log(wifiRadarRefreshInterval);
if (typeof RefreshInterval !== 'undefined') {
clearTimeout(RefreshInterval);
}
RefreshInterval = setTimeout('someFunction();', 20*1000);
}
Click on the button say like 4 times, The output should be printed only once. That is if the ajax call is made 4 times the set time out must execute only once. Check below snippet for demo
var clickCount= 0; // just to maintain the ajax calls count
function NewPageSimilator(clicksTillNow) { // this acts as a new page. Let load this entire thing on ajaX call
if (typeof RefreshInterval !== 'undefined') {
clearTimeout(RefreshInterval);
}
function setNextRefresh() {
window.RefreshInterval = setTimeout(printTime, 3000); //20*1000
}
function printTime() {// dumy function to print time
document.getElementById("output").innerHTML += "I was created at click number " + clicksTillNow + '<br/>';
}
setNextRefresh();
}
document.getElementById("ajaxCall").addEventListener("click", function() { // this will act as a ajax call by loading the scripts again
clickCount++;
NewPageSimilator(clickCount);
});
document.getElementById("clear").addEventListener("click", function() { //reset demo
clickCount = 0;
document.getElementById("output").innerHTML = "";
});
<p id="output">
</p>
<button id="ajaxCall">
AJAX CALL
</button>
<button id="clear">
Clear
</button>
I am using mimetex.cgi to convert LaTeX text into Maths Text. For which I have put the following in the head tag
<head>
<script src="../../asciimath/js/ASCIIMathMLwFallback.js" type="text/javascript">
</script>
<script type="text/javascript">
var AScgiloc = '../../includes/svgimg.php';
var AMTcgiloc = "http://www.imathas.com/cgi-bin/mimetex.cgi";
</script>
</head>
In the body tag I have the following div which is refreshed by ajax. This contains math text.
<div id="mathtext"> .... </div>
Problem that I am facing:
On the first page load the LaTeX code in mathtext div is getting converted to Math Text image. However, when the div is loaded with new LaTeX code using ajax, it doesn't get converted to Math Text.
If I click on refresh, the LaTeX gets converted to MathText again.
I am not sure what is it that I am doing wrong here.
Edit 1: Including the onload function that is a part of ASCIIMathMLwFallback.js
if(typeof window.addEventListener != 'undefined')
{
//.. gecko, safari, konqueror and standard
window.addEventListener('load', generic, false);
}
else if(typeof document.addEventListener != 'undefined')
{
//.. opera 7
document.addEventListener('load', generic, false);
}
else if(typeof window.attachEvent != 'undefined')
{
//.. win/ie
window.attachEvent('onload', generic);
}
//** remove this condition to degrade older browsers
else
{
//.. mac/ie5 and anything else that gets this far
//if there's an existing onload function
if(typeof window.onload == 'function')
{
//store it
var existing = onload;
//add new onload handler
window.onload = function()
{
//call existing onload function
existing();
//call generic onload function
generic();
};
}
else
{
//setup onload function
window.onload = generic;
}
}
if (checkForMathML) {
checkForMathML = false;
var nd = AMisMathMLavailable();
AMnoMathML = (nd != null);
}
It calls a function generic() using the above... I guess it would do if I call this function at the end of my ajax query ?
Solved it !
ASCIIMathMLwFallback.js has a function called as generic() which is being called on page load here.This function translates Latex into math functions.
In order to convert latex to math function using a ajax query , simply call the generic function by adding the below to the ajax code.
generic.call();
This will ensure that all Latex is converted to math !!