How to push array to object that doesn't exist in object? - javascript

I'm very new to JavaScript. I was trying pushing new values to an object. But when I tried to push an array that doesn't exist in myObj, I got Cannot read property 'push' of undefined error.
My code is below:
var myObj = {
first: "first value",
second: "second value",
}
myObj.third.push(123)
console.log(myObj)
But when I check if it doesn't exist and create an empty array, then push it, it works. =>
var myObj = {
first: "first value",
second: "second value",
}
myObj['third'] = myObj.third || []
myObj.third.push(123)
console.log(myObj)
I wonder if bottom code is best practice and if there is a better way to do it.

The push method is part of the Array prototype in your particular case you are trying to access a not defined property which in JavaScript is consider undefined so you are trying to do transalates into something like:
myObj.third.push => myObj.undefined.push
Because myObj does not have a third key you can try this in the console doing console.log(myObje.third );
So the engine returns an error saying that undefined does not have a property push that is only available in Array.
In this case you need to set assign a value to myObj.third before using it as an array, for that there are multiple ways to set the value as an array your answer above is one of those ways:
myObj['third'] = myObj.third || []
That line works however if for example myObj.third has a value will use that as a value as you are assigning the result of the operation myObj.third || [] which in this scenario anything that evaluates as truthy will be returned if for instance you have:
myObj.third = true;
And then you do:
myObj.third.push(123);
An error will be displayed Uncaught TypeError: myObj.third.push is not a function as currently myObj.third is not an array.
So you need to make sure you are operating over an Array when using push, or at least when you initialize the value of your property is set as an Array, you can find more details on Array construction on this page.
Alternatives you can do to check before pushing are:
if ( ! Array.isArray(myObj.third) ) {
myObj.third = [];
}
myObj.third.push(123)

Updated 2nd:
You could do a ternary operator
let myObj = {
first: 'first value',
second: 'second value'
};
myObj.third = myObj.third ? [...myObj.third, 123] : [123];
console.log(myObj);

Related

How to add a new key and value in null object?

I have a null object. And I want to add dynamic key and object into that.
Tried
this.myObj[`${dayValue}`] = {}; //1
this.withDayTimeSlot[dayValue] = [targetValue];
Error
TypeError: Cannot set property '5' of null at ...
My dynamic object will be look like this.
{
'5':[],
'6':[]
}
You cannot set properties in a null object. It needs to be initiated as an empty object {} first.
this.myObj = {};
this.myObj[`${dayValue}`] = []; // [] since your desired value in the object is an empty array [] and not an empty object {}

Meaning of squared brackets after return in JS - fn(){return{}[]}

I've saw this syntax and I'm not sure what it's basically doing.
My current assumption is, that it checks whether the argument is != null AND is in the return.
fn = function(value) {
return {
1: 'Test1',
2: 'Test2'
}[value];
}
fn() results in undefined
fn(1) results in Test1
fn(2) results in Test2
fn(3) results in undefined
I'm not sure about my assumption. Can someone maybe clarify me and tell me what's the name of this syntax construct (does it have a specific name) ?
Edit: I saw it out of this context with random numbers and there for didn't realized that it is basically just accessing it. Thanks!
It doesn't check anything.
You have an object literal.
{
1: 'Test1',
2: 'Test2'
}
From which you extract a value using square bracket notation
(result of evaluating previous expression)[value]
And then you return the result
return (result of evaluating previous expression)
You could rewrite this as:
fn = function(value) {
var data = {
1: 'Test1',
2: 'Test2'
};
var return_value = data[value];
return return_value;
}
This:
{
1: 'Test1',
2: 'Test2'
}
is an object literal, so its value is an object reference.
This:
[value]
is an object property reference expression. That combined with the object reference gets you an object property value, or undefined if the string value passed to the [ ] operator isn't found as a property name in the object.
The code prefixes that stuff with return, making the result of the property lookup be the returned value of the function.
Thus, the function returns the object property value corresponding to the string value of the argument passed in so long as the argument is a property in that object constant, or undefined otherwise.

Checking if a dynamic property exists in a javascript array

I have code that dynamically adds properties to an array.
data.tagAdded[tag.Name] = {
tag: tag,
count: 1,
};
Later in my code I need to check rather data.tagAdded has properties. If it doesn't have properties I need to do some other code. The problem is I can't figure out how to check for the existence properties.
The tagAdded = [] is always an array rather it contains properties or not, so I can't check if it is null. I can't say if property because I don't know the name of the property since it is dynamic. I can't check length because an array with properties is of length 0.
Any other way to check if properties exist?
Assuming you just want to see if you've assigned any key-value pairs to your associative array (just FYI, for what you're doing, an object might serve you better), you can do the following:
function isEmpty(o) {
return !Object.keys(o).length && !o.length;
}
var x = [];
isEmpty(x);
=> true
x['foo'] = 'bar';
isEmpty(x);
=> false
delete x.foo;
isEmpty(x);
=> true
x.push(1);
isEmpty(x);
=> false
You can try
for (var prop in tagAdded) {
if (tagAdded.hasOwnProperty(prop)) {
console.log("property exists");
}
}

How to access properties of object by dot operator in Javascript

var changeJsonKeyName, newObj, obj;
changeJsonKeyName = function(json, oldName, newName) {
json[newName] = json[oldName];
delete json[oldName];
// json.newName = json.oldName;
// delete json.oldName;
// if i use point in this ,i can not get my result that i want
return json;
};
obj = {
'aaa': '1111',
'bb': {
'cc': 333
}
};
newObj = {};
newObj = changeJsonKeyName(obj, 'aaa', 'nnn');
console.log(newObj);
If I use point here ,I can not get my result that's what I want ,what is the wrong,please help me,thank you very much.
I'm not sure if I understood you correctly, but :
json[newName]
access property named with the value of newName variable
json.newName
access a property named 'newName', which does not exist
First, as a comment points out, this is a Javascript question, not a JSON question.
But you seem to be asking why this works:
json[newName] = json[oldName];
delete json[oldName];
but this doesn't:
json.newName. = json.oldName.;
delete json.oldName;
does not.
And the answer is the second form is actually equivalent to
json["newName"] = json["oldName"];
delete json["oldName"];
In other words, you are dealing with attributes whose names are the constants "oldName" and "newName" rather than attributes whose names are passed as parameters to that method.

Loop through properties in JavaScript object with Lodash

Is it possible to loop through the properties in a JavaScript object? For instance, I have a JavaScript object defined as this:
myObject.options = {
property1: 'value 1',
property2: 'value 2'
};
Properties will get dynamically added to this object. Is there a way for me to just loop through and do a check if a property exists? If so, how?
Use _.forOwn().
_.forOwn(obj, function(value, key) { } );
https://lodash.com/docs#forOwn
Note that forOwn checks hasOwnProperty, as you usually need to do when looping over an object's properties. forIn does not do this check.
Yes you can and lodash is not needed... i.e.
for (var key in myObject.options) {
// check also if property is not inherited from prototype
if (myObject.options.hasOwnProperty(key)) {
var value = myObject.options[key];
}
}
Edit: the accepted answer (_.forOwn()) should be https://stackoverflow.com/a/21311045/528262
For your stated desire to "check if a property exists" you can directly use Lo-Dash's has.
var exists = _.has(myObject, propertyNameToCheck);
You can definitely do this with vanilla JS like stecb has shown, but I think each is the best answer to the core question concerning how to do it with lodash.
_.each( myObject.options, ( val, key ) => {
console.log( key, val );
} );
Like JohnnyHK mentioned, there is also the has method which would be helpful for the use case, but from what is originally stated set may be more useful. Let's say you wanted to add something to this object dynamically as you've mentioned:
let dynamicKey = 'someCrazyProperty';
let dynamicValue = 'someCrazyValue';
_.set( myObject.options, dynamicKey, dynamicValue );
That's how I'd do it, based on the original description.
Lets take below object as example
let obj = { property1: 'value 1', property2: 'value 2'};
First fetch all the key in the obj
let keys = Object.keys(obj) //it will return array of keys
and then loop through it
keys.forEach(key => //your way)
just putting all together
Object.keys(obj).forEach(key=>{/*code here*/})
In ES6, it is also possible to iterate over the values of an object using the for..of loop. This doesn't work right out of the box for JavaScript objects, however, as you must define an ##iterator property on the object. This works as follows:
The for..of loop asks the "object to be iterated over" (let's call it obj1 for an iterator object. The loop iterates over obj1 by successively calling the next() method on the provided iterator object and using the returned value as the value for each iteration of the loop.
The iterator object is obtained by invoking the function defined in the ##iterator property, or Symbol.iterator property, of obj1. This is the function you must define yourself, and it should return an iterator object
Here is an example:
const obj1 = {
a: 5,
b: "hello",
[Symbol.iterator]: function() {
const thisObj = this;
let index = 0;
return {
next() {
let keys = Object.keys(thisObj);
return {
value: thisObj[keys[index++]],
done: (index > keys.length)
};
}
};
}
};
Now we can use the for..of loop:
for (val of obj1) {
console.log(val);
} // 5 hello
It would be helpful to understand why you need to do this with lodash. If you just want to check if a key exists in an object, you don't need lodash.
myObject.options.hasOwnProperty('property');
If your looking to see if a value exists, you can use _.invert
_.invert(myObject.options)[value]
If you just want to loop through to map property values then use _.mapValues
If you are checking, if the property exists in the object as stated in the question asked, you can use lodash libray _.has method
_.has(object, path)
Let me give you an example, how to use it.
consider an object
const user = {
name : "prabhat",
age: 27,
height: "5.7"
}
if you want to check, if name property exist in the object,you can use _.has method as follows
_.has(user, 'name') //true
_.has(user, 'address') //false
you will get a boolean true/false in return.

Categories