I'm trying to leverage the technique shown here for replacing values in an object with ramda.js
. Unlike the linked reference, my object has many more nesting layers, and so it fails.
In the following example, we have an object that details attractions in cities. First it specifies the cities, the we dive in into nyc
, then to zoos
, then StatenIslandZoo
, and finally we get to zooInfo
that holds two records for two animals. In each one, we have the aniaml's name in the value associated with the animal
key. I want to correct the value's string by replacing it with another string and return a new copy of the entire cityAttractions
object.
const cityAttractions = {
"cities": {
"nyc": {
"towers": ["One World Trade Center", "Central Park Tower", "Empire State Building"],
"zoos": {
"CentralParkZoo": {},
"BronxZoo": {},
"StatenIslandZoo": {
"zooInfo": [
{
"animal": "zebra_typo", // <- replace with "zebra"
"weight": 100
},
{
"animal": "wrongstring_lion", // <- replace with "lion"
"weight": 1005
}
]
}
}
},
"sf": {},
"dc": {}
}
}
So I defined a function very similar to this one:
const R = require("ramda")
const myAlter = (myPath, whereValueEquals, replaceWith, obj) => R.map(
R.when(R.pathEq(myPath, whereValueEquals), R.assocPath(myPath, replaceWith)),
obj
)
And then called myAlter()
and stored the ouput into altered
:
const altered = myAlter(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo", "animal"], "zebra_typo", "zebra", cityAttractions)
But when checking, I realize no replacement had happend:
console.log(altered.cities.nyc.zoos.StatenIslandZoo.zooInfo)
// [
// { animal: 'zebra_typo', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
Some troubleshooting
If I we go back and examine the original cityAttractions
object, then we can first extract just the level of cityAttractions.cities.nyc.zoos.StatenIslandZoo.zooInfo
, then acting on that with myAlter()
does work.
const ZooinfoExtraction = R.path(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo"])(cityAttractions)
console.log(ZooinfoExtraction)
// [
// { animal: 'zebra_typo', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
console.log(myAlter(["animal"], "zebra_typo", "zebra", ZooinfoExtraction))
// here it works!
// [
// { animal: 'zebra', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
So for some reason, myAlter()
works on the extracted ZooinfoExtraction
but not on the original cityAttractions
. Which is a problem because I need the entire original structure (just replacing the specified values).
EDIT - troubleshooting 2
I guess the problem relies in the fact that
R.path(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo", "animal"], cityAttractions)
returns undefined
.