Declare object from string - javascript

I want to declare 1 javascript object which its properties are generated from one sequence that was created earlier
example:
var x = '"property1": "abc",
"property2": "def",
"property3": "xyz",
';
var obj = {
// insert content of x here
}
what can i do?

You can declare
var x = {property1: "abc",
property2: "def",
property3: "xyz"};
var obj = {
data:x
}

Assuming you have a string that is a valid sequence of key/value pairs that are double-quoted then you can easily make it into JSON by concatenating '{' and '}', after removing any trailing comma (I notice your last property has a trailing comma). Then you can create an object by parsing that JSON. So:
var x = // Your string of quoted, comma-separated key/value pairs here
var obj = JSON.parse('{' + x.replace(/,\s+$/,'') + '}');
General note of disapproval: I don't know why you would create your properties as a string rather than just adding properties directly to an object, and in general you shouldn't hand-create JSON, and I'd like to note that a string literal enclosed by single-quotes can't have line-breaks in it so I'm hoping you just showed it that way for ease of reading.

Use JSON string here
var x = `{"property1": "abc",
"property2": "def",
"property3": "xyz"
}`;
var obj = JSON.parse(x)
After reading your comments OP I think you may be after bracket notation.
You can access an object's property via dot notation
obj.prop = foo;
var v = obj.prop;
Or you can use bracket notation
var propName = "prop"
obj[propName] = foo;
var v = obj[propName];
Note this is not accessing an array.
So you could do it this way
var data = [["property1", "abc"],["property2","def"],["property3","xyz"]]
var obj = {};
data.forEach(pk => { obj[pk[0]] = pk[1]; });
console.log(obj.property1); // output "abc"

You can use the eval API to parse the string too.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
The eval() function evaluates JavaScript code represented as a string.
Example:
let y = "";
let x = ' "property1": "abc", "property2": "def", "property3": "xyz" ';
eval('y={' + x + '}');
Output:
Please note that using eval can be dangerous as noted in its documentation:
eval() is a dangerous function, which executes the code it's passed
with the privileges of the caller. If you run eval() with a string
that could be affected by a malicious party, you may end up running
malicious code on the user's machine with the permissions of your
webpage / extension.
Example: exposing it as a REST service to allow end-users to hit it with any 'object string' which can instead be a piece of malicious code - like downloading virus.

Related

Create object from object literal string

Is there an easy way to parse an object literal as a string into a new object?
I'm looking to turn a string like the following:
'{ name: "A", list: [] }'
Into an object like:
{ name: 'A', list: [] }
Note:
I'm not looking for JSON.parse() as it accepts json strings and not object literal strings. I was hoping that eval would work but unfortunately it does not.
eval does indeed work, with one tweak: the problem is that the standalone line
{ name: 'A', list: [] }
gets parsed as the interpreter as the beginning of a block, rather than as the start of an object literal. So, just like arrow functions which implicitly return objects need to have parentheses surrounding the objects:
arr.map(item => ({ item }))
you need to put parentheses around the input string, so that the content inside (that is, the object, which starts with {) is parsed properly as an expression:
const input = '{ name: "A", list: [] }';
const obj = eval('(' + input + ')');
console.log(obj);
Of course, as with all cases when eval is involved, you should be very sure that the input is trustworthy first.
While I would never do this IRL, you could perhaps try this:
var myObjLiteralString = '{ name: "A", list: [] }';
var myObj;
eval('myObj = ' + myObjLiteralString);
console.log(myObj);

Binding this to JSON.parse()

I have a case where I need to parse a string into JS object by binding this like below:
var jsString = '{"name" : this.name, "age": this.age}';
this.name = "Hello";
this.age = 100;
//This fails(CASE 1)
var jsObjectFromString = JSON.parse(jsString);
console.log(jsObjectFromString );
//This works(CASE 2)
var directObject = {"name" : this.name, "age": this.age};
console.log(directObject);
//Need below output for console.log(jsObjectFromString ):
//{"name" : "Hello", "age": 100}
In my actual program, the string is coming from a web-service & hence I can't use CASE 2 approach.
I can traverse the JS object & set params after parsing like below:
var jsonString = '{"name" : "", "age": 0}';
var jsonObject = JSON.parse(jsonString);
jsonObject["name"] = this.name;
jsonObject["age"] = this.age;
But there a lot of inner objects & traversing would be a kill. I tried the below but failed(obviously :( ):
JSON.parse(jsonString).bind(this);
Is there an approach to overcome this?
PS: This is a browser based app not a node project.
Edit: I want to construct a javascript object from the string. I would want to replace parts of the string(like name,age) into actual values in the parsed Javascript object.
This is very strange use case, and I'm sure that the design of your app should be changed. But here is the solution based on the allowed properties white list and an agreement of a specific role of "this." substring in the initial string:
let income = '{"name" : this.name, "age": this.age}';
this.name = "Hello";
this.age = 100;
const whiteList = ['name', 'age'];
const inject = (prop) => {
if(typeof this[prop] === 'string') {
return '"' + this[prop] + '"';
}
return this[prop];
};
whiteList.forEach(prop => income = income.replace('this.' + prop, inject(prop)));
console.log(income); // {"name" : "Hello", "age": 100}
You may upgrade the procedure by
getting the white list from the context automatically
protecting parser by additional symbols ': this.'
as #Soren sayd on the comment, '{"name" : this.name, "age": this.age}' is not a valid JSON string.
What you want to do actually is to pass expressions in the JSON instead of values, and evaluate them. The first thing you could consider is to use eval() that is, in most cases, a bad idea (a nice article here).
another option, maybe more suitable, is to use a custom markup to identify the expressions you want to evaluate, replacing them with your value, and then parsing the obtained string as JSON:
'{"name" : |name|, "age": |age|}' from this string, you can look for any |...| occurrence and use what is within the | symbol (your custom markup marker) as a key inside any object, in your case this[whateverYouFound].
Now you can replace the found value inside the original string to have something like '{"name" : "hello", "age": 100}' (you could even stringify objects, if you need to), that is a valid JSON string.
this method avoid you exposing the possibility to evaluate dangerous code
The best you could do is to generate a valid JSON. Here is an example:
function preProcess(invalidJSON){
this.name = "Hello";
this.age = 100;
Object.keys(this).forEach(key => {
invalidJSON = invalidJSON.replace(new RegExp("this\\." + key, "g"), '"'+this[key]+'"');
});
// replace all non-existing properties with empty values.
var validJSON = invalidJSON.replace(/this\.[^,\[\]\{\}]+/, '""');
return validJSON;
}
var str = '{"name" : this.name, "age": this.age}';
var validJSON = preProcess.call({}, str);
console.log(validJSON);

mongdb/nodejs: using variables in $inc doesn't work

I have the following that i entered into the mongo terminal and it works great
db.cars.update({'_id':'FordXdfg'},{$inc :{'attribs.0.totl':1}})
which basically updates an array using dot notation, the 0 is the index of the array.
this does work. but transferring it to node my 0 comes from a variable.
so i tried
var carIndex = 3;
cars.update({'_id':'FordXdfg'},{$inc :{'attribs.' + carIndex + '.totl':1}}, function (err, callback) ................)
seems to be invalid javascript, if i replace my carIndex with 3 then it works i.e.
cars.update({'_id':'FordXdfg'},{$inc :{'attribs.3.totl':1}}, function (err, callback) ................)
Any ideas?
thanks
When using that style of object initialization in JavaScript, property names must be string literals. When using the object initialization syntax, property names can not be constructed at run time in code. For example, you can only use literals like:
{
"name": "Martin"
"location": "Earth"
"value": 1234
}
You cannot do this:
var propName = "name";
var obj = {
propName: "Martin";
};
While it syntactically appears to work, you'll end up with an object that looks like:
{
propName: "Martin"
}
Again, that's because only literal values are accepted when constructing an object using the shortened syntax. It will not interpret variable values.
There are two other options for setting properties of a JavaScript object, either through simple dot-notation:
obj.name = "Martin";
Or, you can use bracket notation:
obj["name"] = "Martin";
As objects in JavaScript act like associative arrays in that you can define new properties/keys at runtime each with a value, either syntax above works, and both result in the same underlying storage (and can be used interchangeably).
So, you'll need to construct the $inc syntax separately using the other technique for setting object property values in JavaScript:
var inc = {};
inc["attribs." + carIndx + ".totl"] = 1;
Then use that inside of your update:
{ $inc: inc }

Get values from object if the name of the object is stored as a variable?

I have a JSON object return with the following format:
"miscObject": {
"205": [
{
"h": "Foo",
"l": "Bar"
}
]
}
miscObject contains somewhere over 1500 entries, each named incrementally.
How can I get to the values of 'miscObject.205.h' and 'miscObject.205.l' if I have "205" stored in variable without having to loop through all of the objects inside miscObject?
It seems that you're talking about Javascript objects rather than a JSON string.
x[y] and x.y are mostly interchangeable when accessing properties of Javascript objects, with the distinction that y in the former may be an expression.
Take advantage of this to solve your problem, like so:
var num = '205';
console.log(miscObject[num].l);
// ^^^^^
// \
// instead of `.num`, which wouldn't be the same as
// `num` is not the literal name of the property
Use the member lookup syntax
var miscObject = $.parseJSON(theJsonString);
var name = '205';
miscObject[name].h;
Object values can be accessed 2 ways--using the 'dot' notation as you mentioned, or by using []'s:
The following should work:
var result = miscObject["205"].h;
var miscObject = JSON.parse(your-JSON-object);
var value = miscObject['205'].h
You can do this to get the object:
num = '205'
miscObject[num]

Curly braces inside JavaScript arguments for functions

What do the curly braces surrounding JavaScript arguments for functions do?
var port = chrome.extension.connect({name: "testing"});
port.postMessage({found: (count != undefined)});
A second possible answer has arisen since this question was asked. Javascript ES6 introduced Destructuring Assignment.
var x = function({ foo }) {
console.log(foo)
}
var y = {
bar: "hello",
foo: "Good bye"
}
x(y)
Result: "Good bye"
The curly braces denote an object literal. It is a way of sending key/value pairs of data.
So this:
var obj = {name: "testing"};
Is used like this to access the data.
obj.name; // gives you "testing"
You can give the object several comma separated key/value pairs, as long as the keys are unique.
var obj = {name: "testing",
another: "some other value",
"a-key": "needed quotes because of the hyphen"
};
You can also use square brackets to access the properties of the object.
This would be required in the case of the "a-key".
obj["a-key"] // gives you "needed quotes because of the hyphen"
Using the square brackets, you can access a value using a property name stored in a variable.
var some_variable = "name";
obj[ some_variable ] // gives you "testing"
Curly braces in javascript are used as shorthand to create objects. For example:
// Create an object with a key "name" initialized to the value "testing"
var test = { name : "testing" };
alert(test.name); // alerts "testing"
Check out Douglas Crockford's JavaScript Survey for more detail.
var x = {title: 'the title'};
defines an object literal that has properties on it. you can do
x.title
which will evaluate to 'the title;
this is a common technique for passing configurations to methods, which is what is going on here.

Categories