0

I'm trying to use jqTree to render a collapsible tree to display data from a MySQL database via an ASP.NET project using AJAX.

The Problem:

I can successfully get the string containing the jqTree formatted data (which is not JSON even though they say it supports it) back from my AJAX call. However, once I get it there it get rendered as a vertical string of characters. If I do a typeof call on the data, it says it's a string, even though it 'looks' like an object when visually inspected via console.log.

I have tried a number of different ways to get the string into an object, with varying results.

I'm using this in the code behind to return the manufactured string:

return sb.ToString();

The resultant string looks like this (notice no wrapping quotation marks):

[{label: 'PCBID: 350',children:[{label: 'TimeStamp: 04-Sep-14 10:30:23'},{label: 'User:     DAVEG'},{label: 'PCBID: 350'},{label: 'Assembly Drawing: 41411'},{label: 'PCB Drawing: 10348'},{label: 'Vendor: SBE'},{label: 'PO Number: 98019'}]},{label: 'Serial Number: Not Assigned'},{label: 'Assembly Drawing: 41411'},{label: 'Last Test Result: None Found'}]

Which gets rendered like this in my div:

[
{
l
a
b
e
l
:

'
P
C
B
I
D
...and so on...

I know these are being rendered by jqTree because I can drag & drop them, they highlight when clicked on, etc., but instead of a tree view, I get a "dangling vine" view, not exactly useful.

If I simply take that same exact same string and declare it as a var inside the JS (not using the return value of message.d):

var data = [{label: 'PCBID: 350',children:[{label: 'TimeStamp: 04-Sep-14 10:30:23'},{label: 'User: DAVEG'},{label: 'PCBID: 350'},{label: 'Assembly Drawing: 41411'},{label: 'PCB Drawing: 10348'},{label: 'Vendor: SBE'},{label: 'PO Number: 98019'}]},{label: 'Serial Number: Not Assigned'},{label: 'Assembly Drawing: 41411'},{label: 'Last Test Result: None Found'}] 

inside my JS code & use that, it displays perfectly and typeof thinks it's an object.

Working Example so you can see what I'm looking for:

JSFiddle

The Code on the JS side:

Here's the Success portion of my AJAX call with a bunch of commented out versions that don't work either:

    success: function (message)
    {
        console.log("SUCCESS:  Inside processEvent AJAX success call");
        console.log(message.d);
        console.log(typeof message);
        console.log(typeof message.d);
        var data = message.d;
        //this method works, but not very useful as it's hard coded:
        //var data = [{ label: 'PCBID: 350', children: [{ label: 'TimeStamp: 04-Sep-14 10:30:23' }, { label: 'User: DAVEG' }, { label: 'PCBID: 350' }, { label: 'Assembly Drawing: 41411' }, { label: 'PCB Drawing: 10348' }, { label: 'Vendor: SBE' }, { label: 'PO Number: 98019' }] }, { label: 'Serial Number: Not Assigned' }, { label: 'Assembly Drawing: 41411' }, { label: 'Last Test Result: None Found' }];
        var data = $.getJSON(message.d);
        //var data = { JSON.parse(message.d) };
        //var data = ({}).valueOf.call($.parseJSON(message.d));
        //var data = object.create(message.d);
        console.log(typeof data);
        console.log(data);
        $(function ()
        {
            $('#tree1').tree({
                data: data,
                autoOpen: false,
                saveState: true,
                dragAndDrop: true
            });
        });

The Question:

So after all that, my question is, how do I take the string from the AJAX message.d and turn it into an object so that jqTree can use it to render the tree I'm looking for?

Working Code:

I've added back in some of the success user informing stuff (jGrowl) so don't let that throw you. The bit of code that fixed it is here: data = eval($.parseJSON(message.d));

    success: function (message)
    {
        console.log("SUCCESS:  Inside processEvent AJAX success call");
        console.log(message.d);
        //if it's a non query event, do this
        if (DTO.eventData.eventType != "PCBID_query")
        {
            $.jGrowl("\nSuccessfully inserted a " + DTO.eventData.eventType + " event into the MySQL database.",
                { header: 'SUCCESS', theme: "pcb-success", life: 10000 });
        }
        //if processData was used for a PCBID query, process this code
        if (DTO.eventData.eventType === "PCBID_query")
        {
            var data = {};
            data = eval($.parseJSON(message.d));
            $(function ()
            {
                //force reload of tree data
                $('#tree1').tree('loadData', data);
                $('#tree1').tree({
                    data: data,
                    autoOpen: false,
                    saveState: true,
                    dragAndDrop: true
                });
            });
        }

I know the eval is evil & presents a security hole, however, this is all internal code that'll only be used on local servers & production floor computers so I think the risk is acceptable (as does my manager).

delliottg
  • 3,950
  • 3
  • 38
  • 52
  • `eval(data)` would work in this case, but it is a security issue. Your best solution would be to look for a real way to export JSON from your ASP.NET. Without knowing your code, a little googling shows there are solutions out there. – Jeff B Sep 05 '14 at 17:32
  • I've tried exporting the data as JSON using `return Newtonsoft.Json.JsonConvert.SerializeObject(sb.ToString(), Newtonsoft.Json.Formatting.Indented);` but I end up with the same results when I parse it on the JS side. This won't be used externally by anyone, so the security issue is probably moot. I'll give you suggestion a try (although I've tried a couple of other methods using eval, just didn't include them in the examples). – delliottg Sep 05 '14 at 17:36
  • That worked, thanks! Is there another way to do this that doesn't use `eval`? In any case since it's an internal only tool, I'm not overly worried about the security problem. If you want to write up a quick answer I'll select it. BTW, I saw your original answer before you deleted it using getJSON & tried it as well, didn't work. Thanks again. – delliottg Sep 05 '14 at 18:05
  • Yes, because you are correct that it isn't valid JSON. All json object keys need to be `"` double quoted, which is the biggest issue with your current data. – Jeff B Sep 05 '14 at 18:12
  • I wonder if the jqTree object could be JSON-ified (with double quotes & such) so that it'd be able to be passed as directly? I took their examples & dropped them on JSONLint & they didn't validate, but they did work for what I needed. The rest of my server side stuff all works with real JSON. – delliottg Sep 05 '14 at 20:00

1 Answers1

1

eval(data) would work in this case, but using eval() is usually a security issue, especially when getting data from public areas, such as user submitted SQL data.

The best solution would be to look for a real way to export JSON from your ASP.NET. Without knowing your code, a little googling shows there are solutions out there.

Jeff B
  • 29,943
  • 7
  • 61
  • 90