psuhing an object inside another object - javascript

I want to create an object of objects which should be something like this.
let data={
{ _id:10010,
value:"tom"
},
{
_id:2002,
value:22882
}
}
One solution that i could think of was this .
let data = {};
data.content = ({
_id: 1001,
value: "tom"
});
data.content = ({
id: 10001,
status: "harry"
});
console.log(data);
However if we do this we can only have one content inside our main object .Can we accomplish the desired data format while creating an object of objects ?

You can use array.
let data=[
{ _id:10010,
value:"tom"
},
{ _id:2002,
value:22882
}
]
data.push({
_id:1001,
value:"tom"
});
data.push({
_id:1001,
value:"tom"
});
Push method will add object to the array. If you need something else you can create more complex function/class that handles the requirements, but this maybe would be enough.

I assume you need to do with array
let data=[];
data.push({
_id:1001,
value:"tom"
});
data.push({
id:10001,
status:"harry"
});
console.log(data);

You cannot create an "object of objects". Objects store data in key:value pairs. You might consider creating an array of objects, after which you can reference the array items using indexes:
let data = [];
data.push({
_id: 10010,
value: "tom"
});
data.push({
_id: 2002,
value: 22882
});
console.log(data);

You can make use of arrays in order to achieve the result.
let data = [];
data[0]= {
_id:10010,
value:"tom"
}
data[1]= {
_id:2002,
value:22882
}
and so on...

I believe what you really mean is
let data={
10010: { _id:10010,
value:"tom"
},
2002: {
_id:2002,
value:22882
}
}
Property of objects has to be key value pair, meaning in order to have a object nested in an object, as a value, u need to pair it with a key. Hence using the id of object as the key to store it.
data['10010'] = { _id: 10010, value: 'tom' };
data['2002'] = { _id: 2002, value: 22882 };

Related

How to convert JSON Object into key value pair in JS? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
{"1":"val1","2":"val2","3":"val3"}
i want it to converted like this:
{"Id":"1","value":"val1","Id":"2","value":"val2","Id":"3","value":"val3"}
little Help Please would be much appricated
You can't use the same key name in one object.
instead you can do this.
const origin = {"1":"val1","2":"val2","3":"val3"}
const converted = Object.entries(origin).map( ([key,value]) => ({id: key, value }) );
console.log(converted);
What you have posted is invalid.
What you might want is:
const object = {"1":"val1","2":"val2","3":"val3"};
console.log(Object.entries(object));
// or
console.log(Object.keys(object).map(i => ({Id: i, value: object[i]})));
You could use a loop over Object.entries.
E.g. something like:
const newObjArr = [];
for(let [key, value] of Object.entries(obj)){
newObj.push({Id: key, value});
}
The above would return an array of objects, but I'm sure you can amend it to your particular use case.
const data = {"1":"val1","2":"val2","3":"val3"};
const result = Object.keys(data).map((key) => ({ id: key, value: data[key] }));
The result will be [{ id: "1", value: "val1" }, { id: "2", value: "val2" }, { id: "3", value: "val3" }]
As pointed out this is invalis. If you want to convert it if would look like this:
[{"Id":"1","value":"val1"},{"Id":"2","value":"val2"},{"Id":"3","value":"val3"}]
You can make an function that converts this.
const object = {"1":"val1","2":"val2","3":"val3"};
console.log(Convert(object));
function Convert(obj){
return Object.keys(obj).map(i => ({Id: i, value: obj[i]}));
}
You cannot do this. Object is a unique key value pair.
{"Id":"1","value":"val1","Id":"2","value":"val2","Id":"3","value":"val3"}
Suppose you want to merge two object and What if both the object has same key, it simply merge the last objects value and have only one key value.
You can convert your large object to several small objects and store them in an array as this snippet shows. (It could be much shorter, but this verbose demo should be easier to understand.)
// Defines a single object with several properties
const originalObject = { "1" : "val1", "2" : "val2", "3" : "val3" }
// Defines an empty array where we can add small objects
const destinationArray = [];
// Object.entries gives us an array of "entries", which are length-2 arrays
const entries = Object.entries(originalObject);
// `for...of` loops through an array
for(let currentEntry of entries){
// Each "entry" is an array with two elements
const theKey = currentEntry[0]; // First element is the key
const theValue = currentEntry[1]; // Second element is the value
// Uses the two elements as values in a new object
const smallObject = { id: theKey, value: theValue };
// Adds the new object to our array
destinationArray.push(smallObject);
} // End of for loop (reiterates if there are more entries)
// Prints completed array of small objects to the browser console
console.log(destinationArray);
const obj = {"1":"val1","2":"val2","3":"val3"}
const newObject = Object.keys(obj).map(e => {
return {ID: e , value : obj[e] }
});
console.log(newObject); // [ { ID: '1', value: 'val1' },
{ ID: '2', value: 'val2' },
{ ID: '3', value: 'val3' } ]
it will give u an array of object, later u need to convert it to object and flat the object:
How do I convert array of Objects into one Object in JavaScript?
how to convert this nested object into a flat object?

update nested Object data without changing Object Id

I am currently using array filters to update the nested object.
My structure is -
Category Collection -
{
name:Disease,
_id:ObjectId,
subCategory:[{
name:Hair Problems,
_id:ObjectId,
subSubCategory:[{
name: Hair Fall,
_id:ObjectId
},{
name: Dandruff,
_id:ObjectId
}]
}]
}
I want to update the subsubcategory with id 1.1.1 which I am doing by using array filters.
let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { $set: { 'subCategories.$.subSubCategories.$[j]': data } };
let option = { arrayFilters: [{ 'j._id': subSubId }], new: true };
await Categories.findOneAndUpdate(query, update, option
This code is working fine but array filters change the object id of subsubCategory. Is there any other alternative to do so without changing the ObjectId.
Thanks in advance
You can loop over the keys which you are getting as payload and put inside the $set operator.
const data = {
firstKey: "key",
secondKey: "key2",
thirdKey: "key3"
}
const object = {}
for (var key in data) {
object[`subCategories.$.subSubCategories.$[j].${key}`] = data[key]
}
let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { '$set': object };
let option = { 'arrayFilters': [{ 'j._id': subSubId }], 'new': true };
await Categories.findOneAndUpdate(query, update, option)
Problem is in $set line there you have not mentioned specific fields to be update instead subCategory.$.subSubCategory.$[j] will replace complete object element that matches the _id filter. Hence your _id field is also getting updated. You have to explicitly mention the field name after array element identifier. See example below:
Suppose you want to update name field in subSubCategories from Dandruff to new Dandruff. Then do this way:
let update = { $set: { 'subCategories.$.subSubCategories.$[j].name': "new Dandruff" } };
This will only update name field in subSubCategories array

Update values on multi level nested Object with javascript

I have an Object on sessionStorage for which I need to update values on user input. I am able to update at the root of the Object but not the values that are nested on a deeper level.
request('http://localhost:7474/graphql/', query).then(data => {...}
sessionStorage.setItem('queryData', JSON.stringify(data));
function update(value){
let prevData = JSON.parse(sessionStorage.getItem('queryData'));
Object.keys(value).forEach(function(val, key){
prevData[val] = value[val];
});
sessionStorage.setItem('queryData', JSON.stringify(prevData));
}
update({ maritalStatus: "single" });
So maritalStatus ends up been added and not replaced and I must replace the value:
Object: [,...]
0: {id: "x", maritalStatus: "married"} //want to replace this value here
maritalStatus: "single" // this is where the value is been written
Your data in storage is an Array. So the way you are updating it like prevData[val] = value[val]; is adding another property to the array with index of maritalStatus and value of "single". The object at index 0 is untouched.
My suggested fix is to also include the id in your update call. Then loop through the array in storage and look for the object with the matching id.
Once the id matches update that object, or log if no id matches are found.
let dataInStorage = [{
id: "x",
maritalStatus: "married"
}];
function update(updateObj) {
let prevData = dataInStorage;
let id = updateObj.id;
dataInStorage.forEach(function(data) {
if (data.id === id) {
Object.keys(updateObj).forEach(function(key, index) {
data[key] = updateObj[key];
});
} else {
console.log(`did not find object with id: ${id}`);
}
});
console.log(prevData)
//sessionStorage.setItem('queryData', JSON.stringify(prevData));
}
update({
id: "x",
maritalStatus: "single"
});

How to return new array with dynamically populated properties?

So my call returns something like:
data:
{
nameData: 'Test33333',
emailData: email#email.com,
urlLink: link.com
additionalDetails: [
{
field: 'email',
value: 'other#email.com'
},
{
field: 'name',
value: 'name1223'
}
]
}
Now, I want to make a function that would take the passed parameter (data) and make an array of objects, that should look like below. It should be done in more generic way.
Array output expectation:
fullData = [
{
name: 'data_name'
value: 'Test33333'
},
{
name: 'data_email',
value: 'email#email.com'
},
{
name: 'data_url',
value: 'Link.com'
},
extraData: [
//we never know which one will it return
]
];
It should be done in the function, with name, for example:
generateDataFromObj(data)
so
generateDataArrFromObj = (data) => {
//logic here that will map correctly the data
}
How can this be achieved? I am not really proficient with JavaScript, thanks.
Assuming that you keep your data property keys in camelCase this will work for any data you add, not just the data in the example. Here I've used planetLink. It reduces over the object keys using an initial empty array), extracts the new key name from the existing property key, and concatenates each new object to the returned array.
const data = { nameData: 'Test33333', emailData: 'email#email.com', planetLink: 'Mars' };
function generateDataArrFromObj(data) {
const regex = /([a-z]+)[A-Z]/;
// `reduce` over the object keys
return Object.keys(data).reduce((acc, c) => {
// match against the lowercase part of the key value
// and create the new key name `data_x`
const key = `data_${c.match(regex)[1]}`;
return acc.concat({ name: key, value: data[c] });
}, []);
}
console.log(generateDataArrFromObj(data));
Just run a map over the object keys, this will return an array populated by each item, then in the func map runs over each item, build an object like so:
Object.keys(myObj).map(key => {return {name: key, value: myObj[key]}})

What is the best way to convert an array of strings into an array of objects?

Let's say I have an array of emails:
['a#gmail.com', 'b#gmail.com', 'c#gmail.com']
I need to convert it into an array of objects that looks like this:
[
{
id: 'a#gmail.com',
invite_type: 'EMAIL'
},
{
id: 'b#gmail.com',
invite_type: 'EMAIL'
},
{
id: 'c#gmail.com',
invite_type: 'EMAIL'
}
]
In order to do that, I have written the following code:
$scope.invites = [];
$.each($scope.members, function (index, value) {
let inviteMember = {
'id': value,
invite_type: 'EMAIL'
}
$scope.invites.push(inviteMember);
});
Is there any better way of doing this?
Since you're already using jQuery, you can use jQuery.map() like this:
var originalArray = ['a#gmail.com', 'b#gmail.com', 'c#gmail.com']
var newArray = jQuery.map(originalArray, function(email) {
return {
id: email,
invite_type:'EMAIL'
};
});
jQuery.map() translates all items in a given array into a new array of items. The function I am passing to jQuery.map() is called for every element of the original array and returns a new element that is written to the final array.
There is also the native Array.prototype.map() which is not supported in IE8. If you're not targeting IE8 or if you use a polyfill, then you can use the native .map():
var newArray = originalArray.map(function(email) {
return {
id: email,
invite_type:'EMAIL'
};
});
This pattern
targetArray = []
sourceArray.forEach(function(item) {
let x = do something with item
targetArray.push(x)
})
can be expressed more concisely with map:
targetArray = sourceArray.map(function(item) {
let x = do something with item
return x
})
in your case:
$scope.invites = $scope.members.map(function(value) {
return {
id: value,
invite_type: 'EMAIL'
}
});

Categories