Take the 2-minute tour ×

let say i want to do this

  var dasboard = {};
  var page = "index";

    $(this).toggleClass("active").siblings().slideToggle('slow', function() {
        dashboard['pages'][page][$(this).closest('li').attr("id")]['show'] = $(this).is(":hidden") ? 'collapsed' : 'expanded';

i get an error saying 'dashboard.pages is undefined'

is there away to dynamically add 'pages' and the children that follow without having to do the work of checking to see if it is defined first then if its not doing

   dashboard['pages'] = {};

because sometimes they may already exist and I don't want to have to inspect the tree first i just want to build the branches as needed

EDIT I changed 'pagename' to page to show that page names will change and alo I want to point out that the pages could really be anything too. the idea is that you have any object that can contain ojbjecs with parameters without checking to see if the branches exist

it looks like $extend as stated will be the way to go just not sure how that works. got to get my head around that

share|improve this question
sorry - the script makes no sense to me. The use of bracket indexers implies the desire to dynamically index the object, but you are using constants. That, combined with the statement that you 'do not want to do the work' has me wondering if you know what you are trying to accomplish. Not trying to denigrate - just an observation as to why you may not get the answer you are looking for. –  Sky Sanders Mar 26 '10 at 19:14

6 Answers 6

up vote 8 down vote accepted

Define get and set methods on an Object. Actually it could be defined just on the dashboard object and only its descendants, but that's easy to do.

Object.prototype.get = function(prop) {
    this[prop] = this[prop] || {};
    return this[prop];

Object.prototype.set = function(prop, value) {
    this[prop] = value;

Iterate through nested properties using this get() method and call set() whenever a value has to be set.

var dashboard = {};

dashboard.get('pages').get('user').set('settings', 'oh crap');
// could also set settings directly without using set()
dashboard.get('pages').get('user').settings = 'oh crap';

console.log(dashboard); //​​​​​​​​​​​​​​​ {pages: {user: {settings: "oh crap"}}};

You could also extend/modify the get method to accept the nested properties as individual arguments or an array or a string. Using that, you'd only have to call get once:

// get accepts multiple arguments here
dashboard.get('pages', 'user').set('settings', 'something');

// get accepts an array here
dashboard.get(['pages', 'user']).set('settings', 'something');

// no reason why get can't also accept dotted parameters
// note: you don't have to call set(), could directly add the property
dashboard.get('pages.user').settings = 'something';


Since the get method generically returns an object and does not know whether you need an array or some other type of object, so you would have to specify that yourselves:

dashboard.get('pages.user').settings = [];

Then you could push items to the settings array as

dashboard.get('pages.user').settings.push('something else');

To actually have the get function construct the object hierarchy from a given string such as pages.user, you would have to split the string into parts and check if each nested object exists. Here is a modified version of get that does just that:

Object.prototype.get = function(prop) {
    var parts = prop.split('.');
    var obj = this;
        var p = parts[i];
        if(obj[p] === undefined) {
            obj[p] = {};
        obj = obj[p];
    return obj;

// example use
var user = dashboard.get('pages.user');
user.settings = [];

console.log(dashboard); // {pages: {user: {settings: ["something", "else"] }}}

// can also add to settings directly
share|improve this answer
ok this looks like what I was asking for except that I'm not using prototype how would I do this in jquery ? also let me take it just a step further lets say I want to do it so I have dashboard.get('pages.user.settings').push("something"); dashboard.get('pages.user.settings').push("somethingelse"); that should give me two items in settings right ? –  mcgrailm Apr 8 '10 at 15:36
@mmcgrail, this is regular Javascript and not the Prototype framework. The first approach of getting each property should work on every browser (jquery is not needed for that). Updating the answer for the other query. –  Anurag Apr 8 '10 at 17:32
that's awesome! I've learned allot from this, thank you –  mcgrailm Apr 9 '10 at 12:23
var foo = dashboard['pages'] || {};
foo['pagename'] = 'your thing here';
dashboard['pages'] = foo;

Explaining: the first line will check if the first value is null, undefined or... false (don't think this is a problem here): if it is, create a new object, if it is not, will use it.

share|improve this answer

I don't think there's a good builtin way to do this, but you could always abstract it with a function.

function getProperty(obj,prop){
    if( typeof( obj[prop] ) == 'undefined' ){
        obj[prop] = {};
    return obj[prop];

Then you use




As mentioned, $.extend will make this less burdensome.

share|improve this answer

$.extend is the way to go

function elem(a,b){
var r={'pages':{'pagename':{}}};
return r;
//inside the event handler or something:
data = $.extend(true,data,elem($(this).closest('li').attr("id"),$(this).is(":hidden") ? 'collapsed' : 'expanded'));

But honestly - this is a rather messy idea to store this information anyway. I bet that if You need that information later it could be done with a good selector or with jQuery.data()

share|improve this answer
but that's not dynamic your defining the json in the function. I'll look into the other suggestions you have –  mcgrailm Mar 26 '10 at 19:25
Nope, I'm building an object that has only one element and merge it into the data variable. It does the same thing Your code did if it worked, but also works when Your code didn't. Still I'm glad You try a different way :) –  naugtur Mar 26 '10 at 21:33

I would do it with the ternary operator:

dashboard['pages'][page] = dashboard['pages'][page] ? dashboard['pages'][page] : {};

That will do the trick no matter if it's set/null or whatever.

share|improve this answer

Well I guess you need this:

var dashBoard = new Array();
if(!dashboard['page123']) {
} else {
...do what you want

Seems you are dealing with XML.

share|improve this answer

Your Answer


