r/javascript • u/georgeharveybone • Jul 28 '18
Tiny tip for debugging anonymous functions
I really like to write implicitly returned anonymous functions like:
const example = (stuff) => stuff;But in my ignorance to quickly debug my function I would then tediously convert it like so:
const example = (stuff) => {
console.log(stuff);
return stuff;
}That, however, was before I discovered the Comma Operator! Long story short it evaluates each expression but only returns the last. So therefore you can write that quick, messy debug instead like so:
const example = (stuff) => (console.log(stuff), stuff);Hopefully I wasn't the only other person in the world doing this, and someone finds it helpful!
51
u/prashantpalikhe Jul 28 '18
I recently published more debugging tips using Chrome devtools. Can be useful.
Check it out at https://medium.com/@PrashantPalikhe/art-of-debugging-with-chrome-devtools-ab7b5fd8e0b4
4
u/igor_sikorsky Jul 28 '18
Wow, I actually learned quite a bit from that. Thank you!
0
Jul 28 '18
[deleted]
1
u/igor_sikorsky Jul 28 '18
Also interesting. I've always been looking for some more in depth tutorials for the chrome dev tools
2
u/itsnotlupus beep boop Jul 28 '18
The only problem with the chrome Dev tools is that I feel like I'm being punished when I have to go debug something in Safari.
1
1
31
u/2Dfroody Jul 28 '18
another option is
const example = (stuff) => console.log(stuff) || stuff;4
u/madcaesar Jul 28 '18
I assume console.log always returns undefined right?
6
u/turntopage294 Jul 28 '18
Yes, it does, simply because the value of anything that doesn't return something is undefined by default.
Console.log returns nothing, doesn't it? But wait, even "nothing" is a definite value. So it's more accurate to say that it doesn't return anything. Which simply means that its return type is not defined, i.e. undefined.
16
1
u/IHeartMustard WILL CODE FOR CAFFEINE Jul 29 '18
I use this one all the time, but I always cringe a little when I do. I think I will start using OPs version.
1
u/2Dfroody Aug 02 '18
yeah, it's not something you'd want to have in your codebase, but for a quick check it works
-2
5
9
u/ssjskipp Jul 28 '18 edited Jul 29 '18
Personal favorite since you can toss it into any composition:
const tap = (cb, fn) => (...args) => {
cb(...args);
return fn(...args);
}
tap(x => console.log(x), fn)Lodash has this implemented nicely.
3
u/console_journey Jul 28 '18
Holy moly, I think I understand what this does but I am not sure. Are ...args the returned values from function fn, and you use this ...args as function parameters? I'm confused...
5
u/ShortSynapse Jul 28 '18
The code snippet is missing a closing parenthesis after the argument
fn.
cbandfnare arguments of the tap function. When you call that function, you are returned with another function whose arguments (...args) will be logged and then sent to the supplied function (fn) before being returned.3
u/cuntopilis Jul 28 '18
in other words
function tap(cb, fn) { return function(...args) { cb(...args) return fn(...args) } } function adder(x, y) { return x + y } const result = tap(console.log, adder)(2, 4) // > 2 4 console.log(result) // > 6 // or const printAdd = tap(console.log, adder) console.log(printAdd.toString()) // function(...args) { // cb(...args) // return fn(...args) // } const newResult = printAdd(2, 4) // > 2 4 console.log(newResult) // > 61
33
u/remaze Jul 28 '18
People will never learn to use debugger
46
Jul 28 '18
Oh come on. I am using JS in many different contexts: the browser, nodejs and various test runners and there are plenty of situations where attaching a debugger is tedious for whatever reason.
15
u/godlychaos Jul 28 '18
I agree, trying to figure out how to get - - inspect-brk passed to a mocha test runner is something I can never remember and always have to look up.
But, have you seen the module called ndb? I think it is fairly new. It is a module you can install globally, and use to start any node process (including one's called from a test runner or whatever) in debug mode. It also opens its own debugging window instead of having you open a special tab in chrome.
I suggest you give it a look, it seems really slick from what I read and saw about it last week.
3
1
Jul 28 '18
I'm wondering if it's possible to attach Visual Studio debugger to my browser to debug JS in it. It's just so damn nice to use.
1
Jul 28 '18
It is.
1
Jul 28 '18
actually Visual Studio or VS Code? I know the latter can be attached, but the former is better.
2
-8
u/remaze Jul 28 '18
From my experience usually if it is tedious to attach a debugger means you're doing something wrong.
How is it tedious in a browser?
You cannot run node --inspect?
Test runners do not use node?
2
Jul 28 '18
Until recently I would say attaching a debugger to a clustered app is pretty tedious but just heard about nbd a couple weeks ago that might solve that problem.
3
u/madcaesar Jul 28 '18
What do you mean?
5
u/remaze Jul 28 '18
1
u/madcaesar Jul 29 '18
So how do you find this breakpoint to set in a huge react bundle file during development for example? You have to keep opening bundle.js in the resources tab and search for the function name and hope to find it in 20000 lines of code?
1
u/remaze Jul 29 '18
Why do you bundle during development?
1
u/madcaesar Jul 29 '18
What do you mean? Webpack dev server creates the bundle during development.
1
u/remaze Jul 29 '18
I meant what I said, you don't need everything bundled during development. Webpack only does whatever you configure it to do
1
u/madcaesar Jul 29 '18
Hm not sure what you mean, I used create react app > eject. It's setup to bundle one file for development.
2
u/yee_mon Jul 28 '18
There are legitimate reasons for using console.log instead of the debugger. What if that code path gets called 300 times but I am only interested in a specific one of them? A breakpoint would be painful, but in the console I will see immediately what I was looking for.
4
3
u/epicpoop Jul 28 '18
Same issue with debugger here
5
u/MUDrummer Jul 28 '18
No there isn’t. Use one of the many ways available to use the Chrome developer tools as your inspector and you can set break points at multiple places on the same line.
3
u/epicpoop Jul 28 '18
I was talking about the debugger js keyword. Using chrome dev tools you can set it, true. But you can’t do it while coding. You have to go through the code in the browser and set it there.
-3
u/remaze Jul 28 '18
Yeah let's bloat code with console logs.
And can you change console logs in runtime as easy as breakpoints?
3
u/deltadeep Jul 28 '18
Problem with chrome breakpoints alone is you have to *find* the spots in the code to add the breakpoints. You're hunting through some awful tiny-framed source code dump in chrome to find where to insert them probably using horrible inline searches to try to locate the code. Versus being in your actual editor and just dropping in a console.log or debugger statement, far easier. And if you're using a transpiler or other build tool to produce compiled javascript, as many are these days, the source chrome sees is often just a huge concatenated file full of less readable code - very difficult to use as a first class environment to find and debug relevant code sections.
1
u/remaze Jul 28 '18 edited Jul 28 '18
Imagine up-to-date chrome/node can run ES8 so you don'e have to transpile while developing, even if you're coding in TS you don't have to mangle the output, and it also supports global search though source files and can open files with ctrl+p.
Edit: It's up to developer whether to setup a proper and comfortable dev env or not, usually people just slap on everything they could find and shoot themselves in a leg with crappy sourcemaps and whatever else there is that messes up youd debugging experience
1
Jul 29 '18
If you're having that issue with transpiled code you can usually solve it with sourcemaps. Webpack has always had it
1
u/mrtobo Jul 28 '18
They're fine if you wrap an if (debugMode) around them IMO, even helpful at that point.
Edit: I also use the debugger keyboard tho.
1
u/epicpoop Jul 28 '18
I avoid console logs for debugging, but setting debugger; in the code is more handy than looking for the piece of code you’re trying to debug once again in the browser
3
4
u/Panacean Jul 28 '18 edited Jul 28 '18
I never find the comma operator worth considering due to readability. What you had before was very straightforward, so it's just a matter of personal preference here.
16
u/DrDuPont Jul 28 '18
I'm sure OP isn't talking about actually comitting this. They're just pointing out that when debugging, the latter option is quicker to type out.
5
u/Panacean Jul 28 '18
You're absolutely right. And I definitely concede that this would be valuable for a quick test without committing.
2
u/FormerGameDev Jul 28 '18
I think OP means, ultimately, if you default to using
const x = (y) => (whatever);instead of
const x = (y) => whatever;then it's easier to add a console.log() with a comma, then remove it later, without having to reflow it as a bracketed function with a return.
2
u/NarcolepticSniper Jul 28 '18
What on earth; how did I not know about this?
Been doing bracket-conversion debugging for over a year :(
1
1
u/DarkKunai Jul 28 '18
We've all been here, but never did this occur to me once. Kudos for sharing this!
1
u/Xananax Jul 28 '18
I prefer
const log = (...args) => console.log(...args), args[0]
const example = (stuff) => log(stuff)this way, it's easy to see the 'log', and fast to remove. In production, replace the log function with an identity function
1
u/rahulchandak Jul 29 '18
Anyone has more efficient (good) way to debug publish/subscribe or observables??
1
1
3
Jul 28 '18
[removed] — view removed comment
2
u/arktippr Jul 28 '18
u/georgeharveybone. You have received
Ѧ3.00000000 ARK ($3.74 USD)!Check this transaction on the Ark blockchain
Use ArkTippr | FAQ | Ark.io | Explore Ark | Terms of Use | r/arktippr
Ark provides users, developers, and startups with innovative blockchain technologies. Point. Click. Blockchain.
84
u/rcfox Jul 28 '18
Even easier: Set a conditional breakpoint with the condition being the console.log(stuff). It returns undefined, which is falsey, so it will never actually break and you can enable/disable without having to reload.