1
votes

I have a bit of a unique problem. I'm currently trying to hook up a JSON dataSource to a kendo grid. Because of this, there can be no # anywhere in the JSON because it messes with kendo. So I have to take data like this:

[
    {"ID#": "1", "Prop1": "Val1#"},
    {"ID#": "2", "Prop2": "Val2"},
]

and escape the # so that Kendo can understand it:

[
    {"ID\#": "1", "Prop1": "Val1\#"},
    {"ID\#": "2", "Prop2": "Val2"},
]

The biggest problem with this is that the JSON could resemble just about anything: there could be any number/name of keys/values.

My Attempts:

I tried to escape the # like so: var dataSource = JSON.parse(result.replace("#", "\\#")); However, JSON.parse throws an error when I try this:

SyntaxError: JSON.parse: bad escaped character at line 1 column 7 of the JSON data

Then I tried to replace the # with #. It turns out Kendo can only support HTML entities in rows, not in column headers, without getting a template error. So I'm able to replace property values like this:

var dataSource = JSON.parse(result, function(key, value) {
       if(typeof value === "string") {
           return value.replace("#", "#");
       }
       else {
           return value;
       }
 });

This works for values! However, the keys could still contain # which will mess up my Kendo Grid. I tried to loop through each object and key/pair and replacing the key if it has a #, but for some reason when I call Object.keys the array that is returned is just 0s and 1s even though that's not what my data is named.

for (var object in dataSource) {
     for (var property in object) {
          if (object.hasOwnProperty(property)) {
                var keys = Object.keys(object);
                for(var key in keys) {
                     var oldName = key;
                     var newName = key.replace("#", "\#");
                     object[newName] = object[oldName];       
                     delete object[oldName];           
                 }   
           }
      }
 }

This portion above appears to have no effect. It doesn't even throw an error.

I also tried replacing the # with a string: hashliteral. Then, after the kendo grid was created, I tried using jQuery to replace all of the hashliteral with #.

var fixed = $("#grid").html().replace(/hashliteral/g, "#");
$("#grid").html(fixed);

This does work, but it breaks the kendo grid and all of the bindings. The grid functionality is a must, so I can't use this solution.

Just to Recap

I'm trying to remove/replace or escape all # in JSON data so that it functions correctly with my Kendo Grid.

  • I can't use JSON.stringify and replace the # with \\# because then JSON.parse fails.
  • I can't use # because Kendo headers cannot have special characters.
  • I can't use jQuery to modify the $("#grid").html() because it breaks the grid bindings.
  • The key can be anything. The value can also be anything.
  • The JSON is NOT nested or complex.
  • I cannot define the field/title on the KendoGrid columns because I have no idea what the field/title needs to be, the data is very dynamic.

I'm about ready to give up on this and just remove all # from the data. If anyone can think of some way to accomplish this: renaming the properties of an object so that all # are preceded by a \, it would be much appreciated. For the life of me I can't find a solution to this problem.

1
It seems that there is no problem at all on having # in a value. Check this out. Although I managed to escape the header's title with #, but it screws up the template. IMO it is a bug, it should take care of it anyways...DontVoteMeDown
why exactly don't you loop through all properties and build a new object for further processing? did i miss something?lexith
@lexith I haven't found a way to do this yet without knowing what the oldkeys/newkeys areSunden

1 Answers

1
votes

I think you were already on the right track, but it's easier just to create a new list of objects:

var newObjects = [];

for (var i = 0; i < dataSource.length; i++ ) {
    var currentObject = dataSource[i];
    var newObject = {};

    for (var key in currentObject) {
        if (currentObject.hasOwnProperty(key)) {
             var newKeyName = key.replace("#", "__HASHLITERAL__");
             var newValue = currentObject[key];
             if(typeof newValue === "string") {
                  newValue = newValue.replace("#", "__HASHLITERAL__");
             }
             newObject[newKeyName] = newValue;
        }
    }

    newObjects.push(newObject);
}

console.log(newObjects);

Hope it helps and i understood your problem correctly.


Edit: You can't have special chars like \ as a key, so you have to actually use something unique like ___something___ which you could replace then with whatever later.