Name Indexes in Javascript - Array / Object? - javascript

I understand that when index names are used to push values in Javascript, they essentially work like objects. But what I don't understand is the following behaviour -
person = [];
person[0] = "Someone";
person["test"] = "SomeoneElse"
Inputting person on the console prints ["Someone"] and I could see no information about person.test.
person.test does print SomeoneElse. However, if I go console.log(person), I get ["Someone", test: "SomeoneElse"].
Curious to check if this makes sense, I tried to create a structure like this one -
var experiment = ["Someone1", test1: "SomeoneElse1"]
and what I get is
Uncaught SyntaxError: Unexpected token
What am I missing?
Thanks in advance!

Typing person on the console prints ["Someone"].
Array.prototype.toString formats this output, and it only considers the "array values" of itself without other properties.
However, if I go console.log(person), I get ["Someone", test: "SomeoneElse"].
console.log outputs other information about the object, including own properties.
Uncaught SyntaxError: Unexpected token
Because that is bogus syntax; the array literal syntax doesn't allow keys, because array values aren't supposed to have keys. Arrays are a numerically indexed list of values. Merely by the fact that under the hood those lists are implemented using objects (because everything in Javascript is an object of some kind or another) are you able to set "non numeric keys" on the array. That doesn't mean you're using the array correctly though.
Also see Are JavaScript Array elements nothing more than Array object properties?

This is because an array in JavaScript is also an object itself, and objects can have properties. So it is perfectly valid to have an array with elements, but also have properties set on the array object.
The second example doesn't work because the [...,...,...] syntax is specifically for instantiating an array and its elements.

typing person in console is like having an alert(person); or passing its value to a variable or element, so it is more like you want to get the first set of readable values. That is the reason why it is showing you the values inside, you can try adding person[1] = *something;*, then it will display someone, something
console.log(person) - it displays all the items inside an object. It is more like informing you of what is inside, like a text visualizer in your IDE
var experiment = ["Someone1", test1: "SomeoneElse1"] - it will absolutely throw an exception there is no such format like this on initializing values, at least it is expecting an array format like var experiment = ["Someone1", "SomeoneElse1"]

Related

Querying all maps from an array in a document

I'm trying to query all data from an array in Firestore, but the certain array is made of objects. This is what my DB looks like:
https://imgur.com/a/4n1A2mb
You guys have any idea how I should do it?
This is the code I'm trying to achieve my goal with:
sawroomDB.collection("reservationsSecure").doc(todaysDate.getFullYear().toString()).get().then(doc => {
tableAllReservationsBody.innerHTML = doc.data().allReservations;
console.log(doc.data().allReservations)
})
The output I'm getting printed is just "[object Object],[object Object]" and in the console I can see and browse the arrays
What I need is to see the whole information from the objects, just by calling the array.
Thanks!
doc.data().allReservations is going to be an array of objects, as you can see from the console output. From what we can see in the screenshot, those objects contain at least one property called booking. If you want reach into the first object and get the value of the booking property:
const allReservations = doc.data().allReservations
const r1 = allReservations[0]
console.log(r1)
const booking = r1.booking
Of course, you might want to iterate the allReservations array instead of blindly indexing into it. But the point here is that each object just has that properties that you see in the console. You'll be able to see better when you log each object individually as above, rather than trying to log the entire array, which might compress down the contents of each object from your view.

Json length is always undefined in node js

I am trying to iterate simple json array, but it always return the length of the array is undefined.
var chatmessage = {};
...................
...................
socket.on('listmessage', function(mesg){
chatmessage={"message":"Hello", "to":"sjdfjhsdf"};
});
socket.on('private', function(mesg){
console.log(chatmessage.length+' - '+chatmessage.message +' - '+ chatmessage.to);
});
when private event get trigger it returns
undefined - Hello - sjdfjhsdf
I think it consider length key word as a json array key like {"length":40}.
I have tried Object.keys(chatmessage).length but it returns the total number key value(2) but I have only one record.
What is the right way to iterate json in node js
I am trying to iterate simple json array
Two issues there:
That's not JSON. JSON is a textual notation for data exchange. If you're dealing with JavaScript source code, and not dealing with a string, you're not dealing with JSON. It's a JavaScript object initializer.
It doesn't define an array, it defines an object.
Objects don't have a length property. If you want your chatmessage to say how many properties it has, you'll have to add a third property explicitly (which then raises the question of whether the value should be 2 or 3 :-) ). Or alternately, you could make it an array of objects with "key" and "value" properties, but that would be awkward to work with.
If you need to, you can determine how many properties an object has in a couple of ways:
Object.keys(obj).length will tell you how many own, enumerable properties the object has (ignoring any with Symbol names, if you're using ES2015). The number will not include any inherited properties or any non-enumerable properties. The answer in your example would be 2.
Object.getOwnPropertyNames(obj).length) will tell you how many own properties the object, has regardless of whether they're enumerable (but again ignoring any with Symbol names). The number will not include any inherited properties or any non-enumerable properties. The answer in your example would again be 2 as your object has no non-enumerable properties.
I have tried Object.keys(chatmessage).length but it returns the total number key value(2) but I have only one record.
As I said above, Object.keys will tell you how many own enumerable properties the object has. If you're trying to find out how many objects there are, the answer is 1.
If your goal is to send an array of chat messages, then you want to create that like this:
var chatmessages = [
{"message":"Hello", "to":"sjdfjhsdf"}
];
That defines an array with one entry: A single object representing a chat message. Multiple ones would be separated with ,:
var chatmessages = [
{"message":"Hello", "to":"sjdfjhsdf"}, // First message
{"message":"Hello again", "to":"sjdfjhsdf"} // Second message
];
Note that if you're doing that, your verb should probably be listmessages (plural), not listmessage. (I mention this in case your native language handles plurals differently from English; there are a lot of different ways plurals are handled in the various human languages around the planet. :-) )

Why does push not work on this cookie array?

This works fine:
$cookies.animals = []
$cookies.animals.push({cat: 'meow'})
console.log($cookies.animals) -> [Object]
But identical code inside a factory function doesn't work:
addAnimal: function(id, name, price){
console.log($cookies.animals) //-> [object Object]
$cookies.animals.push({cat: 'meow'}) //-> TypeError: undefined is not a function
}
So why am I getting a TypeError?
If I do this
addAnimal: function(id, name, price){
$cookies.animals = []
console.log($cookies.animals) //-> []
$cookies.animals.push({cat: 'meow'}) //-> works
}
It works (though of course it resets the array) so some something weird is happening to $cookies.animals.
If we look at my console.log inside the factory function:
We get this:
[object Object]
Object with a capital O is my cat, but that weird object is doing something evil I think. Where does it even come from?
Really don't know what's going on to be quite honest. Help please. All I'm trying to do is append to an array...
Per the AngularJS $cookie documentation:
Only a simple Object is exposed and by adding or removing properties to/from this object, new cookies are created/deleted at the end of current $eval. The object's properties can only be strings.
Your initial code works because you can, at any time, set any type of property on any object. Angular does not hold onto your non-string values, though, so your animals property is no longer set in the latter use context. You'll have to serialize and deserialize (probably via JSON) when writing and reading (respectively).
So you'll need to do something like this to initialize the cookie:
var animals = [];
animals.push('Furry Cat');
$cookies.animals = JSON.stringify(animals);
Later when reading, you'd need to do this:
var animal_cookie_value = $cookies.animals,
animals = animal_cookie_value ? JSON.parse(animal_cookie_value) : [];
As for your added remark of:
Object with a capital O is my cat, but that weird object is doing something evil I think. Where does it even come from?
When you see
object Object
in JavaScript you are seeing the output of the default toString() method on JavaScript objects. In other words, you used an object in context of a string, so JS cast it to string (which results in the value you're questioning).
FWIW, I develop a JavaScript cookie library which allows you to pass in any data and it handles the serialization for you. It is currently hosted on Google code, but I am working on moving it to GitHub and hope to add an AngularJS module for it someday.

Syntax Error In Javascript Object Declaration

I have declared an object like this
var me = {'alex','moore','baby','you'};
without the property names. I just want the elements to be set of strings. But i get error in both chrome dev-tools and firebug. i have googled but can't find any good answer.
What am i doing wrong?
thanks.
EDIT
Thanks for your answers. The reason am asking is that i am reading a book "Javascript: The Definitive Guide". On page 115 of the PDF file, it states that Javascript Objects ::
"They can also be used
(by ignoring the value part of the string-to-value mapping)
to represent sets of strings."
So i was trying to test it but getting errors. It seems the book is wrong that they can be used to represent sets of strings.
If you want an ordered list of values, then use an array ([]), not a plain object ({}).
var me = ['alex','moore','baby','you'];
Objects must have named properties.
var me = {
foo: 'alex',
bar: 'moore',
baz: 'baby',
etc: 'you'
};
Seems like what you are looking for is an array
var me = ['alex','moore','baby','you'];
Objects on the other hand need to have properties defined.
Square brackets
var me = ['alex','moore','baby','you'];
You should be using array not object.
var me = ['alex','moore','baby','you'];

Creating multi-dimensional arrays in javascript, error in custom function

I was trying to define an array (including other arrays as values) in a single javascript statement, that I can loop through to validate a form on submission.
The function I wrote to (try to) create inline arrays follows:
function arr(){
var inc;
var tempa = new Array(Math.round(arguments.length/2));
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
This is called three times here to assign an array:
window.validArr = arr(
'f-county',arr('maxlen',10, 'minlen',1),
'f-postcode',arr('maxlen',8, 'minlen',6)
);
However in the javascript debugger the variable is empty, and the arr() function is not returning anything. Does anyone know why my expectations on what this code should do are incorrect?
(I have worked out how to create the array without this function, but I'm curious why this code doesn't work (I thought I understood javascript better than this).)
Well from what your code does, you're not really making arrays. In JavaScript, the thing that makes arrays special is the management of the numerically indexed properties. Otherwise they're just objects, so they can have other properties too, but if you're not using arrays as arrays you might as well just use objects:
function arr(){
var inc;
var tempa = {};
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
What you're seeing from the debugger is the result of it attempting to show you your array as a real array should be shown: that is, its numerically indexed properties. If you call your "arr()" function as is and then look at (from your example) the "f-county" property of the result, you'll see something there.
Also, if you do find yourself wanting a real array, there's absolutely no point in initializing them to a particular size. Just create a new array with []:
var tempa = [];
Your code works. Just inspect your variable, and you will see that the array has the custom keys on it. If not expanded, your debugger shows you just the (numerical) indixed values in short syntax - none for you.
But, you may need to understand the difference between Arrays and Objects. An Object is just key-value-pairs (you could call it a "map"), and its prototype. An Array is a special type of object. It has special prototype methods, a length functionality and a different approach: to store index-value-pairs (even though indexes are still keys). So, you shouldn't use an Array as an associative array.
Therefore, their literal syntax differs:
var array = ["indexed with key 0", "indexed with key 1", ...];
var object = {"custom":"keyed as 'custom'", "another":"string", ...};
// but you still can add keys to array objects:
array.custom = "keyed as 'custom'";

Categories