2

So, I need to transform all keys in array from underscore to camel space in js. That is what I need to do before send form to server. I'm using Angular.js and I want to represent it as a filter (but I think it's not rly important in this case). Anyway, here is a function I've created.

.filter('underscoreToCamelKeys', function () {
        return function (data) {

            var tmp = [];
            function keyReverse(array) {
                angular.forEach(array, function (value, key) {
                        tmp[value] = underscoreToCamelcase(key);
                });

                return tmp;
            }

            var new_obj = {};
            for (var prop in keyReverse(data)) {
                if(tmp.hasOwnProperty(prop)) {
                    new_obj[tmp[prop]] = prop;
                }
            }
            return new_obj;
        };

        function underscoreToCamelcase (string) {
            return string.replace(/(\_\w)/g, function(m){
                return m[1].toUpperCase();
            });
        }
    })

Here I will try to explain how it works, because it looks terrible at first.

underscoreToCamelcase function just reverting any string in underscore to came case, except first character (like this some_string => someString)

So, as I said earlier, I should revert all keys to camel case, but as you understant we can't simply write

date[key] = underscoreToCamelcase(key)

so keyReverse function returns a reverted array, here is example

some_key => value

will be

value => someKey

and for the last I simply reverting keys and values back, to get this

someKey => value

But, as you already may understand, I got a problem, if in array exists the same values, those data will be dissapear

array

some_key1 => value, some_key2 => value

returns as

someKey2 => value

So how can I fix that? I have a suggestion to check if those value exists and if it is add some special substring, like this

some_key1 => value, some_key2 => value

value => someKey1, zx99value => someKey2

and after all parse it for zx99, but it I think I`m going crazy... Maybe some one have a better solution in this case?

Important! Them main problem is not just to transform some string to camel case, but do it with array keys!

Majesty
  • 2,097
  • 5
  • 24
  • 55
  • 1
    one solution is to use https://www.npmjs.com/package/camelcase which does exactly what you want. – krs Apr 08 '16 at 20:32
  • It is not, because the problem is to revert array keys to camel case, but not to camelize just string, I already created a function to camelize string `underscoreToCamelcase` – Majesty Apr 08 '16 at 20:35
  • `var str = "under_score", rep = str.replace(/_([a-z])/,function(match, p1) { return p1.toUpperCase(); }); // <- underScore` – Redu Apr 08 '16 at 21:09
  • Guys, my underscore to camelcase function works perfect, that is named `underscoreToCamelcase`, the problem is to revert array keys – Majesty Apr 08 '16 at 21:13
  • 2
    Why are you switching around the key/value pair in the first place? Why not just replace the keys as you go? e.g. extract the value and key, delete the current key, set the value under the transformed key – ryanlutgen Apr 08 '16 at 21:14
  • uh, you right! thanks! it was so close... – Majesty Apr 08 '16 at 21:23

3 Answers3

5

If you use an existing library to do the camelCase transform, you can then reduce an object like so

import {camelCase} from 'lodash/string'

const camelCaseKeys = (obj) =>
  Object.keys(obj).reduce((ccObj, field) => ({
    ...ccObj,
    [camelCase(field)]: obj[field]
  }), {})
Tim
  • 4,471
  • 5
  • 36
  • 42
1
.filter('underscoreToCamelKeys', function () {
        return function (data) {

            var tmp = {};
            angular.forEach(data, function (value, key) {
                var tmpvalue = underscoreToCamelcase(key);
                tmp[tmpvalue] = value;
            });

            return tmp;
        };

        function underscoreToCamelcase (string) {
            return string.replace(/(\_\w)/g, function(m){
                return m[1].toUpperCase();
            });
        }
    })

thanks to ryanlutgen

Majesty
  • 2,097
  • 5
  • 24
  • 55
0

As an alternative solution, you could use the optional replacer parameter of the JSON.stringify method.

var result = JSON.stringify(myVal, function (key, value) {

  if (value && typeof value === 'object') {
    var replacement = {};
    for (var k in value) {
      if (Object.hasOwnProperty.call(value, k)) {
        replacement[underscoreToCamelcase(k)] = value[k];
      }
    }
    return replacement;
  }

  return value;
});

Of course you'll end up with a string and have to call JSON.parse to get the object.

ViZeke
  • 349
  • 3
  • 7