I'm having some issues with what would seem to me a fairly simple datastructure. I have an object called mylist with 1. an nested empty {} in it and 2. a function to add objects into (1). Please consider the following code:
var object1 = {name: "Object_1"}
var object2 = {name: "Object_2"}
var mylist = {
list: {},
add: function(item, val){
this.list[item] = val
}
}
mylist.add(object1,5)
mylist.add(object2,10)
console.log(mylist)
Now, I would expect the output to be
{ list: { object1: 5, object2: 10 }, add: [Function] }
But instead what I get is:
{ list: { '[object Object]': 10 }, add: [Function] }
For some reason, previous objects in the list are overwritten. Also there seems to be some sort of a conversion to string happening (because of the quotation marks), but I'm not sure why. Why am I not getting the output I expect? Does anyone has a good resource on this?
Thanks a lot in advance.
Maurits
this is because you are passing an object not a string, so whenever you do this:
mylist.add(object1,5);
instead of passing the object object1, you should pass a string:
mylist.add(object1.name,5);
this will return:
{ list: { "Object_1": 5 }, add: [Function] }
otherwise if you do not send a string whatever you pass will be converted into a string
The problem was when you add a property to a object like this.list[item] JavaScript implicitly converts the property into String using toString()(JavaScript properties have keys a strings).
Now when running toString() on object1 and object2 the result is [Object object]. So when first object is added to list it's key becomes [Object object]. When second object is added, it will also have same key [Object object], hence will overwrite the previous one.
So to make the your code working just add .name to item.
var object1 = {name: "Object_1"};
var object2 = {name: "Object_2"};
var mylist = {
list: {},
add: function(item, val){
this.list[item.name] = val;
}
}
mylist.add(object1,5);
mylist.add(object2,10);
console.log(mylist.list);
Related
If I create an object and use console.log it will expand the object and I can see the object properties. If I use alert it does not. Is there any way to do the same thing in an alert?
car=new Object();
car.wheels=4;
car.make="honda";
car.owner="me"
console.log(car);
output: Object { wheels: 4, make: "honda", owner: "me" }
alert(car)
output is [object Object]
How can I get the same output for the alert?
As others have stated you use JSON.stringify.
But I wanted to give a few other pointers. I don't know if you know these already, but your example indicated that you might appreciate the tips.
In JavaScript it is recommended to not use new Object() Instead just create your object:
var car = {
wheels: 4,
make: "honda",
owner: "me"
}
Always use var, let or const when creating variables. If you don't then they are created on the global scope. In the browser you would be creating the new variables on the window object.
JSON.stringify has other parameters:
JSON.stringify(value[, replacer[, space]])
The replacer is not often used, but it can provide a way of filtering and preventing recursive data.
The space parameter can be a number form 0 to 10 or a number of characters in a string from 0 to 10. This indicates how much to indent each level in the output.
function replacer(key, value) {
if (typeof value === 'string') {
return undefined;
}
return value;
}
var foo = {
company: 'Sony',
model: 'Playstation',
version: 4,
pricing: [
{
pro: false,
price: 299.00
},
{
pro: true,
price: 399.00
}
],
comments: 'none'
};
alert(JSON.stringify(foo, replacer, 2));
alert(JSON.stringify(foo, replacer, '----'));
In the console log method, the parameter is considered as an object. So, the object can be in any form like an array, string, integer, etc., and We will get the content. But in the alert method, it accepts only the string. So, if you send the object, it will convert it as string version of the object ( object Object ). If you stringify the object and send as a parameter to the alert method, it will display the content. Try this one,
window.alert(JSON.stringify(object));
You can use this alert(JSON.stringify(object))
I am currently unsure as to how to edit one of my objects in my javascript (React JS) program. I am implementing web sockets into my program, and so I am receiving an object that I need to use to edit another object in my program.
Here are the two summarized objects (with only updated properties included):
objectWeAreEditingWith = {
path: [
"playerStatuses",
"id1" //really is an id like "b02a507f-31..."
],
value: [
true,
"Random"
]
}
objectWeAreEditing = {
property1: ...
property2: ...
...
playerStatuses: {
id1: [
false,
"Generalist"
]
}
...
moreProperties: ...
}
Some details about the objects. The "objectWeAreEditingWith" will always only have a path and value property. The path property just contains the keys that are required access the correct key in "objectWeAreEditing". The value property just contains the variable values to change in the key that was detailed in the path property. "ObjectWeAreEditing" can contain any number of properties. Another thing to note is that the values in the array "value" is always in the same order (and size) as the property we are targeting in "objectWeAreEditing". "path", "value", and "id1" could techincally be any size (very long path / many variables), but id1 and value will always have the same length / have the values in the same order like I said before.
For this case, I am trying to do:
objectWeAreEditing[playerStatuses][id1][0] = objectWeAreEditingWith[value][0];
AND
objectWeAreEditing[playerStatuses][id1][1] = objectWeAreEditingWith[value][1];
The problem is that, of course, I don't know that I am editing:
objectWeAreEditing[playerStatuses][id1]
because this path is given by "objectWeAreEditingWith".
I also don't know that I am only editing:
objectWeAreEditing[playerStatuses][id1][0];
AND
objectWeAreEditing[playerStatuses][id1][1];
because the amount of variables I am editing is given in "objectWeAreEditingWith".
The solution for the second portion is to go into the "value" property and check its length and iterate through that many variables inside of (id1 in this case). I do not, however, have any clue how to iterate through a path of keys inside of an object.
If you want to set data in object2 depending on object1, one solution is:
let object1 = {
path: [
"playerStatuses",
"id1"
],
value: [
true,
"Random"
]
};
let object2 = {
property1: true,
property2: true,
playerStatuses: {
id1: [
false,
"Generalist"
]
}
};
console.log(object2);
(function setObjectFrom(object1, object2) {
var i = 0;
if (object1.path.length <= 0) {
throw "Cannot set empty path";
}
var currentToKey = object1.path[i];
(function walkerObject(object, value) {
for (let key in object) {
if (key == currentToKey) {
if (object1.path.length-i <= 1) {
object[key] = value;
}
else {
i++;
currentToKey = object1.path[i];
walkerObject(object[key], value); // call itself
}
}
}
})(object2, object1.value);
})(object1, object2);
console.log(object2);
Here:
A function (setObjectFrom) is defined to set an attribute of a object2 depending of object1.path and object1.value. It define another function named walkerObject. This function does the following: each time it find a value of path (let name it vPath) as a key of object1, it verify if it is the last key:
When it is the last key, it set value as value of object2[vPath]
If it is not the last key, the walkerObject call itself again looking for the next value of path, but with object2[vPath] as object2
This function is not bullet proof, that mean, it does not handle error such as object1.path is not found inside object2 and others case.
Corresponding jsBin
I'm wondering if, and if how the following thing is working:
I have an array defined like the following:
var array = [
{number: '1', value: 'one', context: 'someContext'},
{number: '2', value: 'two', context: 'anotherContext'},
...
]
What I'm currently doing is pushing the elements into the array, so array.push({number: '1', value: 'one', context: 'someContext'}); and so on, with every array element.
Now this thing is extended: Say there's another key called 'content'. This key has a appropriate value, that is either undefined or a string. Now the question is: If I put the pushing in a function like this:
push(number, value, context, content) {
array.push({
number: number,
value: value,
context: context,
content: content
})
}
Is there anyway, I can make sure, that the key content is only added to the element, if the content (the function gets as parameter) is not null.
Of course I can modify function like that:
push(number, value, context, content) {
if(!content) {
array.push({
number: number,
value: value,
context: context,
content: content
})
} else {
array.push({
number: number,
value: value,
context: context
})
}
}
But the question is, if there is anyway to do this in the push function. I also thought about something like
array.push({
number: number,
value: value,
context: context,
content? content: content
})
So it would only be inserted if content is defined, but does this work, it didn't seem like, but maybe theres a mistake in my code.
If the objective isn't just to make code shorter, the most readable would be something like this, where you create the object, add the property if there is a value, and then push the object to the array.
push(number, value, context, content) {
var o = {
number : number,
value : value,
context : context
}
if (content !== null) o.content = content;
array.push(o);
);
Here's an ES6 way to construct the object directly inside Array.push, and filter any that has null as a value.
function push(...arg) {
array.push(['number','value','context','content'].reduce((a,b,i)=> {
if (arg[i] !== null) a[b]=arg[i]; return a;
}, {}))
}
With Spread operator for object literals (ECMAScript 2018) it looks super easy:
const myPush = (number, value, context, content) =>
array.push({
...{ number, value, context },
...content && { content }
});
If you are open to using ES2015, this can be done with Object.assign:
array.push(
Object.assign(
{ number, value, context },
content ? { content } : null
)
);
It can be done by extending array:
//create Your own array object
myArray=function(){};
myArray.prototype=Object.create(Array.prototype);
//create method
myArray.prototype.pushDefined=function(obj){
var newObj={};//create clean object
for (var key in obj){
if (typeof obj[key]!='undefined' && obj[key]!=null){
//this element is defined and is not null
newObj[key]=obj[key];
}
}
this.push(newObj);//push clean object without undefind properties
};
//tests
var arr=new myArray();
arr.pushDefined({ name:"John",surname:null});
console.log(arr[0]);
Or add this method to Array prototype:
Array.prototype.pushDefined=function(obj)... //this will be method in every array
I would not recommend changing original push method in Array because
always think about other programmers who are using Array in this
particular project.
One of my alerts is giving the following result:
[object Object]
What does this mean exactly? (This was an alert of some jQuery object.)
It means you are alerting an instance of an object. When alerting the object, toString() is called on the object, and the default implementation returns [object Object].
var objA = {};
var objB = new Object;
var objC = {};
objC.toString = function () { return "objC" };
alert(objA); // [object Object]
alert(objB); // [object Object]
alert(objC); // objC
If you want to inspect the object, you should either console.log it, JSON.stringify() it, or enumerate over it's properties and inspect them individually using for in.
As #Matt already explained the reason for [object object], I would like to elaborate on how to inspect the object's value. There are three options that come to my mind:
JSON.stringify(JSONobject)
console.log(JSONobject)
or iterate over the object
Basic example.
var jsonObj={
property1 : "one",
property2 : "two",
property3 : "three",
property4 : "fourth",
};
var strBuilder = [];
for(key in jsonObj) {
if (jsonObj.hasOwnProperty(key)) {
strBuilder.push("Key is " + key + ", value is " + jsonObj[key] + "\n");
}
}
alert(strBuilder.join(""));
// or console.log(strBuilder.join(""))
https://jsfiddle.net/b1u6hfns/
The alert() function can't output an object in a read-friendly manner. Try using console.log(object) instead, and fire up your browser's console to debug.
That is because there are different types of objects in Javascript!
For example
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
...
Object objects!
stringify({}) -> [object Object]
the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
When you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
If you want to see value inside "[Object objects]" use:
console.log(JSON.stringify(result))
If you are popping it in the DOM then try wrapping it in
<pre>
<code>{JSON.stringify(REPLACE_WITH_OBJECT, null, 4)}</code>
</pre>
makes a little easier to visually parse.
Another option is to use JSON.stringify(obj)
For example:
exampleObj = {'a':1,'b':2,'c':3};
alert(JSON.stringify(exampleObj))
https://www.w3schools.com/js/js_json_stringify.asp
In my case I was getting [Object, Object] because I was doing
console.log("particular_object" + particular_object)
Instead of
console.log("particular_object")
console.log(particular_object)
I guess adding another string in the same console.log of an object prevents the object from loading..
But most cases you just have to do:
JSON.stringify(particular_object))
Alerts aren't the best for displaying objects. Try console.log? If you still see Object Object in the console, use JSON.parse like this > var obj = JSON.parse(yourObject); console.log(obj)
In my case I got [object Objects] when I did the following:
const person2 = {
name: "Jo",
age: 27,
address: {
city: "Some city",
state: "Some state"
}
}
const requestedPerson = person2
const {
name,
age,
address,
favFood = "Not defined"
} = requestedPerson
console.log(`Address: ${address}`);
And it was the same as using:
console.log("Address: " + address)
Solution: I got it to work by simply using a comma:
console.log("Address:", address)
One of my alerts is giving the following result:
[object Object]
What does this mean exactly? (This was an alert of some jQuery object.)
It means you are alerting an instance of an object. When alerting the object, toString() is called on the object, and the default implementation returns [object Object].
var objA = {};
var objB = new Object;
var objC = {};
objC.toString = function () { return "objC" };
alert(objA); // [object Object]
alert(objB); // [object Object]
alert(objC); // objC
If you want to inspect the object, you should either console.log it, JSON.stringify() it, or enumerate over it's properties and inspect them individually using for in.
As #Matt already explained the reason for [object object], I would like to elaborate on how to inspect the object's value. There are three options that come to my mind:
JSON.stringify(JSONobject)
console.log(JSONobject)
or iterate over the object
Basic example.
var jsonObj={
property1 : "one",
property2 : "two",
property3 : "three",
property4 : "fourth",
};
var strBuilder = [];
for(key in jsonObj) {
if (jsonObj.hasOwnProperty(key)) {
strBuilder.push("Key is " + key + ", value is " + jsonObj[key] + "\n");
}
}
alert(strBuilder.join(""));
// or console.log(strBuilder.join(""))
https://jsfiddle.net/b1u6hfns/
The alert() function can't output an object in a read-friendly manner. Try using console.log(object) instead, and fire up your browser's console to debug.
That is because there are different types of objects in Javascript!
For example
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
...
Object objects!
stringify({}) -> [object Object]
the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
When you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
If you want to see value inside "[Object objects]" use:
console.log(JSON.stringify(result))
If you are popping it in the DOM then try wrapping it in
<pre>
<code>{JSON.stringify(REPLACE_WITH_OBJECT, null, 4)}</code>
</pre>
makes a little easier to visually parse.
Another option is to use JSON.stringify(obj)
For example:
exampleObj = {'a':1,'b':2,'c':3};
alert(JSON.stringify(exampleObj))
https://www.w3schools.com/js/js_json_stringify.asp
In my case I was getting [Object, Object] because I was doing
console.log("particular_object" + particular_object)
Instead of
console.log("particular_object")
console.log(particular_object)
I guess adding another string in the same console.log of an object prevents the object from loading..
But most cases you just have to do:
JSON.stringify(particular_object))
Alerts aren't the best for displaying objects. Try console.log? If you still see Object Object in the console, use JSON.parse like this > var obj = JSON.parse(yourObject); console.log(obj)
In my case I got [object Objects] when I did the following:
const person2 = {
name: "Jo",
age: 27,
address: {
city: "Some city",
state: "Some state"
}
}
const requestedPerson = person2
const {
name,
age,
address,
favFood = "Not defined"
} = requestedPerson
console.log(`Address: ${address}`);
And it was the same as using:
console.log("Address: " + address)
Solution: I got it to work by simply using a comma:
console.log("Address:", address)