Why the JSON's are different in Javascript? - javascript

I have written some code and I am printing to console . A very strange thing is happening .Below the screenshot attached :
There are two screenshot attached and in both the screenshots the attribute canvasWidth is showing some strange values. When it is unexpanded it is showing 287(expected) and when it is expanded it is showing 5.
But when I am adding the debug points then it is showing the correct value . Does anyone have any idea why it is showing this strange behaviour ???
Thanks

Chrome's debugging tools will re-evaluate the object when you click to expand, so the expanded version shows what the object looks like at the time of the click, not at the time of the console.log. Apparently, the value changed in between when the console.log happened and when the click happened.

You are probably changing this object in your code, the first log is done instantly, right when you call console.log, but your object was mutated before you had the time to expand it.
To make sure the object logged is not mutated you can copy it before the log:
// not sure of your actual log code but:
console.log('==>', index, {...object})
// instead of just
console.log('==>', index, object)

Check this example:
const obj = { cnt: 0 };
console.log(obj);
(function loop() {
obj.cnt++;
setTimeout(loop, 50);
})();
It may be useful to understand what just happend:
It is worth to remember that JavaScript is asynchronous.

Related

array.pop() function weird behavior

Since documentation states that The pop method removes the last element from an array and returns that value to the caller. from here
But this statement below
arr=[1,2,3,4,5];
console.log(arr.pop()); //undefined
prints undefined
Do i always need to store the popped values and use it?? or there is any workaround.
Update
I am just getting "undefined" even in chrome console and in code if i am comparing arr.pop()== its returning true, i have attached the image below.
So, this is happening.
arr.pop() is popping 5 and 5 is getting printed. And then
undefined is returned by console.log().
Hope this answers your question.
UPDATE:
Make sure you check Info in the developers console
(function() {
arr=[1,2,3,4,5];
console.log(arr.pop());
console.log(arr.pop());
console.log(arr.pop());
})()
It works fine here. Can you please update your code with whatever you have tried?.
working fine.
arr = [1,2,3,4,5];
console.log(arr.pop());

Adding or deleting item from a Set and the effects of hoisting

I am learning to use Sets in JavaScript and noticed some odd behavior when going through the documentation.
let beverageSet = new Set();
beverageSet.add('Rum');
beverageSet.add('Tea');
beverageSet.add('OJ');
console.log(beverageSet); // returns Set [‘Rum’, ‘OJ’]
beverageSet.delete('Tea');
console.log(beverageSet); // returns Set [‘Rum’, ‘OJ’]
I know that hoisting pulls all variables to the top of the scope before executing code, but I have not seen anything showing that it would affect console.log()/methods called on arrays and Sets.
Is this an effect of hoisting or something else? How can I get around this and console.log() the full Set before deleting an item and then console.log() again?
The console.log implementation sometimes decides to get the value asynchronously, thereby showing results that might have mutations applied to them, that really occurred after the console.log statement.
To avoid this, take a copy in one or the other way, for instance like this:
console.log([...beverageSet]); // convert set to new array.
See also Bergi's answer to a question concerning the asynchronicity of console.log.
There is also a chromium issue on this: 50316 - Console.log gives incorrect output in Chrome Developer Tools console. It might be an interesting read.

JavaScript: Can't access array in object

I'm experiencing extremely strange behavior when accessing a property of an object.
Running this code:
console.log(myObj);
console.log(myObj.items);
console.log(myObj);
I get this output in the console:
How could this possibly happen?
console.log, during execution, outputs a string representation of the value in the console. Depending on Chrome's mood, it might show something [object Object] or something like Object {}. That doesn't matter.
Now note the little blue i beside it. What it means is that the object has been modified between the time it was logged and the time you expanded it in the console, and it now shows the current value (with the 2 items), not the value during console.log's execution (no items). You can actually hover on the blue i to get the explanation.
To replicate the issue, open the console and run this snippet:
var obj = {arr: []};
console.log(obj);
console.log(obj.arr);
console.log(obj);
// by this time, you see 2 object logs, 1 empty array
// (representation differs from time to time)
// > Object
// []
// > Object
obj.arr.push(1,2);
// when you try to expand the objects, an array of 2 items magically appear
// but you still see the empty array ([]) in the log.
This behavior differs across browsers. As far as I remember, Firebug outputs a serialized version when console.log executes, hence this doesn't happen there.
Debugging the code
To debug this kind of code, you have several options:
The quickest way is to log the stringified version of the object using JSON.stringify, like console.log(JSON.stringify(obj));
The best way is to add a breakpoint via the Sources tab. Browse to your file in the Sources tab of the Dev Tools, and add a breakpoint in that position. Run your code, and it will pause at that point. Use the Scope panel to inspect the variables.
If you can't reach the code using a breakpoint (probably run using eval or injected in the console), you can use the debugger; statement. Just put it in the code at that position. Run the code and it will pause when it reaches the statement. Use the Scope panel in Sources tab to inspect.
You could look at the JSON representation of the object to check, you can do that with:
console.log(JSON.stringify(myObj, null, 2));
With so little information, I can only assume you're dynamically populating the items property, making it empty when the 2nd console log runs.
Now you're wondering why it is there in the 1st console log: the console doesn't show the object properties that were there at the time the object was logged, but rather at the time the object entry was expanded in the console, so it could be that the items were populated after your 2nd console log and before you expanded the 1st one. Try logging the object as a string or a JSON to see its actual state at the time the console log was run.
Bottom line: object properties in the dev console get updated only when you expand the object entry (when you click the arrow) so you're not seeing the actual representation of the object from the time it was logged.
Here's a simple demonstration - see how it can even turn from an array into a string:
var obj = {p: []}
console.log(obj);
setTimeout(function(){
obj.p = "I'm not even an array!";
}, 1000);

Is it possible to flush the console (make it print immediately)?

I use Firefox + Firebug for some Javascripting. The text I'm trying to log with console.log does not immediately appear in Firebug's console. It seems like it piles up in a buffer somewhere, and then gets flushed to console in chunks. I have a function that makes a few log calls. Sometimes I get just the first line, sometimes - nothing. I do, however, see the whole bunch of lines when I refresh the page.
Can I flush the console log manually?
The short answer is no. There is no flush. You could clear the console
console.clear();
But I don't think that's what you want. This is most likely from the code. If we can see it, I can revise my answer with better feedback.
If you want to see all the available methods under console, execute this in the command line:
for(var i in console) {
console.log(i);
}
or have a look at the wiki page of the console API.
It's not a Firefox problem, It's a JavaScript problem because execution is delayed and variables are updated so you can see only the last value.
To see immediately the output you need to convert your object in string so it will not change also if object will be updated.
I wrote this easy function :
function printLog(s) {
if (typeof(s) === 'object') {
console.log( JSON.stringify(s) );
} else {
console.log(s);
}
}
The printed output is a string (so you can't interact with it) but it contains the real dynamic object that you want to see at the print time instant.

console.log() showing contradictory values for the same object property

I think i might be going mad.
I use console.log() to see the state of an object and then on the next line do a console.log() on a particular property of the same object and get different values for each.
The code i'm using is:
console.log(this.pictures.Items[pic].val);
for(var i in this.pictures.Items[pic].val) {
console.log("property: %s, value: %s", i, this.pictures.Items[pic].val[i] );
}
and firebug outputs:
Picture { isLoaded=true, isSelected=false, img_src="imgs/image1.jpg", more...}
property: isLoaded, value: false
...more properties
as you can see, 'isLoaded' is true when logging the object itself but false when logging the property.
I have tried logging the object again after just in case, and it is true again.
Does anyone know what is happening here?
Thanks
Rich
I'm not entirely sure if this is what is happening to you or not, but console.log() seems to have some issues in some browsers where doing a console.log() on a value or using an index variable that is changing or being iterated in an array does not always work properly.
My guess is that it has something to do with things getting marshalled between process boundaries and perhaps a delay in the actual evaluation of the logging expression until a time in which the actual object or index being used or referenced has changed. I've seen this issue in Chrome for sure - don't know about Firefox.
You should be able to work around this particular issue by using string math to build your final string. If only the final string is passed to console.log() where everything is fully evaluated, then this issue would not impact the output.

Categories