Update dynamic object - javascript

I have an object :
{
...,
values: {},
...
}
values is empty by default.
Now I want to add dynamic object to this object :
[myDynamicProperty]: {
title: '...',
introduction: '...'
}
That's ok, I know how to do this. But, on other action, I have to add key: value or key: object to [myDynamicProperty], when I try something, I loose the values of my [myDynamicProperty]
I've tried to clone my initial object, but it doesn't work.
For sure, someone on stackoverflow has the solution.

You could take a two step approach by assigning a default object to myDynamicProperty and then assign the values to it.
This keeps all properties of object.values[myDynamicProperty] and changes only the given keys.
var object = {
values: {},
}
object.values[myDynamicProperty] = object.values[myDynamicProperty] || {};
Object.assign(object.values[myDynamicProperty], { title: '...', introduction: '...' });

If you are trying to convey that you are starting with an object such as:
var user = {
meta: {
first_name: "John",
last_name: "Smith"
}
}
and wish to add middle_name to the meta object property, then you should do the following.
Object.assign(user['meta'], {middle_name: "Harry"});
Note that the first object will be overwritten with values from the later object(s). The later object properties will take precedence over previous objects properties. See Mozilla for further details. WARNING: This is an ES6 feature, use a polyfill for backwards compatibility if necessary.

Related

Javascript object remove nesting

I am have an object that looks like this in the console,
res.local.details > Object {role-details : {} }
so to access this I would need to do res.local.details['role-details']
Is is possible to make it so I can "explode" role-details into details so I can just do
res.locals.details
to access the attributes from role-details
Yes, objects in JS are mutable. If you want to reassign data from one part of your object to another, you can just do it like this:
const myObj = {
name: {
first: 'John',
last: 'Smith',
},
address: {
streetNo: '123',
streetName: 'Main St',
city: {
name: 'Exampletown'
}
}
}
myObj.address.city.name // resolves to Exampletown
myObj.address.city = myObj.address.city.name
myObj.address.city /// resolves to Exampletown
This can be done in several ways.
In this particular case, where details just has that one property, you can just do:
res.local.details = res.local.details['role-details'];
In a more generic situation, details might have other properties that you don't want to destroy with this operation. In that case you can use:
Object.assign(res.local.details, res.local.details['role-details']);
With this, res.local.details will keep all its properties (provided they don't have the same name as properties of role-details), including role-details (but which becomes kind of obsolete).
The same can be achieved with:
res.local.details = {...res.local.details, ...res.local.details['role-details']};

Adding Objects to another object

I'm trying to add object inside an object with id as a key in react provider. Following is the use case.
const [memberList, setMemberList] = useState({
homeTeam: [],
awayTeam: [],
homeTeamClone: {},
});
I can successfully add member to an array, however I'm more keen to add that in homeTeamClone object.
example of object = {"id":"3a21b0a-1223-46-5abe-67b653be5704","memberName":"Adam"}
I want final result as
homeTeamClone: {
"3a21b0a-1223-46-5abe-67b653be5704": {"id":"3a21b0a-1223-46-5abe-67b653be5704","memberName":"Adam"},
"3a21b0a-1223-46-5abe-67b653be5705": {"id":"3a21b0a-1223-46-5abe-67b653be5705","memberName":"Chris"},
"3a21b0a-1223-46-5abe-67b653be5706": {"id":"3a21b0a-1223-46-5abe-67b653be5706","memberName":"Martin"},
}
I tried Object.assign(homeTeamClone, member) but did not get the expected result.
Thanks in Advance.
If the question is how to set individual member than you can do this:
const member = { id: '3a21b0a-1223-46-5abe-67b653be5704', memberName: 'Adam' };
setMemberList({
...memberList,
homeTeamClone: {
...memberList.homeTeamClone,
[member.id]: member,
},
});
In this case spread all old values and add new one. (In case user with same ID is added again, object value will be from the new one)

Creating Dynamic Keys In Object

I am struggling to create dynamic nested keys in javascript. My problem is that I need to have a object like this
{
"grandGrandFather": 'A',
"firstGrandFather": {
name: "AA",
children: {
first: 'AAA',
children: {
first: "AAAA"
}
}
},
"secondGrandFather": {
name: "AB",
first: 'ABA',
children: {
first: "ABAA",
second: "ABAB"
}
}
},
"thirdGrandFather": {
name: "AC",
children: {
name: "ACA"
}
}
}
Here problem is that I need to fetch these data from somewhere and I need to create these values dynamically. The prop creation begins from the first level and goes upto fourth level. So my question is how can I create dynamic keys in JS. Also I know you can create dynamic keys in JS like this:
var obj = {
prop1: "a",
prop2: "b",
prop3:'c'
}
obj['prop4'] = 'd';
Also I have been successful in creating a props to a level but when I need to stack these I get confused any help would be appreciated.
Further details about above object
In the above object I created I am getting data from database and I need to add firstGrandFather, secondGrandFather, thirdGrandFather dynamically. Also I don't know what their children props I need to define would be in the object. Some may have spouse,age,work props inside some may not also I don't know how many of these I would get. And these goes on for one or two more level.
In php it would be easy to create these in associative array easily but I am having hard time doing it in JS.
dynamic keys are possible in ES6+ Docs here
Basically, the syntax is:
obj[variable] = value;
Variable must contain a primitive value.
As for stacking, I'm afraid you have to get used to working with deep keys access with either dot or bracket notation. You can also assign a property of your object to a variable and then access its props.
So if obj is the object from your example:
const firstGrandfathersChildren = obj.firstGrandFather.children
It will have the following assigned:
{
first: 'AAA',
children: {
first: "AAAA"
}
}

How to update the value of a single property within a state object in React.js?

So I have the following object structure:
const SamplePalette = {
id: 1,
name: "Sample Palette",
description: "this is a short description",
swatches: [
{
val: "#FF6245",
tints: ["#FFE0DB", "#FFA797"],
shades: ["#751408", "#C33F27"]
},
{
val: "#FFFDA4",
tints: ["#FFFFE1"],
shades: ["#CCCB83"]
},
{
val: "#BFE8A3",
tints: ["#E7FFD7"],
shades: ["#95B77E"]
}
]
}
Let's imagine that this object is managed by the state of my app like this:
this.state = {
currentPalette: SamplePalette,
}
My question is how would I go about updating the val property of a given swatch object in the swatches array? Or more generally - how do I only update pieces of this object?
I tried using the update helper as well as to figure out how Object.assign() works, however I've been unsuccessful and frankly can't really grasp the syntax by just looking at examples.
Also, since I'm going to be modifying this object quite a lot, should I look into maybe using Redux?
[EDIT]
I tried #maxim.sh suggestion but with no success:
this.setState(
{ currentPalette: {...this.state.currentPalette,
swatches[0].val: newValue}
})
Consider you have new new_swatches
I think the clearer way is to get array, update it and put back as:
let new_swatches = this.state.currentPalette.swatches;
new_swatches[0].val = newValue;
this.setState(
{ currentPalette:
{ ...this.state.currentPalette, swatches: new_swatches }
});
Also you have : Immutability Helpers or https://github.com/kolodny/immutability-helper
Available Commands
{$push: array} push() all the items in array on the target.
{$unshift: array} unshift() all the items in array on the target.
{$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
{$set: any} replace the target entirely.
{$merge: object} merge the keys of object with the target.
{$apply: function} passes in the current value to the function and updates it with the new returned value.

Array filteration and Extraction of data and append to new Array

I have an array with nested array
I want the data to append in a new array.
For the data extraction or filtration what method's i have to use, using library such as lodash
DATA
[
[
{
_id: 588d9b8a608f2a66c298849f,
email: 'sd#',
password: '$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC',
isJobSeeker: true,
__v: 0,
lastName: 'shrestha',
firstName: 'manish',
isSeeker: true
}
],
[
{
_id: 588dbb4f7a48ce0d26cb99fd,
jobId: [Object],
seekerId: 588d9b8a608f2a66c298849f,
employerId: 588d7d6c0ec4512feb819825,
__v: 0,
}
]
]
REQUIRED DATA
[
{
_id: 588d9b8a608f2a66c298849f,
email: 'sd#',
password: '$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC',
isJobSeeker: true,
__v: 0,
lastName: 'shrestha',
firstName: 'manish',
isSeeker: true
},
jobId: [{}, {}, {}] // ARRAY WITH OBJECTS
]
also i want to change the jobId key to other key of custom string as jobs
Following is my attempt:
console.log('Data filteration', data);
const filteredData = [];
filteredData.push(data[0][0]);
data[1].forEach((i) => {
filteredData[0].jobs = i.jobId
});
console.log('filteredData', filteredData);
First you should clean you data to have a better structure.
[
[
{ ... }
],
[
{ ... }
]
]
In this datastructure, its difficult to understand what does inner arrays signify. Instead you should use an object. That would define the purpose of array and make your code more readable.
var data=[[{_id:"588d9b8a608f2a66c298849f",email:"sd#",password:"$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC",isJobSeeker:!0,__v:0,lastName:"shrestha",firstName:"manish",isSeeker:!0}],[{_id:"588dbb4f7a48ce0d26cb99fd",jobId:["test","test1"],seekerId:"588d9b8a608f2a66c298849f",employerId:"588d7d6c0ec4512feb819825",__v:0}]];
var cleanedData = {
userData: data[0],
userJobMap: data[1],
}
var result = cleanedData.userData.reduce(function(p,c){
if(c.isJobSeeker){
var job = cleanedData.userJobMap.filter(x=> x.seekerId === c._id);
// To copy object and not reference
var t = Object.assign({}, c, { jobId: job[0].jobId });
p.push(t)
}
return p
}, [])
console.log(result)
References
Array.map is a tool that iterates over all elements and return different value say a single property of return double value of all numbers in array. Note, this will yield an array of same size.
Array.filter on the other hand is use to filter array based on condition. This will return a subset of original data but elements will be same. You cannot change element structure.
Array.reduce is a tool that address cases where you need to return selected elements with parsed value. You can achieve same by chaining .filter().map() but then its an overkill as it would result in O(2n).
Object.assign In JS objects are passed by reference. So if you assign an object to a variable, you are not copying entire object, but only reference. So it you change anything in this variable, it will also reflect in original object. To avoid this, you need to copy value. This is where Object.assign comes. Note, its not supported by old browsers. For them you can check following post - What is the most efficient way to deep clone an object in JavaScript?
Note: All array functions are part of functional programming paradigm and are used to make your code more readable and concise but they come at an expense of performance. Traditional for will always perform faster then them. So if you want to focus on performance, always try to use for (though difference is very small but can add up for multiple cases and become substantial)

Categories

Resources