Here's a perplexing problem.
I have a site that uses AJAX in which the primary home page loads a home.js file with core scripts that are required by all pages on the site. One of these core scripts is the following RegExp:
var datePattern = new RegExp("^([0][1-9]|[1][0-2])\/([0][1-9]|[1-2][0-9]|[3][0-1])\/([12][0-9][0-9][0-9])$");
When the user goes to a page (via AJAX), the appropriate form validation script.js file is loaded first which contains the following to validate dates (where val is the value of the date element and correctly displays the anticipated date value):
var val=elem[i].value;
if (!datePattern.test(val)) {
elem[i].style.background="#FF0000";
errno++;
}
I have passed both the script and the HTML through a validator and everything appears to be ok.
Everything works fine in FF. However in IE. I get the message that the datePattern is undefined. What is it about the datePattern declaration in the home.js file that I need to change to ensure it is available globally to other js files?
Thanks!
Scripts on a page are executed one after another. Logically, all that needs to happen is the needle-defining-line is executed before whatever needs it. On a static page it's as simple as putting it before the other JS in the markup. In AJAX it needs to be loaded and somehow executed before the other one, which may prove more difficult.
The other common problem is scope. Since you're using var, the variable will be local to its own scope. Make sure that line isn't in a function call. A good way to narrow down the problem is to remove the var keyword. If the problem is fixed; blame scope. If it persists; blame execution order.
I hope that helps with the debugging.
The original regex expression and syntax worked fine. The problem was with another jquery syntax that was failing and not reporting an error, which caused the subsequent expressions to fail.
Related
In my web app I inject some user specific data into the html page.
It looks like this in the page source
<body>
<script>
var userData = {};
window.GLOBAL = {
userData: userData
};
userData.user = {'user_hash': 12478999584505 };
</script>
<script src="/static/scripts/myapp.js"> </script>
Inside myapp.js I retrieve the user_hash and call an initialisation function:
init(window.userData.user.user_hash);
A few users experience this problem spuriously:
Cannot read property 'user_hash' of undefined
It turns out it is very hard for me to pinpoint the exact cause of the problem. This error never happen to me in either production or development environment. There is also no error on the server side that indicates the user_hash generation has failed. I have tried to reproduce this error by throttling network speed in Chrome via Dev Console etc but I haven't been able to trigger this error yet.
On the user side, the platforms vary from mobile devices (could be running the latest version of iOS or andriod) to desktop, and different browsers (chrome, firefox or safari). My point is there is no clear pattern I can pin it down to a particular platform or brower version.
I speculate that the exception happens if /static/scripts/myapp.js is loaded and executed before window.GLOBAL is properly initialised, this exception will be fired.
I am thinking of adding defer keyword to the myapp.js script tag, based on this answer.
My questions are:
1) Is there any issue with my current HTML markup? (the two script tags)
2) My hypothesis is basically that these two script tags may have some racing condition between them. Does it stand?
3) Can adding defer attribute to the second script tag potentially fix this issue if answer to question 2 is yes?
4) If answer to question 3 is no, what else I can try?
1) Is there any issue with my current HTML markup? (the two script tags)
No there is no issue with HTML markup.
2) My hypothesis is basically that these two script tags may have some racing condition between them. Does it stand?
I did not get this question perfectly. Probably you should show your myapp code here
3) Can be adding defer attribute to the second script tag potentially fix this issue if answer to question 2 is yes?
No. JavaScript is always synchronous and single-threaded. If you're executing a JavaScript block of code on a page then no other JavaScript on that page will currently be executed. JavaScript is only asynchronous in the sense that it can make, for example, Ajax calls. and Defer instructs the contents of the script tag to not execute until the page has loaded.
4) If the answer to question 3 is no, what else I can try?
You don't require to use GLOBAL here because when you initialize variable with var on top of the script then it may automatically consider in a global scope. JavaScript has two scopes: global and local. A variable that is declared outside a function definition is a global variable, and its value is accessible and modifiable throughout your program. A variable that is declared inside a function definition is local, and second thing window object represents. the browser's window. All global JavaScript objects, functions, and variables automatically become members of the window object.
Here following code may fulfil your requirement
var userData = {
userData: userData
};
userData.user = {'user_hash': 12478999584505 };
console.log(userData.user.user_hash);
Here is also link of working fiddle: https://jsfiddle.net/dipakchavda2912/eohb0npr/
I have a project where I have three separate JavaScript files (example1.js, example2.js and example3.js lets call them) scripted into one html file (index.html). These three JS files between them are responsible for an API call and manipulating the result.
One of the JS files, example1.js refers to a global variable located in example2.js and as they were both loading into the same html document I thought the access to said variable wouldn't be an issue and it did indeed work perfectly fine until I added the files to my RoR app. Due to Rails I had to encase the JS/jQuery code inside of $document.ready(function(){}
(I should probably should do this as a matter of course anyway?).
The effect this has had is that I am now getting a 'variable not defined' error on the global variable referred to by example1.js that is located in example2.js, even though other code in the same file is working correctly.
I went back to my original JS files away from RoR incase it was a Rails issue. However, encasing the code in my original files with the jQuery document.ready function has the same effect outside of the Rails environment. Can someone explain why this is and a possible solution?
I completely overlooked the fact that document.ready is itself a function and therefore removed everything from the global scope into the function scope of document.ready.
We have an IE extension implemented as a Browser Helper Object (BHO). We have a utility function written in C++ that we add to the window object of the page so that other scripts in the page can use it to load local script files dynamically. In order to resolve relative paths to these local script files, however, we need to determine the path of the JavaScript file that calls our function:
myfunc() written in C++ and exposed to the page's JavaScript
file:///path/to/some/javascript.js
(additional stack frames)
From the top frame I want to get the information that the script calling myfunc() is located in file:///path/to/some/javascript.js.
I first expected that we could simply use the IActiveScriptDebug interface to get a stacktrace from our utility function. However, it appears to be impossible to get the IActiveScript interface from an IWebBrowser2 interface or associated document (see Full callstack for multiple frames JS on IE8).
The only thing I can think of is to register our own script debugger implementation and have myfunc() break into the debugger. However, I'm skeptical that this will work without prompting the user about whether they want to break into the debugger.
Before doing more thorough tests of this approach, I wanted to check whether anyone has definitive information about whether this is likely to work and/or can suggest an alternative approach that will enable a function written in C++ to get a stack trace from the scripting engine that invoked it.
Each script you load may have an id and each method of the script calling myfunc() may pass this id to myfunc(). This means that first you have to modify myfunct() and finally alter your scripts and calls.
This answer describes how I solved the actual issue I described in the original question. The question description isn't great since I was making assumptions about how to solve the problem that actually turned out to be unfounded. What I was really trying to do is determine the path of the currently running script. I've changed the title of the question to more accurately reflect this.
This is actually fairly easy to achieve since scripts are executed in an HTML document as they are loaded. So if I am currently executing some JavaScript that is loaded by a script tag, that script tag will always be the last script tag in the document (since the rest of the document hasn't loaded yet). To solve this problem, it is therefore enough just to get the URL of the src attribute of the last script tag and resolve any relative paths based on that.
Of course this doesn't work for script embedded directly in the HTML page, but that is bad practice anyway (IMO) so this doesn't seem like a very important limitation.
I have a page javascript page.js being loaded with require.js. The call to the page.js is placed on the bottom of the page after the calls to require.js and is as follows:
<script>
require(["page"]);
</script>
Functions inside the page.js simply do not execute each time the page is accessed.
To be clear, an alert('hello'); in the middle of page.js will be alerted most but not all of the times. I'm pretty sure this is not an existing IE issue, and that a simple alert will always execute provided there are no other JS errors.
95% of the time the page and it's corresponding functions execute, about 5% of the time the IE browsers are not reexecuting the contents of the page.js.
I don't think this is an inherent IE issue, but rather require.js is stumbling over related aggressive caching issues found in IE.
Edits:
Just to clarify, the page.js file is visible in the f12 dom load when the error occurs. The page is properly cached. The issue is that the cached code file is not re run!
For instance the alert in this file is not executed!
I'm not sure about the internals of require.js but I suppose they do xhr for the resources and eval it. It seems the xhr completes and loads into the dom, but the eval isn't working correctly. (This is of course speculation, as I don't know enough require.js internals).
The only way i know to prevent caching your js files is to add a random string to the end :
example :
<script src="http://www.mydomaine.com/myjsfile.js?t=123456"></script>
generate the "t" parameter content randomly using an md5 hash or wathever, this makes browsers believe that it's a different file each time.
There problem may not be due to caching. Caching is basically controlled on the server-side, so if you do not want a file cached, you have the server setting the cache-control headers to do that. Caching does not affect if a javascript file is "executed" or not, it only affects where the browser gets data from when trying resolve a given resource. Normally, you want .js files to be cached for performance reasons.
In your case, caching may not be the real problem. When using dynamic javascript source loaders (libraries like dojo support this), it may best that the file you load is wrapped in the following:
(function(){
// Main code here...
})();
This defines an anonymous function, and then executes it right away. This gives the following advantages:
Creates a closure so you can declare variables that are only visible in the scope of your file.
Ensure that any direct executable statements are executed.
Note, I'm not familar with require.js, so there is a possibility it can play a role in your problem. Also, you did not provide the file you are loading via require, which it may have a bug that is causing the inconsistency you are encountering.
Conclusion:
IE (where it was mostly occurring) was kind of swallowing up the error, when we were able to reproduce it in Chrome, we found an error indicating that one of our global funcs wasn't yet loaded because the global funcs file wasn't added to the require list. Unfortunately, we're not using require.js's compile + optimization which may or may not have barfed without an IMPLICIT listing of the globals.js as a dependency.
I guess the take home is make sure any functions called are themselves defined in a dependency implicitly listed in the require block!
I've been trying to get this sorted all day, but really cant figure it out. I've got a page with <div id="ajax"></div> that is populated off a tab based menu pulling in a snippet of HTML code stored in an external file that contains some javascript (mainly form validation).
I've seen in places that I need to eval() the code, but then on the same side of things people say its the last thing to do.
Can someone point me in the right direction, and provide an example if possible as I am very new to jQuery / JavaScript.
Many thanks :)
pulling in a snippet of HTML code stored in an external file that contains some javascript (mainly form validation).
Avoid doing this. Writing <script> to innerHTML doesn't cause the script to get executed... though moving the element afterwards can cause it to get executed, at different times in different browsers.
So it's inconsistent in practice, and it doesn't really make any sense to include script anyway:
when you load the same snippet twice, you'd be running the same script twice, which might redefine some of the functions or variables bound to the page, which can leave you in extremely strange and hard-to-debug situations
non-async/defer scripts are expecting to run at parse time, and may include techniques which can't work when inserted into an existing document (in the case of document.write this typically destroys the whole page, a common symptom when trying to load third-party ad/tracking scripts).
Yes, jQuery tries to make some of this more consistent between browsers by extracting script elements and executing them. But no, it doesn't manage to fix all cases (and in principle can't). So don't ask it to. Keep your scripts static, and run any binding script code that needs to happen in the load callback.
If you fetch html via Ajax, and that html has a <script> tag in it, and you write that html into your document via something like $('#foo').append(html), then the JS should run immediately without any hassle whatsoever.
jquery automatically processes scripts received in an ajax request when adding the content to your page. If you are having a particular problem then post some code.
See this link
dataType: "html" - Returns HTML as
plain text; included script tags are
evaluated when inserted in the DOM.