I have the code below. Which injects the script in head of the page correctly. But why is the "createReview called" message never printed to the developer console?
ps. I'm unsure what this construct is called technically so I just called it an "assigned function".
MyJSObject.createReview = function (c)
In head of page:
if (typeof MyJSObject === "undefined" || !MyJSObject) {var MyJSObject = {};}
MyJSObject.headLoc = document.getElementsByTagName("head").item(0);
MyJSObject.createReview = function (c) {
console.error('createReview called');
MyJSObject.widgetType = c.widgetType;
var a = "https://www.example.com/api/getcompanyreviewdetails/?id=2&callback=MyJSObject.writeReviewsCallback";
var b = document.createElement("script");
b.setAttribute("type", "text/javascript");
b.setAttribute("src", a);
MyJSObject.headLoc.appendChild(b);
};
Then on a button click I call this function, after which I'd expect the "createReview called" message to be printed to the console as an error (I use console.error since there's alreayd a lot of loglines created by other apps and I don't want to have to look for my message. console.log does not show anything either btw):
MyJSObject.createReview({"widgetType":1});
I does appears in your console as an error. bcause it's .error not .log
Maybe you filtered your console for logs and not errors ?
BTW you have an error on this line b.setAttribute("src", a); "a is undefined"
try F12 on this JSFIDDLE
If filter is not the problem, and since it works for me,please try the chrome canary, this happened to me once and was solved on chrome next version.
Are you sure you properly registered a callback to the desired click event?
check that by printing out something there too
$('#buttonToClick').click(function(){
console.log("Check Click");
myJSObject.createReview(..);
});
If you can't find that in the Console it means you are not invoking the createReview method at all
You may try it on a different browser to see if you don't have a bug.
Maybe in your includes, someone overwrote console.log and console.error.
e.g:
console.log = function(){//donothing}
In such case, you should output the function body to your dom to ensure no one altered it.
Idem :
document.getElementById('someJunkDiv').innerHTML = console.log.toString()
Related
I'm doing some studies in Javascript using Twitter website as example. In any website i can open Google Devtools and use the console to manipulate anything on the page, such as get DOM nodes, edit elements and so on.
For instance, when i open 'www.google.com', go to Devtools and type the command above :
console.log('testing');
I get 'testing' string showing in the console.
However, when i open 'www.twitter.com' and do the same thing, NOTHING happens. Nothing is shown in console, just an 'undefined' string as shown below :
Why this behaviour happens only on Twitter website ?
EDIT : Tried the solution proposed on
"delete" - restore native function not working for changed prototype, how then?
But did not work :
In Javascript you can modify your global objects, so it's possible for you to do something like
Array.prototype.push = function(element) {
this[this.length] = 'blah'
}
Now every time you add a element to any array it will always add 'blah';
const myArray = [];
myArray.push(1);
myArray.push(2);
myArray.push(3);
console.log(myArray);
// output ['blah', 'blah', 'blah']
In the twitter website they did the same, although the code is minified you can see it here:
, Y = ["log", "warn", "debug", "info"]
, K = function() {}
, Q = ""
Line 1414 file https://abs.twimg.com/k/en/init.en.caa653749241467e7dbb.js
To make it work again, copy each line and run it on your console (credits for this solution to Rob W):
var frame = document.createElement('iframe');
document.body.appendChild(frame);
console = frame.contentWindow.console
console.log('it works')
If you type in just console.log (without any brackets), you can list the code for the log function on that website. Doing this on Twitter gives you
function (){}
Which is indeed an empty function showing that they've overwritten the default. By contrast, the same on google.com gives
function log() { [native code] }
Which is the default.
I am using console.log(...) for debugging purposes. However the console gets messages from iframes too(I am using iframes in my HTML code). How can I see only the logs that I sent and not the logs that came from iframes?
This is kinda old post, but still, for those who will come here for help:
In Chrome you can check the "Selected context only" (screenshot here) option, and it'll be this.
How about adding a snippet in your JavaScript to catch errors thrown by the iFrames?
You could replace [IFRAME ERROR MESSAGE] with the errors your iFrame is throwing. If the snippet catches an error from an iFrame, it will do nothing, otherwise, it will output the error to the console:
window.onerror = function (msg, url, line) {
if (msg == "[IFRAME ERROR MESSAGE]") {
return true
}
else {
//do nothing
}
}
Make sure to put this code as early as possible in your script.
Reference
Reference 2
Working example (save it as test.html and open in chrome):
<button onclick="myfunction()">x is not defined</button>
<button onclick="myfunction2()">y is not defined</button>
<script>
window.onerror = function (msg, url, line) {
if (msg == "Uncaught ReferenceError: x is not defined") {
return true
}
else {
//do nothing
}
}
function myfunction(){
console.log(x);
}
function myfunction2(){
console.log(y);
}
</script>
In this example, you will see that no errors will be outputted in the console when you click the first button, but you will see errors when you click the second button.
Just filter out (using the Chrome's filter box) the log messages from the iFrame.
In Chrome's Console tab you have a Filter box, type there the name of the file you want to filer out, with a minus sign "-" before the file name.
You can filter multiply files, using space as a delimiter.
For example:
-LogUtil.js -FrameService.js
Or instead of typing, just right click on a log message, and select Hide message from <file_name>.
You can add something like "?nofrm=1" to the src attribute of the page's script tags you want to see logs for. Then in Chrome you can type "nofrm" into the filter to get logs from only them scripts. Add "?nofrm=1" to the url if you want to log inline scripts too.
I wrote a logger service for the client side. I used a pattern by which I can filter out the logs/errors etc which are being produced by my script and not by the iframes.
function logger(){
var pattern="PC:";
var info=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.info.apply(console, arguments);
}
var log=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.log.apply(console, arguments);
}
var warning=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.warn.apply(console, arguments);
}
var debug=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.debug.apply(console, arguments);
}
var error=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.error.apply(console, arguments);
}
return {
info:info,
log:log,
warning:warning,
debug:debug,
error:error
}
}
Here "PC:" is the pattern
You can filter the logs by source / hide from other scripts than you own. It will of course only be a solution if you get logs from a smaller number of scripts
Assume I run my Javascript project in a browser and I'm inside a specific module, can I check whether is already message printed to the console ? i.e. read message from the console...
For example I'm inside my js.file inside function want to check if already printed hello world in the console.
jthanto's answer gave me an idea. I don't think it's good practice, but if you must, you can define your own console class:
var MyConsole = function(oldConsole) {
// store all messages ever logged
this.log = [];
// keep a pointer to oldConsole
this.oldConsole = oldConsole;
}
MyConsole.prototype.log = function(args) {
// push the message into log
this.log.push(Array.prototype.join.call(args));
// call oldConsole.log to actually display the message on the console
if (this.oldConsole)
this.oldConsole.log.apply(this.oldConsole, args);
}
// TODO: implement all other console methods in this fashion (apply for all console API methods)
MyConsole.prototype.<method> = function(args) {
if (this.oldConsole)
this.oldConsole.<method>.apply(this.oldConsole, args);
}
// method to check if something was printed
MyConsole.prototype.wasLogged(message) {
return this.log.indexOf(message)!==-1;
}
// replace console with an instance of MyConsole, pointing to the old console
console = new MyConsole(console);
Save it in a file and load it first (right at the top of your tags)
Use it like:
if (console.wasLogged("Hello World"))
doStuffz();
Hope it helps. Mind it's not tested, but should give you some pointers :)
You could always define your own function for "console.logging" one or more messages (if this is what you are doing), and have a boolean in this function to handle this sort of thing.
I would bet it's not "best practice", but it would solve your problem in some degree.
var messageSent = false;
var myConsoleLog = function($strMessage){
if (!messageSent) {
console.log($strMessage);
messageSent = true;
} else {
// Do whatever you feel like
}
};
Of course if you need to check for more cases you will need to alter the function to actually keep track of more messages. :)
Normally it can't be done. Look at Chrome console's API:
https://developer.chrome.com/devtools/docs/console-api
But this experimental Chrome feature can solve your problem: https://developer.chrome.com/extensions/experimental_devtools_console
Unfortunately it looks like other browsers doesn't have tools like this.
I have a JS script that works fine in all browsers.
But for everybody's surprise, in I.E. it does not work at the first try.
If, after I load my page, I press F12 (open the i.e. debugger) and refresh my page,
it works fine! Just like the others browsers! But for this work, i have to press F12.
Does i.e.'s debugger do something when we open it?
I cant find a solution!
Thanks in advance.
When you don't have the debugger open, IE considers there to be no such thing as console.log, and gives you errors for calling an undefined function. When you hit F12, then you get the console, and so console.log is no longer undefined.
You can workaround by putting this at the top of your code:
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
Rather than editing out console.log from your code, this will merely make the browser do nothing if the console doesn't exist, by defining them as a 'do nothing' function if they are undefined.
If you're looking to shrink down your js file size (particularly important for mobile usage), you will eventually want to remove verbose logging on your release version.
Do you have something like console.log() in your script? This might explain, since there is no console until you press F12
Extended version from previous post
if (!('console' in window)) {
var stub = function() { ; };
window.console = {
log : stub,
info : stub,
warn : stub,
error : stub,
assert : stub
};
}
I'm posting this new one that install stub only if needed
/**
* On IE console is not set if not opened and debug doesn't exists
*/
(function() {
if (!('console' in window)) { window.console = {}; }
var kind = ['log', 'info', 'warn', 'error', 'assert', 'debug'];
var stub = function() { ; };
for (var i = 0; i < kind.length; i++) {
if (kind[i] in window.console) { continue; }
window.console[kind[i]] = stub;
}
})();
I have wrapped calls to firebugs console.log in a logging function (that checks for existance of console along with other flags)
for example:
Log(string) { if (console && DEBUG) console.log(string); }
my issue is that the firebug console shows the line number of the console.log function call rather then the Log function call.
Is there any way to change what line numbers firebug shows?
Firebug does not allow you to change the line number on the console via code.
console.trace() will give you the call stack.
See http://getfirebug.com/logging for more info.
I took a little different approach and just defined a property that sets up a __stack__ variable by intentionally throwing an error, from this we can get the filename, line number (and many others such as callers and their line numbers if you choose to implement them).
Also rather than setting up a log function, I set it up as a variable also, but one that gets logged when set. This will be the location where LOG is set, not where it was defined.
Its as simple as LOG="my message". Then you can use it later as a variable to get the location of your last debug with alert(LOG)
/*#const*/ //for closure-compiler
DEBUG=2 // 0=off, 1=msg:file:line:column, 2=msg:stack-trace
if(DEBUG){
/*#const #constructor*/
Object.defineProperty(window,'__stack__',{get:function(){
try{_ფ_()}catch(e){return e.stack.split(":")}
}})
/*#const #constructor*/
Object.defineProperty(window,'__file__',{get:function(){
var s=__stack__,l=s.length
return (isNaN(s[l-2]))?s[l-2]:s[l-3]
}})
/*#const #constructor*/
Object.defineProperty(window,'__line__',{get:function(){
var s=__stack__,l=s.length
return (isNaN(s[l-2]))?s[l-1]:s[l-2]
}})
/*#const #constructor*/
Object.defineProperty(window,'__col__',{get:function(){
var s=__stack__,l=s.length
return (isNaN(s[l-2]))?"NA":s[l-1]
}})
/*#const #constructor*/
Object.defineProperty(window,'LOG',{
get:function(){return out},
set:function(msg){if(DEBUG>1)out=msg+"\t-\t"+__stack__
else out=msg+" in file:"+__file__+" # Line:"+__line__+", Column:"+__col__
console.log(out)}
})
}//end if(DEBUG)
There doesn't seem to be a way to do that, so I have been using console.group
console.group(file +' (line '+ line +')');
console.log(data);
console.groupEnd();