Parsing key:value declarations

Posted on

Problem

I recently ran into some issues with a plugin and outlined the issue in this post and wanted to know if the modifications I’ve made below cover the scenarios that the with scope blocks would have covered.

I’ve modified some code to remove the with operator and I’m wondering if I’ve replicated everything properly in doing so.

var test = new Function('$f','$c','with($f){with($c){return{'+ declarations +'}}}'));

Where $f and $c are passed objects (From what I could tell, $f shouldn’t ever have a property of $c). The declarations variable is a string that has a colon in it (EX: “value:color”) and available within the scope.

Here is my modified code:

var test = function($f, $c, declarations) {
        var result = {};
        var value = "";
        var split = declarations.split(":");
        if (split.length < 2) {
          throw new Error("Declaration is in an invalid format");
        }
        if ($f[$c] !== undefined && $f[$c][split[1]]) {
          value = $f[$c][split[1]];
        }
        else if ($c[split[1]]) {
          value =  $c[split[1]];
        }
        else if ($f[split[1]]) {
          value =  $f[split[1]];
        }
        else {
          value =  "" + split[1];
        }
        var key = split[0];
        result[key] = value;
        return result;
};

Everything appears to work as it did previously, but this modification now handles the use case where the declarations variable could have a dash in it (EX: “value:background-color”). Additionally the declarations variable is passed into the function, to ensure it’s defined.

Solution

Consider tightening up the long if statement using || which should be equivalent to your current logic. I can’t test this for you, but see if this works:

var test = function($f, $c, declarations) {
  var split = declarations.split(":"), key, value, cIsFProp;

  if (split.length < 2)
    throw new Error("Declaration is in an invalid format");

  cIsFProp = $f[$c] !== undefined && $f[$c][split[1]];

  value = cIsFProp ? $f[$c][split[1]] : null;
  value = value || $c[split[1]]) || $f[split[1]]) || "" + split[1];
  key = split[0];
  return {[key]: value};
};

Looks like is really hard to read in a first look. $c ,$f aren’t no much descriptive. avoid to use that names, if it is came from a dependency injection, or your framework use this nomenclature, try to replace with a string internally.

Also you are doing a lot of treatment of the split. I suggest use 2 variables instead of a split each time.

The code itself looks good, but will be better add more context to understand the kind of check

var test = function($f, $c, declarations) {
                    var $betterF = $f;
        var result = {};
        var value = "";
        var split = declarations.split(":");
        var key = split[0];
        var tmpValue = split[1];
        if (split.length < 2) {
          throw new Error("Declaration is in an invalid format");
        }

        if (!$f[$c] && $f[$c][tmpValue]) {
          value = $f[$c][tmpValue];
        } else if ($c[tmpValue]) {
          value =  $c[tmpValue];
        } else if ($f[tmpValue]) {
          value =  $f[tmpValue];
        } else {
          value =  "" + tmpValue;
        }

        result[key] = value;
        return result;
};

Leave a Reply

Your email address will not be published. Required fields are marked *