The below code snippets are not the actual code, they are only there to explain my issue. So please don't concentrate on the actual functionality. I'm working with Adobe DTM. I have no idea how to get an anonymous function that returns a value (as a Data Element to source a global function? If I have a normal anonymous function within my data Element, everything works fine. If the anonymous function returns, then it doesn't work? Is there any way to get this to work? Example:
//global function
function _myGlobalFunct(str){
return (str);
}
the following code of an anonymous function within the Data Element calls global function and it works as expected:
// working anonymous function
(function () {
window._myGlobalFunct("value1");
})()
but the following return anonymous function, within the Data Element, doesn't call my function but doesn't throw any errors? :
// Not Working Properly but doesn't throw any errors?
return (function() {
var rvalue = document.title || "No Title";
window._myGlobalFunct(rvalue);
return rvalue;
})();
I do know the function is executing but not getting any errors in Chrome?
DTM's data elements execute the code provided within a function (that may not be clear to the other users here), so there will be a return outside of a function in the code you input/show here. You're not returning the value from your function (or if you're trying to update rvalue within the function and rvalue isn't in the right scope (window vs. local)). In any case, is there a reason you're using the anonymous function anyways? Below should work:
var rvalue = document.title || "No Title";
return window._myGlobalFunct(rvalue);
If you still want the anonymous function, make sure to grab the return value from your function:
return (function() {
var rvalue = document.title || "No Title";
return window._myGlobalFunct(rvalue);
})();
I don't think you can return a self-invoking function and then return again in the function.
Since I can't comment yet I will explain it here in more detail, why it is indeed a duplicate. The first answer by Niet the Dark Absol in the link I mentioned above(for reference: Syntax error: Illegal return statement in JavaScript), clearly says the following:
return only makes sense inside a function. There is no function in
your code.
To apply this to your case:
return (function() {
Is your first line, if you would encapsulate everything in another function and call that one everything will be working fine, e.g.:
function myFunction(){
return (function() {
var rvalue = document.title || "No Title";
window._myGlobalFunct(rvalue);
return rvalue;
})();
}
And then you can call myFunction() to get your return value. I hope this helps you out.
I have a simple javascript error logging mechanism in place and it looks somewhhat like this:
window.onerror = function (ErrorMsg, Url, LineNumber, Col, Error) {
// ajax these to the server, including Error.stack}
The problem is that I'd also like to get the value of the local variables and function parameters when the error occurred. Is this even possible?
I'm thinking about modifying the Function prototype so that each time a function runs, its arguments are stored in a global array of strings and then the error handler would just add this array to the ajax call. Can JavaScript do this?
#1 Can local scope be recovered in onerror() without black magic?
Without this being bound in the scope of window.onerror() or the surrounding variables being directly accessible, it's impossible to regain access to the variables you had set.
What you're mostly wanting access to is this.arguments or arguments or the equivalent, but that's destroyed. Any hope of obtaining a key-value associative array or hash-like object would involve meta-programming ( i.e. reading the function definition to obtain the variable names, and obtaining an exception report to attempt to salvage data ).
See this answer for more on something similar:
Getting All Variables In Scope
But this "lacking functionality" is a good thing:
If you could gain access to what you're asking for, that would likely be a fault in the Javascript engine. Why? Because the variable states and contents themselves are what caused the exception/error, assuming bad code wasn't the issue to begin with.
In other words, if you could get access to a faulty variable, that might be a door into an infinite loop:
Failure due to variable contents.
Error handler triggered.
Trace contents of variable.
Failure due to variable contents.
Error handler triggered.
Trace contents of variable.
Etc.
#2 Can Javascript store all arguments of every function call by voodoo?
Yes. It can. This is probably a really bad idea ( see #1 ) but it is possible. Here is a pointer on where to start:
Is there a way to wrap all JavaScript methods with a function?
From there, what you're wanting to do is push this.arguments or equivalent to a stack of function calls. But again, this is approaching insanity for many reasons. Not the least of which is the need to duplicate all the values, lest you reference mutated variables, or be unable to access the data at all... and like I said above, the problem of bad data in general. But still, it is possible.
Is this even possible?
No. A stack trace is proof that the stack has unwound, all stack frames and all the local variables they contained are gone. As for getting the name of a variable, that is not even possible at run time.
To start off i accept #Tomalak completely.
I was also put in your situation where i needed to debug a remote running app in case of crash.
As a work around I have forked my code for you in a fiddler. Please modify according to your need.
Caveat: You have to wrap the function body with try{..}catch(e){..} as illustrated in the fiddler code.
Please read the inline comments for understanding.
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
console.log(errorObj);
}
window.addEventListener("reportOnError", function(e){
console.log(e.detail);
/*Send to the server or any listeners for analysis.*/
//Http.send(e.detail);
});
function ExceptionReport(ex, args, scope) {
var self = {};
self.message = ex.message;
self.stack = ex.stack;
self.name = ex.name;
self.whoCalled = args.callee.caller.name == "" ? "Window": args.callee.caller.name;
self.errorInFunction = args.callee.name;
self.instanceOf = scope.constructor;
self.KeyPairValues = getParamNames(arguments.callee.caller.toString(), Array.prototype.slice.call(args)); //Contains the parameters value set during runtime
window.dispatchEvent(new CustomEvent('reportOnError', {'detail':self}));
}
//Utilties
function getParamNames(fnBody, values) {
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,
ARGUMENT_NAMES = /([^\s,]+)/g,
result = fnBody.slice(fnBody.indexOf('(')+1, fnBody.indexOf(')')).match(ARGUMENT_NAMES),
obj={};
fnBody.replace(STRIP_COMMENTS, '');
if(result !== null){
for(var i=0; i < result.length; i++){
obj[result[i]] = values.length !==0 ? values[i] : null;
}
}else{
obj = null;
}
return obj;
}
/*
This is a testing/sample function that throws the error
*/
function testing(a,b,c){
try{
dummy(1,2) ; //This line throws the error as reference error.
}catch(e){
ExceptionReport(e, arguments, this);
}
}
//Class Emulation: For instanceof illustration.
function testingClass(){
this.testing = testing;
}
//Named self executing function: This calls the function
var myvar = (function myvar(){
testing(1,2,3);
})();
//Illustrating instanceof in exception
var myVar2 = new testingClass();
myVar2.testing(1,2,3);
//Calling from global scope this is Window
testing(1,2,3);
//Without variables
testing();
I have used examples to illustrate the behavior of functions called in different circumstances.
Below signifies the varialble used for
self.KeyPairValues : Used to store the function parameter set/passed during runtime
self.errorInFunction : This stores the name of the function error was caused in.
self.whoCalled : This stores the function name that invoked the defective function
self.instanceOf : This stores the name of the instance is called creating a new instance.
Other variables are same as in Error object
The others answers here are spot on, but I might be able to offer a suggestion for a slightly different way to accomplish this. Instead of trying to track all scope in your program, why not add a tagging function that tracks the scope of one function's parameters without affecting the runtime of the function. For for example:
var globalRecord = {};
function record(name, fn) {
return function () {
var args = [].slice.call(arguments);
var record = globalRecord[name] = {
args: args,
arg: {}
};
args.unshift(function (name, value) {
return record[name] = value;
});
fn.apply(args, arguments);
}
}
// Then, you track variables like this
var func = record("func", function (record, a, b, c) {
record("a", a); // named parameters are accessible now
record("b", b); // if some error occurs in the function body
return a + b + c;
});
// Calling func still behaves as before.
func(1, 2, 3);
// Errors handled like this:
window.onerror = function () {
globalRecord.func.args; // ==> last set of arguments past to function
globalRecord.func.arg.a; // specific arguments recorded with names
};
You could even use this method to track scope without using a function by anonymously calling the recorded function.
record("test", function (record) {
var a = record("a", /* whatever */);
var b = record("b", /* ... */ );
// do scope specific stuff that might fail
})();
Of course, this isn't a polished implementation by any stretch, but with a little work, I think you might be able to get the behavior you're looking for without any seriously black magic. By selectively adding and removing record calls as the need presents itself, you can have precise control over what is logged without any intrusive hacks.
You can find your answer in this link.
Before taking bundles from the server, you must modify them. For example, to solve your problem, you can do changes in the mentioned link as follows. In the BuildBundleContent Class make this change:
contents.Insert(blockContentIndex,
string.Format("if(customErrorLogging)customErrorLogging({0}, this){1}",
errVariable, hasContent ? ";" : ""));
If in the modules you have to use something like:
var self = this;
You can use:
contents.Insert(blockContentIndex,
string.Format("if(customErrorLogging)customErrorLogging({0}, self ? self : this){1}",
errVariable, hasContent ? ";" : ""));
And in added js file:
"use strict";
var customErrorLogging = function (ex, module) {
console.log(module);
//do something...
};
I hope help you.
I'm using PhantomJS v2.0 and CasperJS 1.1.0-beta3. I want to query a specific part inside the page DOM.
Here the code that did not work:
function myfunc()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
}
var del=this.evaluate(myfunc());
this.echo("value: " + del);
And here the code that did work:
var del=this.evaluate(function()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
});
this.echo("value: " + del);
It seems to be the same, but it works different, I don't understand.
And here a code that did also work:
function myfunc()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
}
var del=this.evaluate(myfunc);
this.echo("value: " + del);
The difference here, I call the myfunc without the '()'.
Can anyone explain the reason?
The problem is this:
var text = this.evaluate(myfunc());
Functions in JavaScript are first class citizen. You can pass them into other functions. But that's not what you are doing here. You call the function and pass the result into evaluate, but the result is not a function.
Also casper.evaluate() is the page context, and only the page context has access to the document. When you call the function (with ()) essentially before executing casper.evaluate(), you erroneously try to access the document, when it is not possible.
The difference to casper.evaluate(function(){...}); is that the anonymous function is defined and passed into the evaluate() function.
There are cases where a function should be called instead of passed. For example when currying is done, but this is not applicable to casper.evaluate(), because it is sandboxed and the function that is finally run in casper.evaluate() cannot use variables from outside. It must be self contained. So the following code will also not work:
function myFunc2(a){
return function(){
// a is from outer scope so it will be inaccessible in `evaluate`
return a;
};
}
casper.echo(casper.evaluate(myFunc2("asd"))); // null
You should use
var text = this.evaluate(myfunc);
to pass a previously defined function to run in the page context.
It's also not a good idea to use reserved keywords like del as variable names.
Despite excessive googling I just don't get why my function doSomething does nothing in the situation below. Any idea why it doesn't work?
Many thanks, Gordon
var arrAttend=new object();
arrAttend["Blob"]='hello';
function doSomething() {
alert (arrAttend["Blob"]);
}
It's a typo, you should use new Object (capital O). Or use an Object Literal:
var arrAttend = {Blob: 'hello'};
function doSomething() {
alert (arrAttend.Blob);
}
Two problems :
object isn't defined
you don't call your function
Try this :
var arrAttend= {}; // that's the simplest way to create a new javascript object
arrAttend["Blob"]='hello';
function doSomething() {
alert (arrAttend["Blob"]);
}
doSomething();
Note that the first kind of error is very easily found when you look at the console : an error is displayed. I'd suggest you to use developer tools (for example Chrome's ones) so that you don't develop in the blind. BTW you'd see that using console.log instead of alert is most often more convenient.
Try this :
var arrAttend=new Object();
arrAttend["Blob"]='hello';
function doSomething() {
alert (arrAttend["Blob"]);
}
There's typo error in your code. And an object should be used like follow -
var arrAttend= {
name:'Blob'
};
function doSomething() {
alert (arrAttend.name);
}
doSomething();
Try this:
// create object
var arrAttend=new Object();
arrAttend["Blob"]='hello';
function doSomething() {
alert (arrAttend["Blob"]);
}
// call function
doSomething();
Very new to JS here. When I write PHP I have no problem assigning variables inside a function, but inside a JavaScript function it doesn't work. Why?
example:
function hello() {
var animal = 'Dog';
document.write(animal);
}
Are you calling the hello() function anywhere? If not, you will not execute the contents of the function and thus, no write will happen.
put this snippet inside your function to check if your function is being called
alert('snippet');
If a message box appears, your code should work, but if it does not then the function is not being executed, post some html coding also.