Undefined method with coffescript using html event onclick="function()" - javascript

I have this line of code in my html
<a href="#" onclick="editfuntion(2)">
And My Coffescript
editfunction = (id) ->
console.log id
return
Why is it it returns ?
Uncaught ReferenceError: editfunction is not defined
at HTMLAnchorElement.onclick

Coffeescript will wrap all files in an anonymous function which is immediately executed. This means all variables you define are locally scoped unless explicitly placed in the global namespace (in browsers it is the window object, while in NodeJS it's global).
From coffeescript.org (talking about using Coffeescript in a browser, but it also applies to using the Coffeescript compiled to JS ):
The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the window object.
Try changing your Coffeescript to:
window.editfunction = (id) ->
console.log id
This will expose the function globally on the window object so that it can be used within an onclick handler.

#editfunction = editfunction = (id) ->
console.log 'Yeheyyy'
this will works :)

Related

Getting variable reference errors after implementing es6 modules

I'm trying to clean up my code and implement es6 modules for the first time. I have created three module files and am using the import/export keyword where necessary and have specified type="module" in index.html.
The problem is everything functions correctly except all the global variables are undefined in my main file and now I get Reference Errors: Variable not defined if I try to console.log(variable)in the console. Confusing me further is if I place the same console.log(variable) inside an IIFE within the file it correctly displays the variable value with no Reference Error.
For example:
<script type="module">
let foo = "some text";
(function() {
console.log(foo)
}()); // prints "some text"
console.log(foo); // prints Reference Error: foo not defined
</script>
Are there special rules for how global variables are handled in es6 modules? I'm just really confused because the everything else works properly and all I changed was splitting my file using es6 modules and running a local server (because of CORS error from using module pattern).
It appears my issue was a misunderstanding of how the console works and that it doesn't have access to a variable within a module file unless it is made global by attaching it to window.
For example, this now allows me to access the variable in question:
let foo = "some text";
window.foo = foo;
console.log(foo); // now prints "some text" in the console instead of Reference Error
Related answers:
How to access functions defined in es6 module in a browsers javascript console
What is the correct way to define global variable in ES6 modules?

Dynamics CRM - JS ReferenceError "X" is not defined

I have a short bit of Javascript that sets fields to optional for certain forms.
I've checked syntax multiple times, checked the execute order in the CRM Form, and there are no references to other JS Libraries.
function getFormName() {
var formName;
formName = Xrm.Page.ui.formSelector.getCurrentItem().getLabel();
if (formName == "EPS Plan Form") {
Xrm.Page.getAttribute("abc_plan_type").setRequiredLevel("none");
Xrm.Page.getAttribute("usi_erisa_plan").setRequiredLevel("none");
Xrm.Page.getAttribute("abc_product").setRequiredLevel("none");
}
}
The error I'm getting seems to be in reference to general syntax issues :
ReferenceError: getName is not defined
at eval (eval at RunHandlerInternal
at RunHandlerInternal
at RunHandlers
at OnScriptTagLoaded
Seems like your event trigger on the form might be configured to call a function called getName...
If you check the form Properties > Events, do you see a call to getName in the OnLoad event? Based on your function name above you'd need it to call getFormName.
And for the record, Xrm.Page is deprecated in favor of passing execution context and using executionContext.getFormContext() (except when referencing the parent page from a web resource, in which case Xrm.Page is still supported, last I heard.)

Window object not defined in jasmine

I am trying to test a method where one of the thing that it does it lock orientation of screen. Jasmine however is throwing error in the line:
(<any>window).screen.orientation.lock('portrait') saying that undefined is not a constructer.
I even tried not using typescript types and just window.screen.msOrientationLock('landscape') and other window.screen methods but I get same error. I have the _$window_ injected in beforeEach of my tests too.
Testing if it locks is not necessary part of my test so is there some way to skip this specific line or correct this error. Thanks :)
Well it was easy. I had to inject window object and assign it to a global variable in my global beforeEach like this:
$window = _$window_;
Then, the next issue was that the property orientation was not available in the window.screen object unfortunately. I just had to mock it inside my spec like this:
$window.screen.orientation = {
lock: function() { return; }
};
Just had to do this before spying/calling the method which had window.screen.orientation.lock method inside it.

Jasmine Unit Tests Unexpected this Reference

I am trying to test a fairly simple JavaScript function in Jasmine, however the first statement is throwing an error for being undefined.
myClass.prototype.functiontoBeTested = function() {
var x = this.method()
...
}
The above throws an error in Jasmine as method is not a function and is undefined. The prototype is altered earlier to have this method, and out of curiosity I assigned this method to my test object in the spec itself as such:
myObject.method = function(){return mockResults;};
So I decided to log this to the console and instead of it being my object, I see Window {top: Window, location: Location, document: document, window: Window, external: Object…} which doesn't seem right. I've had this issue before with testing a function in Jasmine that used this but just changed the source code to refer to the object by name since the function was being assigned to something within the closure. I can't do that in this case, and I'm curious why this is referring to something unexpected (at least to me).
Edit: Some details on what the test case looks like as requested:
it("updates the control count", function(){
var mockResults = { ... };
myObject.method = function() {return mockResults;};
expect(myObject.method).not.toThrow();
});
Right now I'm just trying to get the method to execute to completion during the test. The function to be tested updates the text on some HTML components, I'll work on verifying those once I can get it to actually run. The method that is causing an error is the first line of the function, and is simply an accessor method for the object being called. In actual execution, var x = this.method() runs without issue. When testing in jasmine var x = this.method() throws an error because method() is undefined for this. Instead of this referring to the calling object, it is referring to the window. This doesn't happen live, but only during testing with Jasmine. This method is undefined even when I forcibly define it for the test object just prior to execution in the test as above. That's when I decided to log this to console in the source code and realized it isn't referring to what I would have expected it to refer to.
In JavaScript this for a method depends on the context it was called from. When you do a call myObject.method(), then method was called from the context of myObject, therefore this is myObject.
When you pass your function to Jasmine toThrow matcher, it calls it as it was passed (see source code):
try {
actual();
} catch (e) {
// ....
}
Here, actual() is a call of your method. It has no any specific context, so by default it will be called from window context.
Solution is to explicitly bind you method to myObject like the following:
expect(myObject.method.bind(myObject)).not.toThrow();
Credits to questions, you can find more details there:
Does Jasmine's toThrow matcher require the argument to be wrapped in an anonymous function?
How to write a test which expects an Error to be thrown in Jasmine?

javascript global variables visibility

I'm using a global variable in javascript, declared in a script tag outside any function:
<script type="text/javascript">
var prov_status_dict={};
....
</script>
Later on in a javascript method I'm using the variable normally.
temp=prov_status_dict[current_as_id];
I'm having issues with it on opera and ie, while on firefox it works. This is what opera's error console reports:
JavaScript - http://localhost:8000/input/
Event thread: click
Error:
name: ReferenceError
message: Statement on line 62: Undefined variable: prov_status_dict
stacktrace: n/a; see opera:config#UserPrefs|Exceptions Have Stacktrace
I've noticed that the problem is with global variables in general. I tryed moving some into hidden fields, but the same error pops up on the next use of a global var.
Help?
I usually access my globals through the window object so that I always have a point of reference
window.MyVariables = {};
window.MyVariables.prov_status_dict = {};
Give this a try, it might resolve your problem.
Try to avoid using global variables, see http://yuiblog.com/blog/2006/06/01/global-domination

Categories

Resources