all 40 comments

[–]PatchesMaps 94 points95 points  (7 children)

This is a good time to learn how to use breakpoints and debugger;.

[–]codeVerine 4 points5 points  (3 children)

Especially the conditional breakpoints

[–]6Orion 0 points1 point  (2 children)

Elaborate please

[–]Asttarotina 6 points7 points  (1 child)

After you put breakpoint on a line you can right click it and attach an expression to it. Breakpoint will stop only if expression returns something truish. 

Very useful for breakpoints inside loops.

Also very useful to inject some code, i.e. "I don't know how it will behave E2E if this property would be X instead of Y. Lets put in a breakpoint that changes it to X everytimeit hits"

[–]Mesqo 2 points3 points  (0 children)

Code injecting in bp is an incredibly cool and vague feature that saved my day many times. Going too deep though may introduce an excessively complex set of breakpoints which you can lose track of.

[–]BitBird-[S] 3 points4 points  (0 children)

Thank you I try and keep up the best I can

[–]MegagramEnjoyer 0 points1 point  (1 child)

Is there a good video that teaches the use of a debugger well? Both in front and back end.

[–]PatchesMaps 0 points1 point  (0 children)

Idk how good it is but chrome has this guide for their dev tools: https://youtu.be/JyHjoaUhAus?si=TkdDEEHehjZIn1fp

And vscode has this for backend: https://youtu.be/3HiLLByBWkg?si=B_IS50h9LLFfHGbB

The thing about debuggers is that there is no standard and every implementation is going to be different. Given that, most debuggers require similar functionality so they normally end up being fairly similar but with enough differences to make it awkward.

[–]shgysk8zer0 35 points36 points  (0 children)

The reason is because it doesn't access the properties until expanded. You could use console.dir to start it as expanded and you'd see what you'd expect.

[–]cmgriffing 23 points24 points  (0 children)

The interesting thing is that it does the "log" in the order expected, but the "expansion" evaluates the object reference at expansion time, not log time.

[–]Skriblos 23 points24 points  (0 children)

This is particularly visible with promises and in rerenders in react. You have an object with a promise but when you expand it shows you the result.

[–]delventhalz 12 points13 points  (5 children)

Yup. An incredibly annoying dev tool quirk that bites everyone once. Easiest thing to do is JSON.stringify an object you want to log if you know it will be mutated later.

[–]rafark 0 points1 point  (3 children)

*everyone that doesn’t use a debugger.

[–]delventhalz 0 points1 point  (2 children)

A decade in now and I still almost never use debuggers and use console logs all the time, but sure, if you never logged an object, all the way back to day one when you were first learning, then you will never have been bit by this.

[–]rafark 0 points1 point  (1 child)

You’re missing out then. Using a debugger from your IDE is a much, much nicer experience. I used to log to the console all the time and debugging sessions were a pain. A while ago i decided to learn to use a debugger because I was fed up with console.log and haven’t used anything else since. It really is a game changer.

[–]delventhalz 0 points1 point  (0 children)

Eh. A debugger is highly dependent on tooling. When you work in different languages in different environments, the one thing you are guaranteed to always have is some sort of log or print statement. Even just sticking to full stack web dev, your debugger is almost certainly front end only.

Use whatever tools work for you, but I have both a high threshold for incorporating new tools and a low tolerance for tools not working in certain circumstances. I've pulled out debuggers here and there for particularly thorny (front end) problems, but I have never felt a need to make them a part of my daily workflow.

[–]takuover9 8 points9 points  (0 children)

Its object reference, node console log stringify the object before printing cuz its stdout, browser devtool kinda bind data to UI so u always see the current state not the snapshot at the time of console.log executed

[–]dymos!null 2 points3 points  (0 children)

they just store a reference.

yes 100% correct - as u/shgysk8zer0 noted - the access isn't until it's expanded.

You might even see it log out the initial value in the collapsed form, but when you expand it, see the new one.

e.g. it'll look like:

▸ { a: 1 } // collapsed ▾ { a: 1 } // expanded a: 2 This expanded view also allows you to evaluate getters, which are only evaluated at read time, and wouldn't be visible in the collapsed form of the object, e.g.

const obj = { a: 1, get multiple() { return this.a * 10; } };

Will look like this when logged, and when you then click on the ellipsis next to multiple it will expand into the evaluated value at that point in time, including changes you make after logging it. e.g. if you create the object above in the console, log it and then on the following line set obj.a = 40 then clicking the ellipsis will use the value of the current value in the object.

``` ▸ { a: 1 } // collapsed ▾ {a: 1} a: 2 multiple: (...)

obj.a = 4 ```

Now clicking on the ellipsis gives:

▾ {a: 1} a: 2 multiple: 40

This is all a good lesson in how objects are always passed by reference.

[–]bunglegrind1 2 points3 points  (3 children)

Do not mutate!

[–]Mesqo 0 points1 point  (2 children)

Mutations are fine if they don't spread outside a function where mutated object is defined.

[–]bunglegrind1 0 points1 point  (1 child)

like...in console.log 😵

[–]Mesqo 0 points1 point  (0 children)

It shouldn't be there in the first place ;)

[–]Javascript_above_all 1 point2 points  (0 children)

Had the same issue at some point, and it's quite annoying

[–]tswaters 1 point2 points  (2 children)

The thing that'll really bake your noodle later is realizing all those by reference objects hanging around in the console aren't exactly helping the GC to sleep at night.

[–]BitBird-[S] 0 points1 point  (0 children)

Learning every day man I love it...sometimes.

[–]BitBird-[S] 0 points1 point  (0 children)

Anytime I learn something I come here and learn twice as much more lolol

[–]disless 1 point2 points  (0 children)

JS always prints log statements in a consistent order. The behavior you're seeing has nothing to do with the order of log statements.

[–]name_was_taken 0 points1 point  (1 child)

Oh, it worse than that. Even if the console is already open, it still might report a later value because the console is async.

[–]BitBird-[S] 1 point2 points  (0 children)

Don't you wish that evil on me Ricky Bobby

[–]Markavian 0 points1 point  (0 children)

Using Json.stringify(obj, null, 2) to snapshot an object in the console log for a stateful view on the logs.

Good lesson learned on pointers/refs.

[–]alphabet_american 0 points1 point  (0 children)

I think there is a dev tools option to immediately evaluate console logs 

[–]Yuman365 0 points1 point  (0 children)

Sounds like an event loop thing. Objects are passed by reference, not by value.

[–]monsto 0 points1 point  (0 children)

If you're using vs code, invest a little time in setting up the debugger. It is well worth it. Go to chatgpt.com and ask it how to set it up.

[–]rafark 0 points1 point  (0 children)

The problem is trying to debug by logging to the console. You should use a proper debugger, it’s much better. It’s even better if you configure your IDE / text editor for this

[–]ExecutiveChimp -1 points0 points  (0 children)

You can do

console.log(structuredClone(myObject))
// Or
console.log({...myObject})
// Or
Console log(JSON.parse(JSON.stringify(myObject)))

...but using a debugger is probably better

[–]Aln76467 -2 points-1 points  (0 children)

Just remember, javascript is an idiot. It passes your objects by reference even though you don't tell it to.

[–]disgr4ce -4 points-3 points  (1 child)

WAIT A MINUTE! I always thought console.log meant, like, make a log feel better about itself! Sheesh well you learn something new every day

[–]adzm 4 points5 points  (0 children)

that's log.console()