I have been having a recurring issue with Javacript associative arrays. Basically, I have a piece of code that looks like:
var l = assoc['2191'];
console.log(l); // >> outputs 'undefined'
console.log(assoc); // >> correctly outputs the associative array
When I print my associative array, it is printed correctly and I can see that '2191' is in fact a key in the array. Even when I go through the javascript console in Chrome, I can type "assoc['2191']" and it correctly returns the associated object. However, whenever I do this in my actual script, it always evaluates to "undefined".
Does anyone know why this has happening? I have checked the type of the key, and "string" is the right choice.
Related
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.
I'm running a splice on an array like this, where the array has 5 elements:
array.splice(3, 0, newObj);
The splice doesn't work and I still have 5 elements.
When I debug it in Chrome with console.log I see an array of six objects, but when I open the array I see five elements (see pic below). What does this mean?
You're inserting a new object into that array -> newObj
For example, if you run this in Chrome console, works fine :
function aHandler (){
var a = [{1:1},{1:2},{1:3},{1:4},{1:5}];
a.splice(3,0,{1:20});
console.log(a);
}; aHandler();
Even if you insert null or undefined console.log should show you the right object.
So, maybe you modify the object somewhere between splice and console.log
I'm sending an array to the service
[
{
"toppingid": "ABB934CB-EAB7-4863-B832-7F533DA08E2F",
"toppingname": "Default",
"toppingprice": "0.000000"
}
]
When I console.log it shows as above. I do console.log as below
toppinglistforCart = [];
toppinglistforCart = request.body.toppinglist
console.log(toppinglistforCart);
But when I try to toppinglistforCart.length it returns 132 for some peculier reason.
and if I do console.log(toppinglistforCart[0]) then it returns [ very strange. Did someone else came through this same issue?
Thanks for your time
Your toppinglistforCart variable appears to be a string, with length 132. (It doesn't work in older IE, but) JS lets you use the topplinglistforCart[0] syntax to access individual characters within the string, similar to how the same syntax on an array accesses individual array items.
You need to parse the JSON content of your string to create an object:
toppinglistforCart = JSON.parse(request.body.toppinglist);
Note also that your first line:
toppinglistforCart = [];
...is not needed at all - it sets toppinglistforCart to a new empty array but then the next line sets toppinglistforCart to something else so that empty array gets thrown away.
First try at using JSON. I have an ajax/php function that returns a JSON object. Back on the js side, I can see the object and output it to a div. It looks fine. I can print it to the console, still looks good. But when I try to iterate over it and expose the individual values, I just get 'undefined' in my console. I can't figure out what I am missing. Sorry it if's something obvious, but I don't see it. Thanks!
var jsonObj = JSON.parse(xmlhttp.responseText);
console.log(jsonObj); //<--looks perfect
console.log(jsonObj.length);
document.getElementById("rightsidebox").innerHTML=response; //<--looks good
for (var group in jsonObj) {
//each of these generates 'undefined' WHY???
//I get 4 'undefined' outputs for each group, so I know that my loop is iterating correctly
console.log(group.id);
console.log(group.day);
console.log(group.time);
console.log(group.name);
}
EDIT: Here is an example of one of the JSON objects being returned by my ajax call. In this example, I only have a single object inside of the array. Of course, there will typically be multiple objects:
[{"id":"7","day":"Thursday","time":"7:00 a.m.","name":"Sub 10:00"}]
EDIT 2: Given this array, I have to ask what the point of JSON is. I can return this array without having PHP encode it in JSON format. So, if all that comes back is just a javascript array, then what have I accomplished? Why not skip the JSON encoding in PHP and then iterate over the array? Clearly there is a reason for this, so I'm obviously missing something. Is there a better way to do what I am trying to accomplish? Thanks!
Consider the following:
var myJson = '{"groupA": {"id": 123, "name": "foo"}}';
var myObj = JSON.parse(myJson);
for (var i in myObj) {
console.log(i);
console.log(i.id);
console.log(myObj[i].id);
}
The expected output here is:
myGroup
undefined
123
This is because you loop is just assigning the 'key' of your object to the value i. If you were to iterate an array, instead of an object, you'd get indices instead of strings.
In the example JSON you've given, you have an array with one object in it. If you intend to have multiple objects in your array, something like this would be better:
for (var group in jsonObj) {
var thisGroup = jsonObj[group];
thisGroup.id; // Etc etc..
}
If you have the correct jsonObj, and you say that you do, you can use formatting to output the object in an easy to read form. You don't have to loop through it.
console.log(JSON.stringify(jsonObj, null, 1));
Not sure why this works, when my original for (var group in jsonObj) loop doesn't, but whatever...
for (var i=0; i < jsonObj.length; i++) {
console.log(jsonObj[i].id);
console.log(jsonObj[i].day);
console.log(jsonObj[i].time);
console.log(jsonObj[i].name);
}
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