Why can't I expand this event object in the chrome console? - javascript

Simplified, what I'm doing is running this in the console:
window.onbeforeunload = function (e) {
console.log(e);
}
In the console, when the event fires (by trying to "leave page" in the middle of writing an SO question) what I see is this:
Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: document, defaultPrevented: false…}
With a little "i" graphic next to it. When I click the arrow next to it to expand the object in the console, nothing happens. The arrow turns to indicate that it has expanded, but it doesn't expand.
What am I missing here??

This is happening because although you're letting the console persist over page changes, the Object no longer exists - it was destroyed when you left the page. This means it's simply not available to be inspected anymore, so clicking the down triangle is not helpful.
Try this instead, to prevent the page actually changing:
window.onbeforeunload = function (e) {
console.log(e);
return true;
}
Now the page will prompt to ask you what to do. Click 'cancel' in the prompt that comes up in order to remain on the page. Now you can inspect the Event in the console as desired.
The difference is that the onbeforeunload function is now returning a value that isn't null/undefined. The return value could be anything, even '' or false, etc...anything except null and undefined, and it will still cause the page to prompt before navigating away and thus giving you an opportunity to inspect the event. Remember that with no return statement, JavaScript functions return undefined by default.
Whenever you can't inspect something in the Chrome Dev Tools, 90% of the time it's because some action has caused that thing to become unavailable...the page has moved on from when that object existed.

The failure to expand can mean that the object was subsequently removed from memory: possibly deleted or garbage-collected, or (especially if you're using Chrome dev tools on a Node.js script) it could be that the script completed, so all refs now point nowhere.
It's a good practice when inspecting objects that can change later to drop in a debugger instead of console.log:
window.onbeforeunload = function (e) {
debugger; // Now go find `e` in the local variables section
}
This pauses the execution of the code, so you know for sure you're seeing what the variable was at this point, rather than seeing any subsequent changes.
This way, you can access more context and don't need to worry about changes to output caused by what happens later in the code.
Always remember that in JavaScript, any time you deal with a variable that points to an object, you're dealing with a live reference, to the latest state of that object.
console.log logs the reference, not the object's contents, and when you view and expand the logged reference, you're viewing what that reference points to at the time you look at it, not the time you logged it. This might be nothing if it has been removed from memory or reassigned.
Variables pointing to primitives like strings and numbers point to values not references, so you could also:
log a stringified version of the object, like console.log(JSON.stringify(someObject)) (although that output may be harder to read).
if the object's properties are all primitive, log a shallow clone like console.log({ ...someObject }) (though any properties that are objects may face the same problem)
The debugger approach is usually better.

Old question. But this simple solution worked better for me. Use
function(e) {
console.dir(e);
}

I just came across this question with a problem I had where my API PUT request was showing as cancelled in my console tab in chrome dev tools and I was seeing the same behavior where I couldn't expand the object and the little i icon was showing next to the console entry. I decided to post this answer with a link to my question in case it might help anyone else.
Api PUT request showing as "cancelled" with error message "TypeError: failed to fetch"

Related

Logging a function / element / node in chrome inspector does not show all details like firebug used to do

Back in the good old days with firebug, if one console.log(aFunctionThatHasOtherProperties) the inspector would show all properties on it, properties and objects that has been attached to it.
Chrome inspector instead only shows the body of the function.
I would like it be logged, as if it was an object being logged. A function is an object after all, and the choice to build on a function or {} could be made for reasons not to be dwelled into.
Chrome inspector will only log the function as seen in the picture, and body, and it is hard sometimes to detect that there are other things, on the function one could call.
Is there a way to console.log a function and get it to log as if it was an object?
Is there a setting for this?
Same thing with logging a node or element.
Chrome will just show you the element but there are functions and properties on, sometimes desirable to immediately be able to look at. For elements one can navigate to the couple of places in the dom tree, but it is not as nice.
Currently chrome will look the element to be clicked at.
I know i can hack something like outputting keys, but i am looking for a navigational way, as if was an object, which it is.
If it does not does firefox dev tools offer something like that, although I would like to avoid having to make that switch.

How did I lose JavaScript built-in objects and all global variables?

I'm working on an Umbraco site that needs to work in the big browsers, including IE 11, and I've run into a weird issue that I can only replicate on IE 11.
At some point, the script for a TinyMCE plug-in tries to execute this code (about four calls deep) in response to a blur event:
function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
and it throws a "Object doesn't support this action" exception when trying to create the RegExp object. cls is defined and has the value I expect.
While paused (using Visual Studio debugger) on the unhandled exception, I did a little checking.
It turns out that RegExp was undefined. I found this extremely weird.
A little more investigation revealed that ALL the built-in objects were undefined. Number, Array, Object, Math... all of them. Also, while I could enumerate the global keys, all the values were also undefined.
Weirder, I could use the console or immediate-execution windows, within the problematic scope, to create regular expression objects by using the /pattern/ syntax.
But this condition is true only in the scope of the event handler. As soon as the event handler exits, all the built-in objects and global variable values were restored.
How is it even possible to lose access to the built-in JavaScript objects, without losing access to the basic JavaScript parser and engine?
And, once lost, is it possible to restore them?
I experienced this problem as well, and assuming you're also having trouble with the TinyMCE CodeMirror plugin, the problem is triggered by this line in codemirror.js:
on(window, "blur", function () { return forEachCodeMirror(onBlur); })
where window refers to the iframe containing the CodeMirror editor.
This iframe is inside of a TinyMCE dialog. I've discovered the error only occurs when the iframe (or an element inside it) loses focus at the same time that the dialog is closed, removing the iframe from the DOM. You can test this by first clicking outside the iframe (on the page overlay, for example) before closing the dialog.
IE11 seems to be calling the blur event after it has started destructing the iframe's window object. I would classify this as a bug in IE11, which will never get fixed. Since we probably don't care about the blur event in an iframe that's being removed from the DOM, we can work around the problem by modifying the problem line to skip it in that case:
on(window, "blur", function () { if (window.RegExp) return forEachCodeMirror(onBlur); })

Find out if object is still in memory

Is there any way to find out if a javascript object that was referenced somewhere in the code is still alive and in memory?
the reason i ask is that my code got really complicated and I added some "cleanup" functions that are supposed to clear some of the references but I'm not sure if they work as they should. Can I somehow get a list of variables that are still in use by the browser?
In chrome, press F12 to open the debugger, then do the following:
Click the [Timeline] tab
Click the [Record] button in the top-left; play around with your site, open a menu, load a page, etc, where you want to check the memory.
Whilst it's still recording, press the [garbage collector] and wait for a few seconds to let the buffer collect more data. Now press the [record] button again to stop the recording.
Once the recording has stopped, you will see a 'stair-step' of how memory was allocated onto the heap.
Importantly, you should see the lines return to zero after you hit the [garbage collection] button. If this doesn't happen, then you may have a memory-leak.
There are some very detailed videos from google advocates, explaining this debugger feature and is beyond the scope of this simplistic answer. This is just a pointer to a debugger feature you may want to use to test your code and find which objects are on the heap and if they're cleaned up as expected.
You can do further analysis of your objects with the [profiles] tab.
JavaScript is completely managed language and doesn't allow any kind of delete function.[delete keyword only deletes the properties but doesn't delete objects from memory]
Best bet to clean any object is to assign to null to give a hint to garbage collector still may not work in all scenarios.
Hope this helps

Why is google chromes console delayed? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Chrome’s JavaScript console lazy about evaluating arrays?
Basically what I am finding is that google chrome is having issues with it's developer tools.
Take this snippet for example:
console.log($(this).find(' .buttons .cancel'));
$(this).find(' .buttons .cancel').remove();
When that snippet is triggered, if there are two items that match those selectors google chrome outputs [, ]. basically it is finding the elements, but it seems to be slower at displaying the data than it should be.
I want to be able to log what items I am deleting, but as it stands I must run it first without the .remove() line. and then after I know that is working I can run it again with the remove() function.
Consider the following test:
a={a:'a'}. It returns an object.
a.a='b'
expand the return from the first command. It shows a: "b"
So, an object is always shown in the state it is in when it first gets open in the Chrome developer console. For (pseudo-)arrays, what matters is the state of the object when the console gets to it. This could be right after the normal javascript returns (hard to tell why. Performance reasons, perhaps).
You can handle this by always logging elements that don't change, such as:
primitive values: console.log("hello")
clones of DOM nodes or jQuery objects: console.log($(this).find(".buttons .cancel").clone())
If logging an immutable object is not an option, you can still log while tracing the code: console.log(document); debugger;
If you pass an object to Google Chrome's console.log() that is not a primitive value like string or a number, it does not output that object's contents immediately. Probably due to some interprocess communication, there is some delay in actually getting the data from the object and outputting to the console. This will/can cause problems if you are immediately modifying the same object as you won't necessarily get the right thing displayed in the console.
One work-around is to only pass finished strings to console.log(). Since strings are immutable, they will never get changed by anything else so you won't get deceived by console.log().
In your case, you are removing the DOM elements in the next line of code. Because of Chrome's timing weirdness, this removes the DOM elements before console.log() can actually see what they are and output them. You could do something like this instead which makes the displayed string immediately and passes that string to console.log():
console.log($(this).find(' .buttons .cancel').toString());

How to copy watched javascript variable in Chrome?

I put a breakpoint in javascript and am testing some code with Chrome. I also added a watch expression for the value.
Chrome breaks at the breakpoint and shows the value. However the value is very long, and it doesn't display it all. I move the window separator to the left but it stops at mid screen. When I double click on the watched variable it wants to edit the expression. When I single click and drag on it, it selects the visible text, but not all. Right clicking does nothing.
This is what I see
url: "m=mtgoxUSD&SubmitButton=Draw&r=&i=&c=0&s=&e=&Prev=&Next=&t=S&b=&a1=&m1=10&a2=&m2=25&x=0...
I want to copy the whole expression without the ... in the end. How can I do that?
I'm adding a late answer after nearly 3 years because with the current Chrome Dev Tools, neither approach work if you have an Array or even just a nested Object property in that variable, following both answers you'll just end up copying a string with a lot of Array[size] or Object strings interleaved in the actual object value, completely useless for complex object hierarchies.
The suggested approaches are ok if you just need to manually navigate through the value but not if you need to copy it as requested in the question.
What i recommend instead, especially if you need to copy the watched value to use it as the content of a new variable, is to dump it to console after it has been stringified.
Show the Javascript console and type:
console.log(JSON.stringify(my_watched_var))
This way the complete structure will be displayed in pure Javascript, a fully reusable/copyable way.
Chrome DevTools' console command-line has a built-in "copy" function:
copy(my_variable)
If the value of my_variable is not a string, it will automatically be converted to JSON. The resulting string is left on the system clipboard for pasting.
Here's the reference doc.
Show the console, then type the expression to be displayed and press . You'll see whole value and you'll be able to select and copy it.
While the debugger is paused, this works even with expressions that involve local variables that are in scope at the current point of execution.
Here's what I do.
Edit: This works in the Scope Variables which is below the Watch Expressions panel.
Double click on the value to switch to edit mode.
Ctrl+A (windows) or Cmd+A (mac) to select the entire value.
Ctrl+C (or Cmd+C) to copy.
Look this answer "Is there a way to auto expand objects in Chrome Dev Tools?" , it iterates trough all the properties of an object and it shows the full hierarchy including datatype and values.
Useful if you need to compare two states of an application.
This link has amazing descripion: https://scottwhittaker.net/chrome-devtools/2016/02/29/chrome-devtools-copy-object.html
Steps:
1) Right click variable and select "Add as Global Variable"
2) In the console, write copy(temp1)
3) Open any editor and paste

Categories