I'm trying to work with data that resembles this kind of object:
const sampleData = {
coyotes: '',
armadillos: false,
wombats: [''],
geckos: 0,
dogs: {
beagle: '',
bulldog: ''
},
wolves: [
{
type: '',
color: '',
range: '',
status: {
endangered: true,
protected: false
}
}
],
cats: {}
}
As you can see, it's got a mix of different JavaScript types: strings, Booleans, numbers, etc.
When something in the form changes, I need to compare the old object with the changed object and check for equality, among other things. To determine if something has changed, I use this recursive function:
export const getChangedValues = (initialValues, values) => {
return Object
.entries(values)
.reduce((acc, [key, value]) => {
const hasChanged = initialValues[key] !== value
if (hasChanged) {
acc[key] = value
}
return acc
}, {})
}
However, when I compare new objects with old using lodash isEqual, I get a false for the number values because our fields save numbers as strings (I have no control over that).
So, I use this to convert JUST the numbers in the object to strings, because I need to leave everything else alone (especially the Booleans):
export const convertValuesToStrings = (obj) => {
return _.cloneDeepWith(obj, value => {
return (_.isNumber(value)) ? _.toString(value) : undefined
})
}
This works perfectly in converting numbers to strings, but I'm getting a false positive for the nested objects. After running the string converter and then checking if there has been a change, it's also returning objects, even if their underlying data hasn't changed.
I'm still learning the more complex areas of JavaScript, like recursion. Can anyone spot what I'm missing here?
Bottom line is that I need to recursively compare two objects after converting any number values (and ONLY number values) to strings. :)