Currently, to see console.log()
entries from StackSnippets, you need to open your browser console, and make sure it's recording from frames. Things could be a lot simpler if you would add a console to the snippets. Maybe something at the bottom of the snippet.
This could be done by overwriting the default console.log
function with a custom one that both writes to the browser console (keep a reference to the original function), and also writes to the snippet's console.
EDIT:
And perhaps also show errors thrown in this console.
6 Answers 6
Thanks for bringing this up!
Thanks in large part to the efforts of canon and his MIT licensed virtual console library for Stack Snippets, we now have a virtual console!
Normally I'd do screenshots, but with Stack Snippets I can just give you a live demo instead. Check it out!
console.log("virtual!");
console.log("console!");
<b>Here's some HTML</b>
-
2Thanks for finally taking care of this!Scimonster– Scimonster2016年05月18日 20:04:12 +00:00Commented May 18, 2016 at 20:04
-
2Yeah, thanks for finally implementing this. Did all the bounties draw attention to this and have any influence on your decision? By the way, here are 500 meta reputation points.Josh Crozier– Josh Crozier2016年05月18日 20:29:40 +00:00Commented May 18, 2016 at 20:29
-
Thanks @JoshCrozier. And no, not really honestly. Or at least not in the way you might think. I don't care about the points so much as the fact that it matters to people enough for them to drop huge bounties on it. That spells out a big need: so I went and solved it with the help of canon.2016年05月18日 20:30:54 +00:00Commented May 18, 2016 at 20:30
-
1David, like several others, I've taken the "Feedback welcomed!" link to mean we should post answers there with feedback, including bug reports and feature requests. Should we be doing that? Or posting them separate as bug or feature-request questions as appropriate? You've implemented one of them in response to one of those answers, but I'm not sure how long you want that model to continue...T.J. Crowder– T.J. Crowder2016年05月20日 14:54:12 +00:00Commented May 20, 2016 at 14:54
-
1@T.J.Crowder either is fine honestly. Having them as answers to that post makes it easy for me to review. And BTW haven't been ignoring you, am contemplating your thoughts and thinking about possibilities. :)2016年05月20日 15:23:12 +00:00Commented May 20, 2016 at 15:23
-
1@Haney: Cool, as more comes up, I'll post them there. Really, really appreciating the renewed attention on Stack Snippets and the console in particular.T.J. Crowder– T.J. Crowder2016年05月20日 15:44:12 +00:00Commented May 20, 2016 at 15:44
A duplicate of this question came up on meta.SO where I suggested a solution, copied here:
I whole-heartedly agree. If the point of these snippets is to enable us to demo functionality and display its output inline, the output pane needs to be adapted to (optionally) mirror logged messages.
Why should we bother avoiding document.write()
and alert()
?
- Both assume a browser environment even if we're demonstrating a purely javascript concept. We certainly don't want either method in the middle of what should be a node.js function.
- Neither are what we're using to debug (I hope)
alert()
is extremely intrusive.document.write()
shouldn't even be suggested to the novice user without a littany of caveats- Neither method offers robust serialization... forget serializing objects.
- Our debugging messages deserve more love than that from our demo tool. We can do much, much better.
My Temporary Solution
I've created a small script to include via the html snippet1 (please leave the comment intact):
<!-- console visualization; see http://meta.stackexchange.com/a/242491 -->
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
1 If we ever get integrated console visualization, we can just remove this script wholesale and it should be very low-impact.
Notes:
- All calls to
console.log()
(info()
,warn()
,error()
,table()
, andclear()
) are passed along to the actualconsole
- Loosely imitates Chrome's output (colors and styles excluded)
- Handles circular references via lazy-expansion.
- Works by injecting elements into the page... so, it obviously pollutes the DOM.
- The number of entries is limited to 50. Older entries will be removed to make room for newer entries.
- Logs unhandled errors.
Here's a demo:
/* config stuff... ignore this line */ console.config({ maximize: true, timeStamps: false });
// sample data
const values = [
1e100,
"a",
true,
new Date(),
x => 1,
/(?:)/ig,
undefined,
null,
document.querySelector("button")
];
// add a circular reference
values.push(values);
// log whole array with circular reference
console.log("array with circular reference: %o", values);
// log each value individually
values.forEach((v, i) => console.log("%i: %o", i, v));
// table output
console.table([
{ Name: "Zoe", Age: 20 },
{ Name: "Xander", Age: 21 },
{ Name: "Cthulhu", Age: Infinity },
]);
// throw a test error
throw new Error("test!");
<!-- console visualization; see http://meta.stackexchange.com/a/242491 -->
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<button>click me</button>
-
12This answer is not receiving enough upvotesSamuel Liew– Samuel Liew2015年07月09日 03:23:30 +00:00Commented Jul 9, 2015 at 3:23
-
2I wish I could assign another bounty for this answer alonecat– cat2016年03月02日 02:59:52 +00:00Commented Mar 2, 2016 at 2:59
-
4Wow, if I understand this correctly, T.J. Crowder gave Canon an enormous bounty, who in turn gave T.J. Crowder an enormous bounty. I just wanted to point out this beautiful sportsmanship.bmende– bmende2016年04月10日 23:58:28 +00:00Commented Apr 10, 2016 at 23:58
-
@bmende It's actually being discussed whether it is a form of abuse.unbindall– unbindall2016年04月14日 02:49:20 +00:00Commented Apr 14, 2016 at 2:49
-
Is there any issue with using firebug instead? It seems perfect for this: codepen.io/anon/pen/vGvXYWMarie– Marie2016年05月04日 13:56:12 +00:00Commented May 4, 2016 at 13:56
-
1Just want to say: You've done a great job with this console. Really fantastic, and I'm glad that SE management have had the sense to take it on board. All of us in the javascript tag salute you!T.J. Crowder– T.J. Crowder2016年05月19日 13:52:33 +00:00Commented May 19, 2016 at 13:52
TL;DR
Best to leave the actual console alone, not least because interfering with it can prevent asking and answering questions related to the console (such as when and how data is expanded on V8's console, which is a non-trivial thing).
Snippets definitely need a built-in, simple means of generating output without promoting poor practices like
document.write
.Specific suggestion for what to provide below, including
(削除) a version hosted on GitHub Pages (削除ここまで)(they've discontinued that URL, though the project is still there) for use until/unless Snippets have their own way.
I think the console should be left alone, not least because interfering with it can prevent asking and answering questions related to the console (such as when and how data is expanded on V8's console, which is a non-trivial thing).
But I'm very keen to see what I think is the main point of this request: A simple means of writing output to the output pane of the snippet.
Right now, people are doing four things:
Using
document.write
. This is awful, it promotes 1990s code in 2014+.Using some function for output, like my usual:
function display(msg) { document.body.insertAdjacentHTML( "beforeend", "<p>" + msg + "</p>" ); }
This is also not good, because it adds a lot of noise, esp. to short snippets.
Using
console.log
, which just makes the output pane of the snippet wasted space.Writing scripts they include in snippets (like mine below), which means the snippet relies on an off-site resource.
None of those is a good solution.
My suggestion is Keep It Simple and inject a snippet
object into snippets (without showing it in the snippet) with a log
(or whatever) method; perhaps both log
and logHTML
:
// MIT license, see: https://github.com/tjcrowder/simple-snippets-console/blob/master/LICENSE
var snippet = {
version: "1.3",
// Writes out the given text in a monospaced paragraph tag, escaping
// & and < so they aren't rendered as HTML.
log: function(msg, tag) {
var elm = document.createElement(tag || "p");
elm.style.fontFamily = "monospace";
elm.style.margin = "2px 0 2px 0";
if (Object.prototype.toString.call(msg) === "[object Array]") {
msg = msg.join();
} else if (typeof msg === "object") {
msg = msg === null ? "null" : JSON.stringify(msg);
}
elm.appendChild(document.createTextNode(msg));
document.body.appendChild(elm);
},
// Writes out the given HTML at the end of the body,
// exactly as-is
logHTML: function(html) {
document.body.insertAdjacentHTML("beforeend", html);
}
};
I've made a version available (削除) here on GitHub Pages (削除ここまで) (they've discontinued that URL) for use until snippets have their own way of doing it. Feel free to insert that at the top of a snippet like this:
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
A simple snippet
object like that solves the issues with what people are doing now. Consider this example:
Question:
How do I create an array with just a subset of the contents of an existing array in JavaScript? For instance, only non-negative numbers?
Answer:
You can use ES5's Array#filter
for that. It calls a function you supply, passing in each entry in the array, and builds a new array from the entries you return a truthy value for:
var a = [10, 0, -5, 7, 12, -3, -1];
var filtered = a.filter(function(entry) {
return entry >= 0;
});
snippet.log("original: " + a.join(", ")); // "10, 0, -5, 7, 12, -3, -1"
snippet.log("filtered: " + filtered.join(", ")); // "10, 0, 7, 12"
(Obviously if you try to run that, you'll get an error, as snippet
isn't defined.)
Isn't that better than:
var a = [10, 0, -5, 7, 12, -3, -1];
var filtered = a.filter(function(entry) {
return entry >= 0;
});
display("original: " + a.join(", ")); // "10, 0, -5, 7, 12, -3, -1"
display("filtered: " + filtered.join(", ")); // "10, 0, 7, 12"
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" + msg + "</p>"
);
}
-
3@canon: I've been using the
snippet
object above, loading the script from github.T.J. Crowder– T.J. Crowder2015年02月11日 08:13:38 +00:00Commented Feb 11, 2015 at 8:13 -
1I'm not sure if having a separate snippet object is very discoverable. Right now I think the first thing most people will do is try to use "console.log" and then wonder why its not working.hugomg– hugomg2015年05月15日 13:27:48 +00:00Commented May 15, 2015 at 13:27
-
1@hugomg: Very easy to detect
/\bconsole\./
and show a fadeover message saying what to do. Whenever you take over something like that, you immediately open yourself up to getting in the way of improvements/innovations for it, special features it has on some platforms, questions like this one today about the console itself, etc., etc., etc. Or we could try to fully emulateconsole
, but if so, I'd want an opt-out option (likevar console = realConsole;
), but I think it would be much better just not to get in the way in the first place.T.J. Crowder– T.J. Crowder2015年05月15日 13:41:21 +00:00Commented May 15, 2015 at 13:41 -
1Another alternative would be adding a tab titled "snippet.log output". I just think its important to get "in the way" somehow to avoid the common problem of trying console.log and it just showing a blank result tab.hugomg– hugomg2015年05月15日 14:11:57 +00:00Commented May 15, 2015 at 14:11
-
2I'd prefer to see us detect and handle that, which is trivial. But it's just my view. Also, given the complete absense of any kind of meaningful development on Stack Snippets in the last eight months, I think smaller = slightly more likely to actually happen.T.J. Crowder– T.J. Crowder2015年05月15日 14:13:42 +00:00Commented May 15, 2015 at 14:13
-
msg = msg === null ? "null" : JSON.stringify(msg);
vsmsg = JSON.stringify(msg);
? JSON.stringify returnsnull
if null. or do i miss something?Nina Scholz– Nina Scholz2015年08月15日 16:50:18 +00:00Commented Aug 15, 2015 at 16:50 -
1@NinaScholz: At the time, I wasn't sure that was specified behavior. Now, I'm pretty sure it is. Still, the check prevents converting
null
to"null"
and then parsing"null"
back tonull
, so...T.J. Crowder– T.J. Crowder2015年08月15日 16:53:00 +00:00Commented Aug 15, 2015 at 16:53 -
Yep, in the absence of any built-in snippet behavior, I'm usually using
document.write()
just because it's simplest and seems the least complicated to viewers. in jsFiddles, I use my own off-site script resource because that script resource can be added to the jsFiddle, yet not complicate the code display. Since that is not the case with snippets, I just usedocument.write()
and live with that 80's feel to it. There really should be something built into StackOverflow snippets. It doesn't need to be much (perhaps 5 lines of code to expose alog()
function.jfriend00– jfriend002015年09月04日 04:06:21 +00:00Commented Sep 4, 2015 at 4:06 -
1@canon: LOL! Get this: I never upvoted yours, either. Crikey.T.J. Crowder– T.J. Crowder2016年04月24日 10:01:55 +00:00Commented Apr 24, 2016 at 10:01
-
@T.J.Crowder -- Quick heads up, a console has finally been implemented.Josh Crozier– Josh Crozier2016年05月18日 20:33:24 +00:00Commented May 18, 2016 at 20:33
-
@canon - Interesting! FWIW, I wouldn't use the dark background, doesn't fit with SO's design and of course for the demo part it's not what browsers do by default... Do you have any SE engagement on this, or is this just your own project?T.J. Crowder– T.J. Crowder2018年12月02日 09:16:25 +00:00Commented Dec 2, 2018 at 9:16
-
@canon - Cool. (Yes, I prefer a dark background for coding as well.)T.J. Crowder– T.J. Crowder2018年12月02日 11:13:21 +00:00Commented Dec 2, 2018 at 11:13
-
looks like the link to your stack snippet's broken2020年07月28日 18:39:21 +00:00Commented Jul 28, 2020 at 18:39
-
@JourneymanGeek - Yeah, GitHub yanked those URLs. :-| But we have a snippets console these days, so... (I've been slowly working my way through the ~340 SO answers I had using that link to switch to the snippets built-in console...)T.J. Crowder– T.J. Crowder2020年07月29日 07:33:35 +00:00Commented Jul 29, 2020 at 7:33
This actually isn't the best snippet. See the answers below by T. J. Crowder and canon for better console simulations.
There is an important difference though. Mine is a userscript which applies to all posts. The others are for including in a specific snippet, for everyone to benefit from.
I've created a script to do this. You can read more about it here on Stack Apps. Download it from Greasy Fork.
See it in action! (Image from this post)
enter image description here
Update (2014年10月12日):
Now shows errors.
I bring news (and hope) from the inaugural meta.SE Community Town Hall chat event.
Here's a partial transcript:
canon: @Haney any chance we can have a discussion about Stack-SnippetsTM?
Undo: @canon What specifically?
canon: @Undo console output (meta.stackexchange.com/a/279053/159427)
Haney: @canon I don't want to hijack the conversation, but know that's it's on our radar for sure. We definitely want to do it, just a matter of finding time right now
canon: @Haney Just to clarify, you definitely want to have a discussion... or definitely want to implement console visualization?
Haney: @canon we think a console offering would be an awesome benefit (and win-win, could enable / disable it probably within snippets). Just need to find time to implement.
canon: @Haney great!
Haney: hey @canon what kinda license do you have on your stopgap console js there? ;)
canon: @Haney I think I blindly picked MIT
Haney: good, good
Haney: @canon see my job gets easier when the groundwork has been done for us... MIT license would let us adopt this readily. I'll see what team thinks next week
Update:
Haney posted a comment on the town hall chat proposal:
@canon we've agreed to investigate the library over the next couple of weeks, we're leaning towards including it but no promises... yet.
After a long time, I've decided to post my answer.
I've started it in April this year and I've improved it these days.
My code, currently, takes control over the console
object in a 'different' way (I'm missing the right word).
The code handles the following methods in the console
object:
log
error
warn
info
time
timeEnd
clear
Also, it shows objects and arrays in a tree-like view.
A few examples of what the code can do:
//starts the console and tells to use the specific element to add the messages there
console._RELAY_TO_DOC = document.getElementById('messages');
//misc stuff, only _USE_JSON has the default value
console._USE_JSON = false;
console._SHOW_COOL_NUMBERS = true;
console._SHOW_TYPES = true;
console._SHOW_STRING_LENGTH = true;
//just use the console now:
console.time('test');
console.log(1,[],{},'string',[1,2,3,4,5],{a:1,b:2,c:3});
console.warn('Too much awesomeness!');
console.info('You are informed.');
console.error('Oh no! We divided by 0!');
console.timeEnd('test');
throw new Error('This will show in the console');
* {font-family:sans-serif;}
html,document {overflow:hidden;}
#console{
position:absolute;
top:0px;
right:-300px;
-webkit-transition: right 1s;
transition: right 1s;
height:100%;
max-height:100%;
}
#show {display:none;}
#show:checked+#console{right:0px;}
#show_button{
display:inline-block;
width:20px;
height:40px;
text-align:center;
border:1px solid #ccc;
-webkit-border-top-left-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-bottomleft: 5px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
background:white;
cursor:pointer;
float:left;
padding-top:20px;
}
#messages {
width:300px;
float:right;
min-height:100%;
max-height:100%;
height:100%;
background:white;
overflow-y:scroll;
border-left:1px solid #ccc;
}
textarea {width:350px; height:130px;}
<!-- load the script -->
<script src="http://ismael-miguel.github.io/console-log-to-document/files/console.log.min.js"></script>
<span> All the messages are present there --> </span>
<input type="checkbox" id="show" />
<div id="console">
<label id="show_button" for="show" checked="checked"> ▶ </label>
<div id="messages"><span>List of all messages:</span></div>
</div>
<div>
Eval you code here: (write and click outside)<br>
<textarea onchange="Function(this.value)();">console.time('test');
console.log(1,[],{},'string',[1,2,3,4,5],{a:1,b:2,c:3});
console.warn('Too much awesomeness!');
console.info('You are informed.');
console.error('Oh no! We divided by 0!');
console.timeEnd('test');
throw new Error('This will show in the console');</textarea>
</div>
I've asked @canon to lend me an important feature of his code: the ability to handle exceptions when uncaught.
There are also a few options in the console
object:
_RELAY_TO_DOC
- Enables/disables the logging of the messages in the document.
You can set it totrue
or set it with anElement
._USE_JSON
- Simply returns a JSON string. Overrides all and every option from now on._SHOW_COOL_NUMBERS
- Show numbers in binary, octal and hexadecimal representation_SHOW_TYPES
- Show the data type of an element._SHOW_STRING_LENGTH
- Shows the string length.
It also adds 2 methods to the console
object:
_restore_old_method
- Restores a method (e.g.:log
) to the default value_restore_relay_method
- Does the oposite of the above method
I hope you like it!
You can visit http://ismael-miguel.github.io/console-log-to-document/ for a full explanation of the code and it's functionality.
To make it work in any page, just paste <script src="http://ismael-miguel.github.io/console-log-to-document/files/console.log.min.js"></script>
into your <head>
.
Warning:
- This does not like recursion (it is safe to use with
Element
s, it is prepared to ignore it's recursion) - The code can't handle very huge elements (like
document
) - This may burn a lot of CPU if misused
- The
time
andtimeEnd
aren't accurate, but close enough to the real result
-
"Sweet" doesn't begin to describe thiscat– cat2016年04月10日 00:54:14 +00:00Commented Apr 10, 2016 at 0:54
-
@cat Thank you! I still see some rough edges that need some polishing. If you have any ideas on how I can improve it, I'm listening. I had fun making this code and hoped someone would find it useful. Once again, thank you for your comment!Ismael Miguel– Ismael Miguel2016年04月10日 09:39:03 +00:00Commented Apr 10, 2016 at 9:39
You must log in to answer this question.
Explore related questions
See similar questions with these tags.
document.write
, which is just a terrible idea. It doesn't have to beconsole.log
, just something. Perhapssnippet.write("HTML goes here")
.console
exists" then you can't call yourself a "programmer" (well not a web one at least). This is 2014 people not the 90s.