Array containing objects has wrong length - javascript

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

Related

Realm object list functions are undefined, even though object is defined and list is populated

Trying to push a new int into an int realm list. I can get the Realm object, I can print it and when I print the object it shows the list with it's content, I can use Realm Studio to edit, add numbers to the list, etc.. But when I try to call any methods form the list it says it is undefined.
Have tried async, await, then, though it was a synchronization issue, but doesn't seem like it.
The code below is similar to mine, but edited to hide the original names, etc, and does not have all the properties from the original, but it does not change the behave for the specific list I am trying to edit. Everything else works fine.
I have an schema like
let mySchema={
name:'MySchema',
properties:{
my_schema_id: 'string',
numbers: 'int[]'
}
The function to create a new object is
Realm.open({schema: [mySchema]})
.then(realm => {
realm.write(() => {
realm.create('MySchema', {my_schema_id: `${my_schema_id}`, numbers: [parseInt(number, 10)]});
});
I try to add a number with:
Realm.open({schema: [mySchema]})
.then((realm) => {
let fetchedSchema = realm.objects('MySchema').filtered(`my_schema_id ="${my_schema_id}"`);
console.log(fetchedSchema);
realm.write(()=>{
fetchedSchema.numbers.push(parseInt(number, 10));
});
And it gives an error:
(node:73249) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
I expected to push the item to the list, or to be able to call the list functions. Instead, when I try to use the list it shows as undefined even though I can see it and it's content when I print the object...
Found a solution.
Querying let fetchedSchema = realm.objects('MySchema').filtered(my_schema_id ="${my_schema_id}"); actually returns an array of elements, so I just had to select the first with [0]at the end

Cannot reorder an array of objects in JS

I have an array of objects which are presented to the user as blocks. They can drag and drop to change the order that that blocks appear, which I then want to change the position of the objects in the array.
$scope.myArray = [{a:1,b:2,c:3}, {a:11,b:22,c:33}, {a:111,b:222,c:333}];
function orderChanged(event) {
console.log($scope.myArray);
//logs [{a:1,b:2,c:3}, {a:11,b:22,c:33}, {a:111,b:222,c:333}]
console.log("source:", event.source.index, "dest:", event.dest.index);
//logs source: 1 dest: 2
$scope.myArray.move(event.source.index, event.dest.index);
console.log($scope.myArray);
//logs [{a:1,b:2,c:3}, {a:11,b:22,c:33}, {a:111,b:222,c:333}]
};
//this is going to rearrange the array
Array.prototype.move = function (from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};
The orderChange event has the source index and destination index as integers that represent their order as present to the user, which also maps to their positions in the array before any moving has occurred.
I cannot get the array to rearrange, each time I log the array in the orderChange function both logs return the same order.
All of the other examples of array re-ordering are for arrays that do not contain objects, I'm wondering if this is what is messing up my code?
I'm testing your code and works ok. Where are you modifying the Array prototype? Just try to replace the call to move() with the code that actually does the reorder and test...
Anyway, you're using AngularJS. Why are you messing with the DOM? Add a property called Order to each of your objects and let Angular do the syncrhonisation... that what is meant for.
In short, take a look at this module, maybe it would do your life easier:
http://ngmodules.org/modules/ng-sortable
I think, your code works ok, but the log does not.
console.log might not represent the values at runtime, but at viewtime, especially with multidimensional objects and arrays.
Try a different log to see console.log($scope[0].a, $scope[1].a, $scope[2].a)
You might want to check in a different brwoser, as this seems to be a Chrome issue, see here:
Is Chrome's JavaScript console lazy about evaluating arrays?
Wrong value in console.log

Pushing various objects in Javascript but save not properly

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.

Javascript: splice strange behavior

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

Array length issue in azure mobile services

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.

Categories

Resources