1

I am pulling some data from a server (names of databases and specific data from each database). I then present the data to the user which chooses which entries he likes and then sends them to the server for analysis. To contain the user selections (database names and entries) I dynamically create an object which looks like this:

enter image description here

Because I don't know which databases I'll get and which entries, I dynamically create the object's databses names properties with Object.defineProperty like so:

Object.defineProperty(dbs_list, db_name, {
 value: {},
 writable: true,
 configurable: true
});

After building the object I want to send it to the server as a JSON object. There I encountered my first issue. JSON.stringify didn't work on the object because (as far as I understand) the object properties weren't 'own' properties.

As I understand possible solutions are to:

  1. make the properties become 'own' properties - which, after some searching, I haven't figured out how to.
  2. make the object have a toJSON property function - which is the option I chose.

Here is the gist of it:

var selected_entries = {
 toJSON() {
 for (db in this) {
 for (entry in this[db]) {
 //do something
 }
 }
 return json_string;
 }
};

But here I encounter the same issue - the properties are not 'own' properties so all I get from the first loop is the toJson property.

Is there a way to get the entries without saving them in an array and looping over it? Or, is there a way to define them as an 'own' properties?

Raghul SK
1,4005 gold badges24 silver badges36 bronze badges
asked Jul 6, 2020 at 7:33

1 Answer 1

2

The properties on your object are own properties. The problem is they're not enumerable. JSON.stringify only includes enumerable properties. That's also why you're not seeing them in your for-in loop. (Note: for-in doesn't only enumerate own properties, it includes inherited ones too. But only enumerable ones.)

To make your properties enumerable, add enumerable: true to your call to defineProperty; like all the flags, it defaults to false.

Object.defineProperty(dbs_list, db_name, {
 value: {},
 writable: true,
 configurable: true
});

But, at that point, you're just defining a data property anyway, so it would be simpler to simply do:

dbs_list[db_name] = {};

Then JSON.stringify will work.

Example:

const dbs_list = {};
let db_name;
let random = Math.floor(Math.random() * 10000);
db_name = "mysql" + random;
dbs_list[db_name] = {};
++random;
db_name = "mysql" + random;
dbs_list[db_name] = {};
console.log(JSON.stringify(dbs_list));


If for some reason you wanted to keep the properties non-enumerable, you could get an array of their names using Object.getOwnPropertyNames, then loop through that. But I don't see any reason for these to be non-enumerable properties.

answered Jul 6, 2020 at 7:36
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Just learned some important stuff! Now it works. So I can defined new properties with just obj[property_name] like a python dictionary.
@DvirH - Yup! In fact, defineProperty wasn't even added until ES5 in 2009. Until then, assignment (obj[expression] = value or obj.name = value;) was the only way to add properties to an object that already existed.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.