recurly-js
recurly-js copied to clipboard
Converting response to simpler format
trafficstars
The response XML is converted to JSON which places child $ and _ to represent attributes and text nodes, I'm guessing. Also data types are represented by object with $.type and $._ as the value.
JSON supports types, so it's possible to convert to JSON types without having to represent it in serial text format.
I've put together a dirty solution:
const recurlyNormalize = data => {
return Object.entries(data).reduce((curr, [key, value]) => {
const type = typeof value
// handle arrays
if (value.$ && value.$.type === 'array') {
const list = Object.values(value).find(value => Array.isArray(value)) || Object.values(value).pop()
curr[key] = Array.isArray(list) ? list.map(item => recurlyNormalize(item)) : [recurlyNormalize(list)]
// convert types
} else if (value.$ && value.$.type && value._) {
if (value.$.type === 'boolean') curr[key] = !!value._
else if (value.$.type === 'integer') curr[key] = parseInt(value._, 10)
else curr[key] = value._
// special type nil has no value._
} else if (value.$ && value.$.nil === 'nil') {
curr[key] = null
// handle objects with $
} else if (key === '$') {
curr = Object.assign(curr, recurlyNormalize(value))
// recurse arrays
} else if (Array.isArray(value)) {
curr[key] = value.map(item => recurlyNormalize(item))
// recurse objects
} else if (!['string', 'boolean', 'number'].includes(type)) {
curr[key] = recurlyNormalize(value)
// basic types
} else {
curr[key] = (value)
}
return curr
}, {})
}
If there is interest in using this approach I can refine it, add tests and submit a PR?
That would be awesome for the next major version, even though it would require a decent amount of testing. I will try to add some typings to the current version, so that it will be easier for users to follow the changes.