I would like to copy a object from an existing object.
But I only need the field I want below
Since whiteList approach is required, I couldn’t simply copy the whole object and then use a delete approach to remove unwanted fields
So, my approach right now is like below
const copiedData = {
productId: data.productId,
time: data.time,
lastModifiedDate: data.lastModifiedDate
plan: {
planDetails: optionallySelProperties({
data: data.plan.planDetails,
dependencies: planDetailsDependencies
}), //--XXXXXXXXXXXXXXXX problem comes in
analysis: optionallySelProperties({
data: data.analysis,
dependencies: ......})
products: .......,
}
}
if they properties I need is a object. I would wrap it by a function that support optionally to select properties.
const planDetailsDependencies = [
'planName',
'status',
'customproductAllocations',
]
const optionallySelProperties = ({ data, dependencies }: IOptionallySelProperties) => {
return Object.entries(pick(data, dependencies) || {}).reduce((ret, cur) => {
return {
...ret,
[cur[0]]: cur[1],
}
}, {})
}
PS: pick is lodash function
rn, if the data that is passed into optionallySelProperties contains nested objects and I also need to optionally select properties. I couldnt achieve this in my function.
Is there a way to achieve this?
Here is the data I wanted to copy
const data = {
"abcId": "b27e21f7",
"productId": "G0221837387", //----- field I want to take
"time": 1698303900879, //----- field I want to take
"member": { //----- field I want to take
"teamMembers": [{
"roles": [],
"type": "Team Member",
"name": "Me",
}
]
},
"plan": { //----- field I want to take
"id": 86, //----- field I want to take
"lastModifiedDate": "2023-10-25T01:37:58.648146", //----- field I want to take
"planDetails": { //----- field I want to take
"planName": "20230202",
"options": [{
"value": 1,
"text": "Pineapple"
}
],
"status": "DRAFT", //----- field I want to take
"customproductAllocations": [{ //----- field I want to take
"id": 24744,
"allocationDetail": { //----- field I want to take
"name": "Created on 17 August 2023",
"dollar": "USD", //----- field I want to take
"allocations": [{
"id": "1005",
"name": "chocolatePreferred", //----- field I want to take
}, {
"id": "1007",
"name": "chocolate Large Cap", //----- field I want to take
},
]
}
]
},
"products": { //----- field I want to take
"inital": 169000000, //----- field I want to take
"externalproducts": [{ //----- field I want to take
"id": 659,
"name": "Additional", //----- field I want to take
}
],
"productAllocation": { //----- field I want to take
"productAllocation": [{
"id": "1005",
"category": "Card", //----- field I want to take
}, {
"id": "1007",
"category": "Fruit", //----- field I want to take
},
]
}
},
"analysis": { //----- field I want to take
"analysisA": { //----- field I want to take
"id": 50443,
"key": "Liq", //----- field I want to take
},
"analysisB": { //----- field I want to take
"id": 50443,
"key": "dity", //----- field I want to take
}
},
},
}
3
Answers
You could define the shape of the desired result with another object.
And use that object to build the new one.
For example
The obvious solution to the OP’s problem is to implement a single function which recursively clones any provided data-structure, but not entirely since there are exceptions.
Note … Not the other way around … The OP’s request is better described by a ignore-list than a required-list.
Besides its first parameter, which is the to be cloned value/data, this function also accepts a
Set
instance which features the key-names of properties which are supposed to not to be cloned (hence a ignore list).A first rough solution, though it does not fully cover the OP’s use case of precisely targeting specific key-paths, would work with such a key-ignore list and does look like follows …
The above first approach can be refined, in order to fully cover the OP’s specific use case.
The
Set
instance now would featurekeypath
values instead of the not precise enough property names, whereas the recursive function would aggregate and pass to itself the current scope’skeypath
upon which the ignoring decision is going to be made.The
keypath
based approach also allows notations which …either can target any array-item within the path regardless of its exact array index
or do precisely target a specific member of the data-structure.
Here’s a simple picker inspired by ArkType syntax
It’s made to work with arrays, records and optional keys
https://tsplay.dev/wjpebm has typedefs for autocompletion