Reputation: 6282
I'm sure it's possible to take an object and modify it and filter it to get another shape for easier consumption after an api request, but unfortunately I'm not able to create any elegant solutions that don't involve using path
and prop
for every key eg.
const { prop, path } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
const newObj = {
id: prop('id', baseObject),
name: prop('name', baseObject),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url'], baseObject),
}
console.log(newObj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
Can anyone show me if there is a way to do elegant pointfree object reshaping. It seems like there should be some mapper function that can take the base object as a seed, but I can't seem to pinpoint it.
I have tried evolve
but that doesn't add new points, I have tried lens
but I may have missed something from the documentation because I can only modify existing keys or filter down like with prop
.
Cheers,
edit. I was able to create a mapping function that will do the job, but is there a better way?
const { prop, path, toUpper, map, compose } = R
const baseObject = {
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
}
// createObjectFromSpec :: { k: f(a) } -> a -> { k: b }
const createObjectFromSpec = spec => baseObj => R.map(f => f(baseObj), spec);
const createObjectTypeOne = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
image: path(['info', 'items', 0, 'url']),
})
const createObjectTypeTwo = createObjectFromSpec({
id: prop('id'),
name: prop('name'),
// image is a new prop not found on the base object
itemName: path(['info', 'items', 0, 'name']),
})
console.log(
createObjectTypeOne(baseObject)
)
console.log(
createObjectTypeTwo(baseObject)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
Upvotes: 2
Views: 174
Reputation: 6516
The createObjectFromSpec
function you have in your example exists in Ramda as applySpec
.
const fn = R.applySpec({
id: R.prop('id'),
name: R.prop('name'),
image: R.path(['info', 'items', 0, 'url'])
})
const result = fn({
id: 1,
name: 'object-one',
info: {
items: [
{ name: 'item-one', url: '/images/item-one.jpg' },
]
},
})
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
Upvotes: 4