console.log/console.dir showing last state of object, not current - javascript

I want to log how my array/object is changing with new steps of loop. Console.log does this bad. It shows only last state of object everywhere. For example:
var a = {};
console.log(a); // {bob1: 0, bob2: 0}
a.bob1 = 0;
console.log(a); // {bob1: 0, bob2: 0}
a.bob2 = 0;
console.log(a); // {bob1: 0, bob2: 0}
I found there, on so, another command: console.dir. It is working properly in same example. It shows states of object correcly.
Look this example. This command works perfect: http://jsfiddle.net/RLzVV/
Now, look my code pls. All output is in console. http://jsfiddle.net/3BDs7/4/
This is aStar algorithm. Take a look on this part (neighbor 3 loop <--- neighbor 3 start ---> this code is situated here <--- neighbor 3 stop -->) in console. Lanes, which output this to console are 105-113:
new openset length: 2
openset after adding new vertex
**shows 1 element, but length is 2**
It shows length is 2, but shows only 1 element. But! Seems to me algo is working correctly (it is popping another element, which is hidden on this step after). Why this bug appears? Did I did something wrong? Seems to me, everywhere only last state of array shown, not current:( help me please.

That's a known issue -- sounds like you are running under Chrome.
The easiest work-around is to JSON encode the value as you log in.
console.log(JSON.stringify(a));

Related

Javascript isn't setting the Array

I am not getting any errors. When you look at the console.log()'s outputs, the first one gives me the array, and when I open up the 2nd one, it says the array is empty! It's almost as if it was never set. The array I'm checking for is .axes.
I can directly access it, but then I can't see it when I expand the object.
This is for the most important thing in my life and the universe is trying to stop me.
for(i=0; i<$.count; i+=1){
h = chain[i];
h.axes = [ chain[0] ];
if (i==3){
console.log('Direct_AXES',h.axes);
console.log('Direct_H',h);
}
chain[0].dna.push(h);
}
As far as I can help you. This works like a charm.
var chain = [{},{},{},{},{}];
for(i=0;i<chain.length;i+=1){
h = chain[i];
h.axes = [ chain[0] ];
if (i==3){
console.log('Direct_AXES',h.axes);
console.log('Direct_H',h);
}
// chain[0].dna.push(h);
}
I added an array with four empty objects (so the code would somehow run). And I commented the last line of the loop because obviously I would run into an error.
Everything is working fine. So the conclusion here is that there is an error in the part you didn't post, because everything is working as expected.
Both logs do print the array and the whole object h containing the axes array.

How is it possible to have an array with length 0 but has content?

I have the following test code:
console.log('AA',slider);
console.log('AB',slider.length);
it returns the following in chrome console.
AA Array[53]
AB 0
i added test code because slider[5] always came back with undefined even though the console shows there is a value there.
here is a simplified version of initialisation script. entire code is pretty long and Slider is an object. Code for object is working the test script is later on trying to manipulate specific slider positions based on ajax return data.
var slider=[];
for (var uid=1;uid<50;uid++) {
slider[uid]=new Slider(.........);
}
var slider={};
for (var uid=1;uid<50;uid++) {
slider[uid]=new Slider(.........);
}
returns
AA {
1:{m
a: ....,
b: ....,
c: ....,
g: ....,
h: ....
},
2: .....
gets all the way up to 49
Ok i figured out the problem and hopefully this helps others.
After going through the code here is a much better example of initialization
var slider=[];
setInterval(function(){
for (var uid=1;uid<50;uid++) {
slider[uid]=new Slider(.........);
}
},500);
console.log('AA',slider);
console.log('AB',slider.length);
the array is indeed empty at the time the console log commands are executed but apparently the first line records reference to the object and not current state. So when I look at the log which is always going to be more then half a second later it shows data being there.

For loop keeps breaking out after 1 instance - Apps Script

I have looked everywhere I can think of for anything that can provide an answer to this. First time posting a question here - I can usually find my answers. I have a for loop that is pulling information from a range of data that is formatted in one cell like this: 09/01/2016 - Status changed to active.
The loop is supposed to first see how many values are in that column then go one by one and split the data into a simple array, post it into two columns on a separate sheet, then move onto the next one. The problem is that it stops after the first entry.
var numEntries = dataSheet.getRange(1,i+1,1000).getValues();
var lastEntry = numEntries.filter(String).length;
if (lastEntry == 7) {
// no change data to date
sheet.getRange(18,3).setValue("No changes yet");
} else {
var changeData = dataSheet.getRange(8,i+1,lastEntry-7).getValues();
for (var y = 0; y < changeData.length; y++) {
var changeHistory = changeData[y][y].split(" - ");
sheet.getRange(nextRow+1,2).setValue(changeHistory[0]);
sheet.getRange(nextRow+1,3).setValue(changeHistory[1]);
nextRow++;
Logger.log(nextRow);
Logger.log(changeData.length);
Logger.log(y);
}
}
I know that it is executing properly because it is properly setting the "No changes yet" value when there are no entries. Variable nextRow starts at a value of 17, and the log properly shows changeData.length with the number of entries and y being equal to 0. But then it stops. It doesn't follow the loop that y is still less than changeData.length. Any help is very much appreciated!
[edit] - I also want to point out that it does properly split and populate the first value into the two cells I want it to, so the whole for statement does work, it just doesn't loop. [edit]
[16-09-29 15:37:48:514 CDT] 18.0 [16-09-29 15:37:48:515 CDT]
11.0 [16-09-29 15:37:48:515 CDT] 0.0
changeData is an n*1 Array.
You are increasing y and and you are also trying to get the y-th column from changeData.
After the first iteration this is undefined because there's only one column.
undefined does not have a split method throwing an exception and terminating the script. (You may not see this exception, these kinds of exceptions aren't always shown to the user for some reason)
Try
var changeHistory = changeData[y][0].split(" - ");
instead.

Javascript issue on getelementbytagname

I'm having some trouble with this code:
var lista_input = document.getElementsByTagName("input");
console.log(lista_input);
console.log(lista_input[0]);
The first log correctly show me:
[item: function]
0: input
1: input
length: 2
__proto__: NodeList
but the second log show me:
undefined
I don't understand the reason,it could show me the first element input in dom!
The problem occurs from the fact that the return value of document.getElementsByTagName is a live NodeList:
var l = document.getElementsByTagName('div');
console.log(l[0]); // undefined
var d = document.createElement('div');
document.body.appendChild(d);
console.log(l[0]); // div
Combine that with the fact that you call the code before the document is ready (so before there are items in the list) and the known bug in the Console code that can show objects in a state after the call to console.log is made and you have the exact behavior you are experiencing.
To reiterate:
var lista_input = document.getElementsByTagName("input");
// lista_input is a live NodeList with 0 elements
console.log(lista_input); // will print the lista_input object at a later point
console.log(lista_input[0]); // will print undefined at a later point
/* time passes, dom is loaded */
// lista_input now has the inputs you expect it to have
/* time passes */
// logs are now shown in Console
EDIT: To get a good log, you can stringify the object when logging it, turning it into a primitive value that gets logged correctly:
var lista_input = document.getElementsByTagName("input");
console.log(JSON.stringify(lista_input)); // {"length":0} - empty list
console.log(JSON.stringify(lista_input[0])); // undefined
PS:
Link to a blog post explaining the Console bug:
http://techblog.appnexus.com/2011/webkit-chrome-safari-console-log-bug/
Link to a question requesting a fix to the Console bug:
How can I change the default behavior of console.log? (*Error console in safari, no add-on*)

Bug in console.log? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Chrome's JavaScript console lazy about evaluating arrays?
I try the following code:
var myList = new Object();
var item = new Object();
item.text = "item-1";
myList[3] = item;
console.log(myList);
console.log(myList[3].text);
// Assign another object to the same entry
var item2 = new Object();
item2.text = "item-2";
myList[3] = item2;
console.log(myList);
console.log(myList[3].text);
The result is quite odd:
* Object
* 3: Object
text: "item-2"
item-1
* Object
* 3: Object
text: "item-2"
item-2
BUT - if i execute the second part after some time (using setTimeout), and unfold the first object, I get it right, i.e.:
* Object
* 3: Object
text: "item-1"
item-1
* Object
* 3: Object
text: "item-2"
item-2
I find it important to share it, since I think one can waste a lot of time trying to understand what's wrong in his code.
And if somebody has some reference to an open bug or something - please reply this ticket.
Thanks!
My view is that this is a horrendously irritating 'feature' that I really wish I could turn off, it makes debugging a nightmare, not knowing at which point in time something may have updated an object, whilst trying to establish exact object state at a give point in the code. The feature could be useful for 'watch points' etc, but not in something called a 'LOG' (the clue is in the name).
Consider this code fragment:
var person = {'name':'Tom'};
console.log( person); //output the entire object variable
person.name = 'Thomas';
//the output is an object, whose 'name' value is 'Thomas', even though the log statement was placed before the value was changed to 'Thomas'.
AND THEN:
var person = {'name':'Tom'};
console.log( person.name); //changed to output a string variable
person.name = 'Thomas';
//the output here, however, has not dynamically updated and correctly outputs 'Tom'
this is a known bug (50316) that gets reported again and again because people don't take a look at the bugtracker before reporting:
78325
94887
105559
107828
111020
131124
sadly, theres no information about if/when this will get solved. until that moment, you'll need to clone objects before passing them to console.log().
Sounds to me more like a race condition than anything else. Since you are only passing a reference to console.log(), the value it refers it has likely changed value by the time it is actually logged. Then when you use setTimeout(), the value changes after it has been logged. Instead of passing a reference to console.log(), pass a clone of the value.
This is a known problem/feature with the console log in some browsers.
When you log something, it may not immediately be turned into text format. If the log stores a reference to the object that you log, it will be turned into text format when it's actually shown in the log.
This has the advantage that logging something has a very small impact on performance, until you actually open the log window to show the log.
Even if you have the log window open while you run the code, there is no updates happening while your function is running (as Javascript is single threaded), so the console window will show the values as they are at the end of the function, when the window is updated.
I have done some experiments with this "problem" on the latest version of Chrome 20.0.1132.57 m.To summarize the key points :-
console.log() prints a reference to the object with as "> Object" when the code is executed
The state of the object when you click on the triangle is displayed, irrespective of the line of code where the console.log() is executed
If you want to print the object in its current state, print a clone console.log(JSON.parse(JSON.stringify(obj)));
You could use this bit of code to test this on your own browser:
window.onload = function() {chto = {a : 10, b : 20};
console.log('Open this object after 5 seconds')
console.log(chto);
console.log('Open this object before 5 seconds')
console.log(chto);
console.log('Console of the cloned object')
console.log(JSON.parse(JSON.stringify(chto)));
setTimeout(function(){ console.log('5 seconds up'); chto['b'] = 30; },5000 ) ; };

Categories

Resources