Chrome not recognizing function arguments correctly - javascript

I have wrote some cross browser code for adding event listeners, then chrome started being funky, anyone know why this is happening?
Add Event listener code:
function addEventListener(Elm,Type,Func)
{
if(Elm.attachEvent)
Elm.attachEvent((Type.substr(0,2) == 'on' ? Type : 'on'+Type),Func);
else
Elm.addEventListener(Type,Func);
}
Code calling the method:
addEventListener(window,'load',SetSize);
addEventListener(window,'resize',SetSize);
Error:
Uncaught TypeError: Object load has no method 'addEventListener'
You can very clearly see that I have passed the arguments in the correct order yet they are not interpreted in said order..

You have overwritten window.addEventListener.
The native signature is: event_name, callback but yours is: object, event_name, callback.
Change the name of your function addEventListener or namespace it, like my_framework.addEventListener

You have redefined window.addEventListener. Anything you declare in the global namespace basically belongs to window, so:
function addEventListener(...) {
}
is the same as:
window.addEventListener = function(...) {
}
The argument signature for the native addEventListener is eventName, listener, but you have Elm, Type, Func.
Then inside your function body, you are doing Elm.addEventListener and passing it 'load' and SetSize. In that call, it calls your function again (because Elm is window) and this time, it attempts to call addEventListener on the string 'load', which won't work because a string doesn't have that method.
Change the name of your function, or namespace it, and it should work.

I would say the window object has not .attachEvent or .addEventListener.
This may caused because your function is named addEventListener and has overwritten the window.addEventListener()

Related

using flush on lodash's throttle decorator

Using TypeScript (JavaScript and Angular):
I want lodash's throttle decorator to limit an API call while the user is navigating around the page, but still fire before they unload (leave) the site.
In the typescript constructor I have window.addEventListener('beforeunload', () => this.onUnload());
with the onUnload() function being declared as
onUnload() {
this.thisIsTheThrottledFunction.flush;
}
but I am getting the error response "Property 'flush' does not exist on type '() => Promise'."
The function whose .flush method I am trying to access is the declared throttled version of the other function. The function is successfully throttled, so I am confident that part of the code works. What is the best way to access the .flush method?
You should be able to debug this by verifying what the value of this is. Seems to me like you just need to bind the object's this value to the onUnload function (or you can pass it in). For instance, you could put this in your constructor: this.onUnload = this.onUnload.bind(this). There's a sugar for this syntax, where you define it in your class using onUnload = () => { ... }. Both of those methods attach the method to the instance instead of just having it as part of the prototype. Or, you could pass the bound function directly to your event listener:
window.addEventListener('beforeunload', this.onUnload.bind(this));

Define socket io function outside of "on" statement

I'm writing code with Socket.io in JavaScript and I've been trying to define the function that happens during a certain event outside of the event statement because I want to reuse the function later. So instead of the usual:
socket.on('eventName',function(input){
//code triggered by event
});
I want to declare the function beforehand and then use it in the "on" statement:
function myFunction(input){
//some code
}
socket.on('input', myFunction(input));
So far I haven't had any success and I keep getting this error in Terminal:
nodejs exception: ReferenceError: input is not defined
in reference to the input being sent from the client with the 'input' event. Do I always have to define the code that happens when the event is triggered in the "on" statement?
What you want is to pass a reference to myFunction, like this:
socket.on('input', myFunction);
What you're doing with myFunction(input) is actually executing myFunction with an undefined variable input as its argument (hence the error).

how to create instances of a function in javascript?

Im trying to add an event listener to a object for example:
this.startLoading = function(){
this.a.addEventListener("complete", this.loadingHandler()); this gives me an error
},
this.loadingHandler = function(){
console.log("im doing something")
}
ERROR: "Uncaught Error: addListener only takes instances of
Function. The listener for event "complete" is "undefined"
However if I put the loadingHandler() function inside the scope it works, for example:
this.startLoading = function(){
var loadingHandler = function(){...}
this.a.addEventListener("complete", loadingHandler()); // this works
},
Im not sure what instances of a function means in that regard?
When you put () after a reference to a function, that means to call the function, and the value of the expression is whatever the function returns.
Your second example, that you say works, actually will not work, and you'll get the same error if the "startLoading" function is called.
Because you probably need to retain the proper context (this), what you probably need is
this.a.addEventListener("complete", this.loadingHandler.bind(this));
The .bind() method returns a function (exactly what addEventListener requires) that in turn will invoke your function such that this has the value requested.

Trying to call method name using string: Uncaught TypeError: Object [object global] has no method

So, I've figured out how to call a method in JavaScript when you have the method name in a string e.g. strCallback = 'targetMethod'; window[strCallback]();, however, I get the following error message indicating that it can't find the method and after researching I'm still not sure why.
Calling the method by the actual name works, but not by using window[strCallback]();
Error:
Uncaught TypeError: Object [object global] has no method 'targetMethod'
Code:
function startMethod(strCallback) {
var results = '...';
// window[strCallback](results); // <-- Causes error
targetMethod(results); // <-- Works
}
function targetMethod(r) {
console.debug(r);
}
startMethod('targetMethod');
Thanks for any help.
From the discussion in comments it looks like the problem is the context in which the callback method is declared. If you use window[callback] it expects the callback to me declared in the global context, in your case it does not appear to be the case. It might be because you have declared everything inside a anonymous function/dom ready creating a closure context for the function.
As a solution I would recommend not to pass the callback as a function name string, instead pass it as a function reference.
So instead of calling startMethod('targetMethod');, you need to call startMethod(targetMethod); and invoke callback using strCallback() instead of window[strCallback](results);.
I solution we worked out in the comments was just a workaround where we forced the callback to the global scope which is not a recommended method

Actionscript error when executing eventlistener in javascript

I have the following code using actionscript and the indesign sdk:
At the beginning of my Class
[ Embed (source= "resources/js/eventHandlers.jsx" , mimeType= "application/octet-stream" )]
private static var jsHandler:Class;
var jsxInterface:HostObject = HostObject.getRoot(HostObject.extensions[0]);
In my function:
jsxInterface.eval( new jsHandler().toString());
jsxInterface.init( this );
document.xmlElements.item(0).xmlElements.item("docpreset").importXML(File.applicationStorageDirectory.resolvePath("temp/cstyles.xml"));
jsxInterface.afterImport(document);
this is the code inside eventHandlers.jsx:
var asInterface = {};
function init(wrapper) {
asInterface = wrapper;
}
function afterImport(document) {
document.addEventListener (Document.AFTER_IMPORT, asInterface.test());
}
and from javascript I call this:
public function test():void {
trace("ole");
}
Now, the test function gets executed correctly, but after that the next thing that gets called is again this:
jsxInterface.afterImport(document);
and then an error is thrown:
Error: ActionScript error: Error: Missing required parameter 'handler' for method 'addEventListener'.
I have no idea anymore on what I need to do. All I want is for the xml to be imported and an event dispatched when the import is complete.
I have no idea why I even have to call a javascript function, and can't use the document.AFTER_IMPORT inside a normal eventListener. Can anyone help me out on this one please?
The problem seems to be that in your afterImport() method, you are adding the event listener incorrectly.
The second parameter to the addEventListener() method should be the name of a function (technically it's a reference to a function). In your code, you have put parentheses on the end of the function name -- so instead of providing the reference to the function, the function is being executed.
When the function executes, it returns nothing, so the second parameter to addEventListener() is missing and you get the error.
Try this instead:
function afterImport(document) {
document.addEventListener (Document.AFTER_IMPORT, asInterface.test);
// notice no "()" here ^^
}
[Edit]
Since you are still getting the error, you might want to add some code to debug it further.
In the method above, comment out the addEventListener line, and replace with something like this:
// for debugging
if (asInterface.test == null)
{
trace("fail: it's null");
}
else if (asInterface.test is Function)
{
trace("success: it's a function");
// this is the only code path where your error will not occur
}
else
{
trace("fail: i don't know what this is: ", asInterface.test);
}
I think you have to initiate the AS wrapper like this :
jsxInterface.init( this );
then the AS API becomes available to the js code.
Loic

Categories