I've tried to find the solution in previous questions but i couldn't.
I have a web project developed in jquery using requireJS. Everything seems to work fine (in all modern browsers) until i tested in IE9 where there isn't a script working. I tried to find the cause but all i can get is the feedback from dev tool console:
SCRIPT1002: Syntax error libCommon.js, line 10 character 3
SCRIPT445: Object doesn't support this action libEvents.js, line 5
character 2
This is the beginning code of libCommon.js:
//generic JS for all views
define(['jquery'], function ($) {
var LibCommon = function () {};
LibCommon.prototype.hideSubmenu = function() {
$submenu.removeClass('show');
}
LibCommon.prototype.toggleSubmenu = function(tipo) {
const $tipoSubmenu = $('#'+tipo);
this.hideSubmenu();
if (!$tipoSubmenu.hasClass('show')) {
$tipoSubmenu.addClass('show');
} else {
$tipoSubmenu.removeClass('show');
}
};
//and other functions...
And this is the beginning code of libEvents.js:
//generic JS for all views
define(['jquery', 'bootstrap', './libCommon', 'modernizr'], function ($, Bootstrap, LibCommon, Modernizr) {
var common = new LibCommon();
/**
* =================
* TO EXECUTE WHEN INIT
* =================
*/
$( document ).ready(function() {
console.log('initialized all common events');
var common = new LibCommon();
// Fixed header
var stickyNavTop = $('.topmenu').offset().top;
common.fixedNav(stickyNavTop);
$(window).scroll(function() {
common.fixedNav(stickyNavTop);
});
// and other functions or events...
In both errors it's first character of creating a variable/instance of an object after defining all objects/dependencies in requireJS, so it shouldn't be an error. I tried by changing for var common = 0; but error continues appearing in console. It seems that IE9 doesn't like any script. Otherwise, require's instances are working because bootstrap is working properly. Any idea?
Shilly already pointed out in a comment that you should not pass ES6 constructs to IE9. Either write ES5 or use a tool to transpile it.
Now, the error you are getting in libEvents is bizarre because libCommon should not have loaded at all, and consequently the factory of libEvents should not run because one of the dependencies did not load. It is possible to have a module load and later give errors. But I don't recall ever seeing a syntax error in the immediately-interpreted code of a module that did not just cause the load to fail. (The code you are showing is interpreted immediately, even if it is executed later. If you had an eval(string_of_code) in there or a Function(string_of_code) then string_of_code would be interpreted later but this is not something that happens in your code.) I suspect the reason RequireJS goes ahead with executing the factory for libEvents has to do with a problem catching load failures in IE9 and lower. The documentation suggests turning on enforceDefine. I would do this for your code. This won't solve everything but it may help RequireJS detect problems better.
console.log will also probably give you troubles, as explained by this question and answer.
Related
I wrote the following code for debugging puposes:
(function () {
"use strict";
// The initialize function is run each time the page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
// Use this to check whether the API is supported in the Word client.
if (Office.context.requirements.isSetSupported('WordApi', 1.1)) {
// Do something that is only available via the new APIs
Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged, onSelectionChanged);
}
else {
// Just letting you know that this code will not work with your version of Word.
$('#status').html('This code requires WordApi 1.1 or greater.');
}
});
};
var c = 1;
function onSelectionChanged(eventArgs) {
c++;
$('#status').html('onSelectionChanged() call '+c+);
}
})();
This code only sometimes reacts to changes. Sometimes reeaaly slow. Sometimes (I guess, if it is too slow and there have been multiple changes in between, it does not recognize them und prints onSelectionChanged() call 4 after a while, even though, there have been many more changes.
Other times, if I close Word, and open it again, it just works as a charm. Then I close it and open it again, and again, it fails - It is completely inconsistant. Thereby this feature is effectively not usable.
I tested this on different machines, different versions of Windows and it occures independend of the utilization of the system.
Any ideas?
Unfortunately I was not able to repro your issue. The event works quite consistently.
Its not related but is there a specific reason why you are checking the 1.1 requirement set? This event was shipped on the first release of the API so that's not needed.
If you can provide your build number and a sample document and video of whats going on we could investigate in more detail.
thanks!
I've tried to setup a testing environment with mocha, phantomjs and istanbul (and grunt). It works great so far, but when it comes to angular-testing i got some problems. I want (and need) to use angular-mocks, but as soon as I include it in my test.html, I get the following console-error in my browser:
Uncaught TypeError: (window.beforeEach || window.setup) is not a function
The matching code in angular-mocks.js is the following one:
(window.beforeEach || window.setup)(function() {
annotatedFunctions = [];
currentSpec = this;
});
This happens both for the current version (1.4.3) and for an old version which apparently worked in another project: 1.3.15.
What am I missing?
I fixed it.
The problem was, that i included my librarys (including angular-mocks.js) before mocha.js which apparently doesn't work.
As soon as I add:
<script src="/bower_components/ember/ember.min.js"></script>
on the same page where there's our snagengage chat code:
<!-- begin SnapEngage code -->
<script type="text/javascript">
(function() {
var se = document.createElement('script'); se.type = 'text/javascript'; se.async = true;
se.src = '//commondatastorage.googleapis.com/code.snapengage.com/js/4f645e9b-afb9-4226-9ebc-f8fc52d28cef.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(se, s);
})();
</script>
<!-- end SnapEngage code -->
it provokes an error:
Uncaught TypeError: Cannot call method 'push' of undefined 4f645e9b-afb9-4226-9ebc-f8fc52d28cef.js:223
YAHOO.register 4f645e9b-afb9-4226-9ebc-f8fc52d28cef.js:223
(anonymous function) 4f645e9b-afb9-4226-9ebc-f8fc52d28cef.js:242
Anyone ever experienced this? Any suggestion about how to fix this?
PS: I tried removing that JS line and it works, that's definitively a conflict between Ember and some YAHOO library I guess.
Thanks!
I opened a ticket on this with SnapEngage and they recently pushed out a fix. If you had a SnapEngage account prior to Mar 6, 2014, then you need to click "Save" within the "Style" section of your account in order for the JS to be updated to the latest version. After this, the error should go away - worked for me!
NOTE: I am using Ember 1.4.0
I had this same issue and I think it was caused by a _super() on the YAHOO.register function cycling through line 233 twice. The first time it does it the variables k.versions and k.builds are defined, but the second time they are not (perhaps because the super reruns the YAHOO.register function without passing in any arguments. Regardless of exactly what caused it, I was able to remedy the issue (albeit in a VERY hacky way) by making the following edits to the snapengage.js source:
1) On line 233 change:
k.versions.push(p);k.builds.push(q);
to:
k.versions ? k.versions.push(p):false;k.builds ? k.builds.push(q):false;
All this does is check to see if the variables are defined and if they are, push to them. If not, do nothing.
I placed the edited snapengage.js source file in app/assets/javascripts/vendor/ and then added the following line to my application.js file:
//= stub ./vendor/snapengage.js
This will stop your ember application from loading the SnapEngage source when the app loads.
Finally, I wrote a chat mixin and loaded the snapengage.js script as follows:
App.Chat = Em.Mixin.create({
agentOnline: false,
didInsertElement: function() {
this._getChatApi();
},
_getChatApi: function() {
var url = 'assets/home/vendor/snapengage.js',
_this = this;
$.getScript(url).done(function() {
// Your custom SnapEngage Javascript API code here. For example...
SnapEngage.getAgentStatusAsync(function(online) {
_this.set('agentOnline', online);
});
});
},
});
App.IndexView = Em.View.extend(Home.Chat, {
// The rest of your view code here
});
The snapengage.js script won't load itself twice but if you're using the mixin on multiple pages you might want to make sure you're not loading the chat assets (images, loading spinner, etc) twice because the plugin seems to make a call to snapengage.com everytime you click on the 'help' button rendered on the webpage.
As I mentioned, it's a very hacky solution and I don't recommend editing the source code for plugins, but this will give you a fix to easily use Snapengage in an Ember.js app.
I work on an app with a javascript/html front-end and a back-end REST service. I mostly work on the back end service, but I'm attempting to add javascript unit tests to the build. I had someone help me with the javascript testing framework setup, using phantomjs, qunit, and jstestrunner, all referenced from Maven.
I wrote a trivial unit test for a module (we'll call it "data.daily.js") that begins like this:
Data.Daily = new Function();
Data.Daily.prototype = {
Just to be clear, this code runs every day in production, and appears to work fine in all major browsers (FF, IE, and Chrome).
The test looks like this:
requirejs.config({ shim: { 'data.daily': ['config'] } });
require(['data.daily'], function() {
'use strict';
module('data.daily');
test('data.daily.test.initialize', function() {
var dataDaily = new Data.Daily();
dataDaily.initialize(Config.AJAX_DAILY_DATA_BASE_URL, Config.MOCKDATA_AJAX_DAILY_DATA_BASE_URL);
deepEqual(dataDaily.getData(), {}, "object is \"" + JSON.stringify(dataDaily.getData()) + "\", but it should be empty object");
});
});
When I run this test, it fails like this:
ReferenceError: Can't find variable: Data, source: http://localhost:9080/data.daily.js:5
[data.daily] data.daily.test.initialize: failed: 1 passed: 0
Died on test #1 at http://localhost:9080/js/qunit.js:425
at http://localhost:9080/js/data.daily.test.js:17
at http://localhost:9080/js/require.js:1682
at http://localhost:9080/js/require.js:983
at http://localhost:9080/js/require.js:1194
at http://localhost:9080/js/require.js:129
at http://localhost:9080/js/require.js:1237
at each (http://localhost:9080/js/require.js:58)
at http://localhost:9080/js/require.js:1238
at http://localhost:9080/js/require.js:1043
at http://localhost:9080/js/require.js:1224
at http://localhost:9080/js/require.js:882
at callGetModule (http://localhost:9080/js/require.js:1249)
at http://localhost:9080/js/require.js:1578
at http://localhost:9080/js/require.js:1703: Can't find variable: Data, source: ReferenceError: Can't find variable: Data
The only way I can find to get this test working is to change "data.daily.js" in this way, adding a line before the existing lines:
var Data = {};
Data.Daily = new Function();
Data.Daily.prototype = {
Now I have to say that this looks logical to me, but the fact remains that the existing code works fine in all the major browsers. This code only started failing when referenced from the test.
Note that I also tried changing the test script instead, adding the "var Data = {}" line before the "var dataDaily = new Data.Daily()" line, but that had no effect.
So, can anyone explain what is going on here? Why does the original code work if it fails in the test. Is there something funky about how "require.js" works that makes this happen? Why didn't the test work by adding the line in the test, instead of the CUT (code under test)?
Ok, I've managed to resolve this.
The assignment is actually present in the existing production code, I just didn't think to look in ".html" files for it before. When I didn't find it in ".js" files, I thought something else was going on.
The reason it didn't work to put the line in the test script instead was because I was putting the line in the wrong place. The error actually occurs at configuration time, not when the test itself is executed, so the assignment had to be before the "requirejs.config()" call. Now the test works, without having to modify the CUT.
I have this script provided by #Felix Kling in this post HERE, but is crashing my IE when I use it; on FF 3.6, Opera, Chrome, Safari work fine.
Any idea why is this happening? A fix maybe?
var ajaxTimeout;
function autorun() {
if ($("#contactForm").is(":visible")){
if(ajaxTimeout) {
clearInterval(ajaxTimeout);
ajaxTimeout = false;
}
}
else if(!ajaxTimeout) {
ajaxTimeout = setInterval("refreshAjax();", 15000);
}
}
$(function autorun() {
setInterval("autorun();", 2000)
});
Thanks,
Cristian.
LE. Sorry, forgot to add details about that.
IE just closes, "encounter an error and needs to close, looking for a solution ...". IE 8.0 Windows7. If I load the page, I cannot open the debugger from the developer tools, but if I open the debugger before I load that page and press Start debug it doesn't show any errors or anything, but the page is not refreshing the grid as it was suppose to.
Here's what you're after:
$(function () {
var ajaxTimeout;
function autorun() {
if ($("#contactForm").is(":visible")){
if(ajaxTimeout) {
clearInterval(ajaxTimeout);
ajaxTimeout = false;
}
}
else if(!ajaxTimeout) {
ajaxTimeout = setInterval(refreshAjax, 15000);
}
}
setInterval(autorun, 2000);
});
IE doesn't at all like named functions used like this, and it's overriding the previously defined one. This is a long-standing bug not fixed until IE9. The core of the problem is that $(function autorun() { is taking over the autorun name, which is just queuing more and more runs of itself.
Also, it's better to pass function references to setInterval() directly, not strings.
I suspect that this is the culprit:
$(function autorun() {
setInterval("autorun();", 2000)
});
That's not really valid javascript. I think it's probably supposed to be something like:
$(document).ready(function() {
setInterval("autorun();", 2000);
});
[edit: there was an error in my suggestion above, and I have corrected it. I was incorrectly assigning the result of setInterval(...) to the variable ajaxTimeout. This ultimately caused the logic inside the main autorun() function to never initiate its interval on refreshAjax(), thus causing the code to appear to "do nothing".]
[edit: some have indicated that my suggestion was offered without enough explanation, so I'll try to provide that here.]
you were declaring function autorun() twice. Once at the top, and again in the bottom section where I've suggested that you should make changes. Both declarations are in the same scope, so the names will collide and behavior will be browser-dependent. Some browsers will let one function "hide" the other, while other browsers will (probably) refuse to compile it.
you have used a named function declaration (the second declaration of autorun) in an "inline" context. This may be allowed by some browsers (and some have suggested that it is actually valid by the standard -- though admittedly I thought it was not), but it will definitely cause problems in IE.
My suggestion changes the second declaration into an anonymous declaration so as to kill two birds with one stone: avoid a name collision, and use syntax that is supported across all browsers.
finally, I introduced the use of $(document).ready(...), because it's standard practice these days, when programming with jQuery. You can read more about it on jQuery's site. Long story short - it is directly equivalent to the $(function() {...}) syntax that you've used, so you can take it or leave it as you please.