I have JSON returned from an API like so:
Contacts: [{ GivenName: "Matt", FamilyName: "Berry" }]
To keep this consistent
You can do this with this recursive function (with lodash and ES6):
import { camelCase } from 'lodash';
const camelizeKeys = (obj) => {
if (Array.isArray(obj)) {
return obj.map(v => camelizeKeys(v));
} else if (obj !== null && obj.constructor === Object) {
return Object.keys(obj).reduce(
(result, key) => ({
...result,
[camelCase(key)]: camelizeKeys(obj[key]),
}),
{},
);
}
return obj;
};
Test:
const obj = {
'FirstName': 'John',
'LastName': 'Smith',
'BirthDate': new Date(),
'ArrayTest': ['one', 'TWO', 3],
'ThisKey': {
'This-Sub-Key': 42
}
}
console.log(JSON.stringify(camelizeKeys(obj)))
Output:
{
"firstName": "John",
"lastName": "Smith",
"birthDate": "2018-05-31T09:03:57.844Z",
"arrayTest":[
"one",
"TWO",
3
],
"thisKey":{
"thisSubKey": 42
}
}
I needed a generic method that accepted an array or object. This is what I'm using (I borrowed KyorCode's firstToLower()
implementation):
function convertKeysToCamelCase(obj) {
if (!obj || typeof obj !== "object") return null;
if (obj instanceof Array) {
return $.map(obj, function(value) {
return convertKeysToCamelCase(value);
});
}
var newObj = {};
$.each(obj, function(key, value) {
key = key.charAt(0).toLowerCase() + key.slice(1);
if (typeof value == "object" && !(value instanceof Array)) {
value = convertKeysToCamelCase(value);
}
newObj[key] = value;
});
return newObj;
};
Example calls:
var contact = { GivenName: "Matt", FamilyName:"Berry" };
console.log(convertKeysToCamelCase(contact));
// logs: Object { givenName="Matt", familyName="Berry"}
console.log(convertKeysToCamelCase([contact]));
// logs: [Object { givenName="Matt", familyName="Berry"}]
console.log(convertKeysToCamelCase("string"));
// logs: null
console.log(contact);
// logs: Object { GivenName="Matt", FamilyName="Berry"}
To change a plain object's keys from snake_case
to camelCase
recursively try the following
(which uses Lodash):
function objectKeysToCamelCase(snake_case_object) {
var camelCaseObject = {};
_.forEach(
snake_case_object,
function(value, key) {
if (_.isPlainObject(value) || _.isArray(value)) { // checks that a value is a plain object or an array - for recursive key conversion
value = objectKeysToCamelCase(value); // recursively update keys of any values that are also objects
}
camelCaseObject[_.camelCase(key)] = value;
}
)
return camelCaseObject;
};
test in this PLUNKER
Note: also works recursively for objects within arrays
If you would use lodash instead of underscore, this would do:
_.mapKeys(obj, (v, k) => _.camelCase(k))
This would convert both TitleCase
and snake_case
to camelCase
. Note that it is not recursive though.
Using lodash, you can do it like this:
export const toCamelCase = obj => {
return _.reduce(obj, (result, value, key) => {
const finalValue = _.isPlainObject(value) || _.isArray(value) ? toCamelCase(value) : value;
return { ...result, [_.camelCase(key)]: finalValue };
}, {});
};
This solution based on the plain js solution above, uses loadash and Keeps an array if passed as a parameter and Only change the Keys
function camelCaseObject(o) {
let newO, origKey, value
if (o instanceof Array) {
newO = []
for (origKey in o) {
value = o[origKey]
if (typeof value === 'object') {
value = camelCaseObject(value)
}
newO.push(value)
}
} else {
newO = {}
for (origKey in o) {
if (o.hasOwnProperty(origKey)) {
newO[_.camelCase(origKey)] = o[origKey]
}
}
}
return newO
}
// Example
const obj = [
{'my_key': 'value'},
{'Another_Key':'anotherValue'},
{'array_key':
[{'me_too':2}]
}
]
console.log(camelCaseObject(obj))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>