I'm pushing various objects in an array.
$scope.itemsPending = [];
while(bonos.length > 0){
if($scope.itemsPending.length > 0){
console.log($scope.itemsPending);
}
bono = bonos.shift();
if(bono.is_highlighted == false){
aux.push(bono);
maximo++;
}else{
if(maximo + 2 < 4){
aux.push(bono);
maximo += 2;
}else{
$scope.itemsPending.push(bono);
}
}
}
But when I show it in the dev console I have one or two "objects" and if I open this items, I have three.
What is happening?
EDIT
My bono value is like that
Chrome's console (for better or for worse) "logs" a reference to the object and when you inspect its contents by clicking on the arrow, it shows the current value at that object. This means that modifying an array within a loop and logging it on each iteration might have unexpected results.
Here is a simplified example demonstrating the issue. You should see the array being logged 3 times as [Object], [Object, Object], [Object, Object, Object], but "expanding" each of these logs will access the current contents of the array and show you 3 elements in all cases.
To reliably log changes to an object, log a primitive value instead of an object or an array. For example, the length of the array, or a serialized version of the array.
Also, consider that in the alternative (in order to show the state of the object at the time it was logged), the browser would need to clone and retain every object that is logged. This would cause it to run out of memory very quickly.
Related
I have a JavaScript Object named "userinfo" (it stored some user's info). And I want to access value by key in it. For all the keys I can success get, except one key named "auths". And then I print it in console by console.log(userinfo), it shown as well. And while I traversal it Object, the key don't show again...
And then I click the option "Store as global variable" in Chrome debug console. And not when I try to access, it works well.
Here it's my code and debug's screenshot.
console.log(userinfo);
for (var key in userinfo){
console.log(key + " = " + userinfo[key]);
}
Because here some my really personal informations in it, I produced this picture.(Position I've printed "hide info").
I want to know why the code working not well, and how can I access the info stored in key "auths".
Thanks!
console.log is deceiving. It's printing a "live" object. If object is altered after it's been logged, the log will update (you'll see the new property when you expand the object in the log). Naturally, this doesn't apply to the temp strings you build there with concatenation. So yes, I'd bet 10 bucks that the object does not indeed have auths property at the time of printing. It is added later.
Observe this in action (look in browser's console)
var myobj = { foo: 1 }
console.log(myobj);
myobj.bar = 2;
I've written a very simple application that pulls all the tracks off of a spotify playlist. First, it gets the track JSON objects using an AJAX request and puts them in an array called tracks[].
Next, I iterate through this array, and in each iteration I pull out the strings for the name of the song and the artist for each track. I put these in a concentrated string. This string is then stored in a new array called complete. This is done for each track.
Essentially, complete is an array that looks something like
[
"Sympathy for The Devil, The Rolling Stones",
"Come Together, The Beatles",
...
]
At this point I have a strange issue. According to chrome's debugger, the array complete has all of the correct values inside of it. However, when I attempt to console.log any element of complete I end up with the value 'undefined'. Stranger yet, if I console.log the expression I use to get the two strings and stitch them it prints the correct value.
Why does this happen and how can I fix it so it can console.log the correct values
Here is the code that iterates through stored JSON objects, stores them in new array, and prints:
function print() {
for(var x = 0; x < 4; x++) {
for(var n = 0; n < 100; n++) {
try {
//this logs correct
console.log(tracks[x].items[n].track.name + " " + tracks[x].items[n].track.artists[0].name);
//these have correct value
var deb = (tracks[x].items[n].track.name + " " + tracks[x].items[n].track.artists[0].name);
complete[z] = deb;
z++;
console.log(deb); //throws no error, prints fine
console.log(complete[z]); //prints undefined
} catch(err) {
//no exception ever thrown
}
}
}
}
I don't do too much JS, sorry if I'm missing something obvious.
Right after assigning complete[z], you are incrementing z. When printing, you are not accessing complete[z] anymore, but complete[z+1] which is not yet defined. Try moving the incrementation after the console.log command.
Well, in your example above, you've incremented z (which I assume was defined earlier somewhere?) after setting the value on your array. So when setting the value on the array, you've set it to complete[5] (or whatever) but you're logging complete[6] which is most likely outside the range of your array.
I don't understand how to interpret this debug data. I do a console.log of my object, and on the summary-line that appears in the console I am shown windows: array[0] but if I expand the object, I am shown that windows is an array of 2 items.
Which is the correct one?
My code seem to run on the summary version, ie. windows array being empty.
Does anyone know what my problem is - why is the object presented in an inconsistent way?
The object is being mutated between when you print it and when you view it. When it's initially logged, it's empty but by the time you open it, 2 items have been added.
var obj = { arr: [] };
console.log(obj); // Will say { arr: Array[0] }
obj.arr.push(1); // Open it up in the console after this
Basically, the dev tools print a string that's representative of it's state at the time of the log but it stores a reference to the object in the console itself.
I have found that when using console.log on a nested object the result seems to print after subsequent operations have performed, but only when logging an object with a depth of at least two.
Consider the following example:
function addNumbers(data) {
data.container.firstNumber++
console.log(data); // 3
data.container.firstNumber++
}
var numberData = {
container : {
"firstNumber": 1
}
};
console.log(numberData); // 3
addNumbers(numberData);
I assumed that with this example I would see numberData printed with the values 1 and then 2. In actuality, the value is 3, 3. My first thought was perhaps there is some race condition here where the values changes before the log operation can complete, but if you add more specific references to the object, you will get the value that matches the console.log's position in the code like this:
function addNumbers(data) {
data.container.firstNumber++
console.log(data.container); // 2
data.container.firstNumber++
}
var numberData = {
container : {
"firstNumber": 1
}
};
console.log(numberData.container); // 1
addNumbers(numberData);
Why doesn't the variable evaluate to its value relative to the position of the console.log in the first example, but does in the second example?
relevant fiddle
Most browsers only fetch the properties of an object logged to the console when you expand the object -- and often note this in a tooltip next to the object reference.
They also tend to only expand the object the first time and cache from then on, so the console is not a reliable way to inspect objects.
To get around this, browsers offer a watch panel that will update more frequently and can be used with breakpoints or stepping to get the current state of an object repeatedly.
I have an array like:
errors = [ {...}, {...}, {...} ]
It's an instanceof array, yet it only returns 1 for .length?
Relevant code:
if(data.error){
errors.push({'element':ele,error:data.error});
}
//Above is looped a few times and there are N number of errors now inside
console.log(errors) //Returns 2+ objects like {...}, {...}
console.log(errors.length) //Returns 1
For Uzi and Muirbot, here's the errors array:
[
Object
element: b.fn.b.init[1]
error: "You must enter "example" into the field to pass"
__proto__: Object
,
Object
element: b.fn.b.init[1]
error: "Crap!"
__proto__: Object
It is correct, this code:
var errors = new Array();
errors.push({'element':'ele', error:'data.error'});
...adds ONE object to the array. The object has two properties.
It's possible your code is executing in an order other than what you're expecting. ie, when you log both errors and errors.length, errors does contain only 1 object. But after that you are adding to the errors array, and only after that are you looking at the console. At that point you could see a larger array in errors for two reasons - first, your actual code isn't logging errors but some object that contains errors. In that case the console display is live, and will show you not what was in errors at the time, but what is in it now. Alternatively, the console could just be taking some time to log errors.
Without more code I can't be sure if this is the case. But you could verify it by replacing console.log(errors); with console.log(errors[1]);. If errors is really only 1 long at the time, it will log undefined.
The problem was that Chrome's Web Inspector's console.log is an async event. So, the length was a property lookup so it gave that back instantly, but the object with two items inside was held off until the rest of the events had fired.
In the future I, and others with this issue, should use debugger; instead.
is it an Array object or something that resembles it?
arrays do work:
> a = [{a:1}, {b:2}]
[Object, Object]
> a.length
2
you'll have to provide more code.
and now that you've provided the relevant code, the correct answer is what Steve Wellens said (which was downvoted, by the way).
Array.push adds a single element, objects may have more than one key but they're still a single object so your real case was different from your original example, which of course works.
another possibility:
> a = []
[]
> a.length = 2
2
> a
[]
> a.length
2
> a instanceof Array
true