knockoutjs foreach not working in IE 9 - javascript

This is a simple app simulating a chat. I provide jsfiddle:
http://jsfiddle.net/LkqTU/2785/
Some messages coming from the server, simulated by the button, and a user typing on a textarea binded to the keypress event to get te enter key and send the message.
Well, this is working fine in Chrome and Firefox but fails in IE9.
What could be wrong?
Thanks

Well, it was relatively easy to locate an error: assigning this to an external variable named self right at the beginning of Model function just doesn't look right.
The explanation why it worked fine in Chrome and Firefox, but failed in IE, though, is much more interesting. Obviously varless self refers to window.self, which is actually a special property of window object - reference to... window itself (MDN).
Internet Explorer is actually well-known for its specific treatment of this property: while in other browsers window === window.self evaluates to true, in IE it's false. And I wouldn't say IE does it without any reasoning; check this discussion for some details.
Ironically, in this particular example IE turns out to be a half-hero. ) I said "hero", because IE is the only browser that doesn't let you overwrite window.self. All the others are not so picky; add console.log(window.self) to the end of your script to witness their shame. )
And I said "half", because IE could be much more... heroic about it. ) Instead of ignoring window.self = ... line silently (and throwing an error for that far away line that used the ignored assignment in a slightly different way), why didn't IE just give an early warning? Damn, even a notice would do.
Anyway. It's pretty easy not to rely on IE's sporadic heroism for such things: just add 'use strict' line at the beginning your script, and voila! both Chrome and Firefox will spit out a 'Reference Error' warning right where it belongs - at self = this line. )
Yes, I understand that 'use strict' use is not a simple step, and it might break some scripts; yet I wholly stand by Nicholas Zakas' statement on that topic.

Related

Apparently missing ) gets fixed in jQuery :not(.class on all but Safari?

I had a jQuery Syntax-Error in my Script but only Safari throw an exception.
$("#id:not(.class").length
The :not wasn't closed by ). In Safari length was 0, in all other browser it was the correct value if the error hadn't exist. Could it possible that Chrome, Firefox, Opera and Internet Explorer fixes these errors on the fly?
Additionally, it seems not to be inherent to jQuery, because even native querySelector calls recovers syntax errors in the selector literal:
document.querySelector('[href^="h' ) ===
document.querySelector('[href^="h"]'); // true in non-Safari
document.querySelector(':not([X="Y' ) ===
document.querySelector(':not([X="Y"])'); // true in non-Safari
Error raised in Safari reads SYNTAX_ERR: DOM Exception 12.
This is really somehow fascinating because I have asked myself this a lot of times, too, without further investigation why that is. Chrome indeed sometimes "ignores" syntax errors, for example when you add or leave out ; or , in object notations for instance.
That can be a good thing but is sometimes hard to debug. Older browsers like IE throw errors where newer browsers dont. I dont know if this is a feature or a bug :)
I dont have sources on this but I can confirm that I noticed similar behavior. Most likely this has something to do with JavaScipt's strict mode.
This should be
$("#id:not('.class')").length
instead of
$("#id:not(.class").length

Firefox Bookmarklet: Exposing functions to the global namespace

I'm working on a moderately-complex Bookmarklet that works just fine in Chrome, but I can't get it to work in Firefox. When I run my Bookmarklet in Firefox it redirects to a new page that only says true on it.
I've narrowed the cause down to a very specific thing: Firefox doesn't seem to like when you expose new functions to the global namespace.
If this is the case, might you know more about it? Is this documented anywhere, such that I can learn more about it? Resources on the nuances of bookmarklet-building seem scarce, and I can't find anything relevant. A second question would be if there are there any known workarounds.
And for some examples (remember, to test them simply copy these lines of code into a bookmarklet in Firefox. Then run them on any page).
Redirecting bookmarklets
javascript:!function(){window.okay={test:function(){}}}();
The project I'm working on
A Non-redirecting bookmarklet
javascript:!function(){window.okay={test:!0}}();
Any thoughts? Thanks!
For now, I plan to use manual subscriptions in Knockout to get the functionality I need. It'd still be nice to know the answer to this question, though.
It has nothing to do with exposing globals. It has everything to do with the final evaluated value of your bookmarklet.
Any JS code that is evaluated always returns a value which comes from the last line of code or the last block.
For me, in Firefox, both of your examples redirect because both return true. You can test this by pasting the code directly into Firefox console.
Furthermore...
javascript:!function(){...}();
This is weird. I've never seen this pattern.
This is the most common bookmarklet pattern these days:
javascript:(function(){...})();
As long as you don't end that anonymous function with a return, that pattern evaluates to undefined, and no redirect happens.
The older way of achieving the same result was to always use void(0); as the last line of code. That evaluates to undefined also, and if it is the last line, then the entire script evaluates to undefined, and no redirect happens.

VERY confused - javascript not being executed - unless Console is turned on in Firebug?

I just started doing some Javascript work for a project, I do mostly backend work so I'm sorry for being new at this! Also, not using a Javascript framework because I want to learn about the fundamentals before making everything very easy for myself :)
So, here is my question/confusion: I wrote a little javascript that dynamically changed forms. This is how I called the code:
// loads the initial box
window.onload = initList(environment_box);
// loads artifacts on each change to environment select box
environment_box.onchange = changeList;
This worked like magic - in CHROME that is! I never noticed it wasn't working in Firefox (its just an internal tool, so I can assume decent browsers, but I figure hey, if its working in Chrome, it will work in Firefox!). So, I did some investigation, and it seems as though the code isnt getting executed in Firefox. I whipped out firebug and wanted to see what was going on.
The interesting thing was, when I enabled Console on firebug, my code got executed! I am very confused as to why, and I would much appreciate any help I could get. Thanks!
-Shawn
You are calling some method on console in your JavaScript is my best guess. Chrome has console defined be default, so it is not a problem.
On Firefox, however, there is no such global object (not without Firebug), so when you try to call a property on an undefined object like,
console.log(..);
it throws an exception which you are not catching, so the JavaScript execution halts.
You're probably calling a method of the console object which just doesn't exist by default in most web browsers. It may be always available on webkit based browsers (like Chrome) but with firefox/IE(/opera?) it requires an external add-on, either firebug or a javascript dependency.
Checkout things like firebugx which simply defines the most common methods of a console object as no-op functions.

Finding Parse Errors in Javascript

Is there an easy way to find parse errors in javascript code?
Last week I was debugging a javascript problem where the first javascript function that was called gave an 'object expected' error. I later determined that this was because the browser wasn't able to parse my javascript code. I eventually solved the problem but it was a painful process that involved pouring over my code line by line, trying to find my mistake.
There must be an easier way.
Use a tool like Jslint or an alternative browser.
Until recently, IE was the only browser that did not have built in development assistance. Other browsers will a) not come to a grinding halt on the first error they encounter, and b) tell you what and where the problem in your code is.
My favorite "quick ad easy" way to test IE syntax problems is to load the page up in Opera. It parses code like IE but will give you meaningful error messages.
I'll clarify with an example:
var foo = {
prop1 : 'value',
prop2 : 'value',
prop2 : 'value', // <-- the problem
};
If I remember correctly: In IE6 and IE7 the code will break because IE demands leaving the last comma out. The parser throws a fit and the browser simply stops. It may alert some errors but the line numbers (or even filenames) will not be reliable. Firefox and Safari, however, simply ignore the comma. Opera runs the code, but will print an error on the console indicating line number (and more).
Easiest way to write JavaScript is with Firefox + Firebug. Test with IE and have Opera tell you what is breaking when it does.
What browser are you using? IE8 has great build-in feature to debug javascript, for Firefox, Firebug is great.
Checking that the values passed into functions are correct and throwing your own errors if they aren't will help you track down problems faster.
Safari 4 (which runs on both Mac OS X and Windows) comes with some development tools (including a debugger) that are very useful. If you prefer using Firefox, Firebug provides similar functionality.
JSLint can help you track down simple errors.
Steve

Javascript best practice: handling Firebug-specific code

Firebug is certainly a wonderful tool for javascript debugging; I use console.log() extensively.
I wanted to know if I can leave the Firebug-specific code in production.
What's the best practice? Commenting the debug code?
If you leave console.log() calls in your production code, then people visiting the site using Internet Explorer will have JavaScript errors. If those people have extra debugging tools configured, then they will see nasty dialog boxes or popups.
A quick search revealed this thread discussing methods to detect if the Firebug console exists: http://www.nabble.com/Re:-detect-firebug-existance-td19610337.html
been bitten by this before. Ideally all the console.log statements need to be removed before production, but this is error prone and developers invariably forget or only test in FF + Firebug.
A possible solution is to create a dummy console object if one isn't already defined.
if( typeof window.console == 'undefined'){
window.console = {
log:function(){}
};
}
One word of caution: It used to be the case for Safari on 10.4 that any call to console.log would throw a security exception as the console object is a reserved object used in the Mac OS Dashboard widgets. Not sure this is the case anymore, will check tonight.
Personally I modified my compressor a while ago to strip out console references pre-compress. A few minutes adding a regex there saves a lifetime of hassle.
Just thought I would add a really good tip for any js debugging.... use the keyword "debugger", and its like a breakpoint in the code, firebug detects it also MSIE (if you have visual studio) detects it and as I say its a breakpoint.
Not many people seem to know about this but I have found it invaluble... also if there isnt a debugger installed on the machine that is running the code, nothing happens and the code goes through fine. Although I wouldn't advise leaving them in there.
I have had many a headache caused by this.
I use console.log() a lot, and until recently, found that it would cause the entire JS code to fail in versions of FF not using firebug.
I usually run a find before going live, and commenting it out.
D
Some compressors will strip out any line prefixed by ;;; (which is a legal sequence to have, being three empty statements.) This way you're not strictly limited to console references (i.e. you could do some calculations and then console.log() the result at the end, and the compressor can strip all of them out.) I use JavaScript::Minifier for this.
I use this in OOP Javascript, making my own wrapper for log that checks that firebug exists:
myclass.prototype.log = function()
{
if( typeof window.console != 'undefined' )
{
console.log.apply( null, arguments );
}
}
Just call:
this.log( arg1, arg2, ...)
Just a reminder that IE Dev Tool does not support apply() on console.log.
Calling console.log.apply() will raise exception in IE8 when dev tool is active.
You can try JavaScript Debug, it is s simple wrapper for console.log
http://benalman.com/projects/javascript-debug-console-log/

Categories

Resources