4

In the context of a web app, I have a server which sends or receives JSON strings based on the input from the client. On client consumption, these JSON strings are immediately converted into JavaScript objects where they will live out their lives as objects. These objects are not arrays; they represent complex, arbitrary data models, each property of which can have an arbitrary number of unique subproperties or objects.

var myView = {
    name: 'root'
    id: 'root_0'
    children: {
       child_1: {
          arbitraryid: 'root_0_child_1',
          type: 'Department',
          name: 'Produce',
          quadrant: 1,
          children: {
              child_1: {
                  arbitraryid: 'root_0_child_1_child_1',
                  type: 'Aisle',
                  number: 3,
                  length: 12,
                  children: { }
              }
          }
       },
       child_2: {
          arbitraryid: 'root_0_child_2',
          name: 'West',
          type: 'Region',
          children: {
              child_1: {
                  arbitraryid: 'root_0_child_2_child_1',
                  name: 'Wegmans',
                  type: 'Store', 
                  children: { 
                      child_1: {
                          arbitraryid: 'root_0_child_2_child_1_child_1',
                          type: 'Department',
                          children: { }
                      }
                  }
             }
          }      
       }
    }
};

When I build the JSON string server side, I guarantee that all objects will have 'children' and 'arbitraryid' properties; but everything else is dynamically generated and the properties and values are completely arbitrary.

If this were XML, I could use jQuery to var someChild = myView.find('#root_0_child_1_child_1'). This would get me a jQuery object with the results of the find AND not only a reference to myView but a position from which to move omnidirectionally through the object: var someChild = myView.find('#root_0_child_1_child_1').parent().

Does a utility exist to solve this problem for native, JavaScript objects or is there a preferable way/methodology to do this? I'd like to avoid writing a bunch of this type of code to simply get at my property and then potentially loop again to update the parent object.

while (obj.hasOwnProperty('children')) {
   for (var child in obj) {
     //..etc, etc
   } 
}

Most of the SO questions I see on this subject deal with searching arrays, frequently with predictable data table style construction.

Mapping is possible, but these objects quickly become deep and that option seems little better than dumb looping.

Ideas?

Edit: rolling my own utility class.

I'm still exploring other libraries/utilities, but I wrote a generic helper class to do searches:

ObjectHelper

While useful, I think it illustrates some of the difficulty with getting at other jQuery-like functionality. Not only would I like to search, but I'd like to be able to crawl up/down the object property structure similarly to the way you can chain .parent().children().find() operators together. Doable, but complicated.

Community
  • 1
  • 1
Christopher
  • 1,723
  • 1
  • 18
  • 31

2 Answers2

2

I found a few JSON Query Languages:

This page sums them up and goes through their pros and cons.

There is a DOJO module for querying JSON as well:

I'm not sure how stable/standard these are though.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • Yes, something like these tools. I've looked at the various flavors of LINQ as implemented in JS as well as JSONPath. JAQL appears to take the same approach. The problem with these tools is that I'm not working with Arrays and I'm not using Strings (therefore not using JSON). I'm working with objects that don't map well (at all) to table structures. Most tools assume either that you have an array with predictable "rows" or that you have actual JSON (as far as I can tell). – Christopher Aug 17 '11 at 15:55
  • @Christopher That makes sense. You want to be able to query any arbitrary object. – Vivin Paliath Aug 17 '11 at 16:16
  • JSONQuery looks promising. I can't test it with jsfiddle as Dojo doesn't seem to include the dojox modules in any CDN content. Downloading and testing locally now. – Christopher Aug 17 '11 at 16:41
  • 1
    using JSONQuery, I can't find nested properties. The quest continues. Thanks for the tip. – Christopher Aug 17 '11 at 16:54
0

I solved this by rolling my own classes. ShadesJS is pretty basic right now, but it has some methods for crawling JavaScript objects and working with Web Storage. On the to-do is implement parent/child methods to get some JQuery-esque flexibility. It's not hard to do, but it's tricky to get it right and performant.

Christopher
  • 1,723
  • 1
  • 18
  • 31